מדריך Activiti עם Java

1. סקירה כללית

ממשק API של Activiti הוא מערכת זרימת עבודה וניהול תהליכים עסקיים. אנו יכולים להגדיר תהליך בו, לבצע אותו ולבצע מניפולציות בדרכים שונות באמצעות השירותים הניתנים על ידי ה- API. זה דורש JDK 7+.

פיתוח באמצעות ה- API יכול להיעשות בכל IDE, אך כדי להשתמש במעצב Activiti, אנו זקוקים ל Eclipse.

אנו יכולים להגדיר תהליך בו באמצעות תקן BPMN 2.0. יש דרך אחרת ופחות פופולרית - שימוש בשיעורי Java כמו StartEvent, EndEvent, UserTask, SequenceFlow, וכו.

אם אנו רוצים להפעיל תהליך או לגשת לאחד מהשירותים, עלינו ליצור ProcessEngineConfiguration.

אנחנו יכולים להשיג את ProcessEngine באמצעות ProcessEngineConfiguration, במובנים מסוימים, עליהם נדבר במאמר זה. דרךה ProcessEngine אנחנו יכולים לבצע את פעולות זרימת העבודה וה- BPMN.

2. תלות Maven

כדי להשתמש ב- API זה, עלינו לכלול את התלות של Activiti:

 org.activiti activiti-engine 

3. יצירת א ProcessEngine

ProcessEngine ב- Activiti מוגדר בדרך כלל באמצעות קובץ XML, activiti.cfg.xml. דוגמה לקובץ תצורה זה היא:

עכשיו נוכל להשיג את ProcessEngine משתמש ב ProcessEngines מעמד:

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine ();

הצהרה זו תחפש activiti.cfg.קובץ xml בכיתה ובנה a ProcessEngine בהתבסס על התצורה בקובץ.

קוד הדוגמה של קובץ התצורה מראה שהוא רק תצורה מבוססת אביב. אבל, זה לא אומר שאנחנו יכולים להשתמש ב- Activiti רק בסביבת אביב. היכולות של אביב משמשות רק באופן פנימי ליצירת ה- ProcessEngine.

בוא נכתוב מקרה מבחן JUnit שייצור את ה- ProcessEngine באמצעות קובץ התצורה המוצג לעיל:

@ מבחן חלל ציבורי נתון XMLConfig_whenGetDefault_thenGotProcessEngine () {ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine (); assertNotNull (processEngine); assertEquals ("root", processEngine.getProcessEngineConfiguration () .getJdbcUsername ()); } 

4. Activiti Process Engine API ושירותים

נקודת הכניסה של האינטראקציה עם ה- API היא ה- ProcessEngine. דרך ה ProcessEngine, אנו יכולים לגשת לשירותים שונים המספקים שיטות זרימת עבודה / BPMN. ה ProcessEngine וכל אובייקטי השירות הם בטוחים בחוטים.

נלקח מ //www.activiti.org/userguide/images/api.services.png

ה ProcessEngines הכיתה תסרוק אחר activiti.cfg.xml ו activiti-context.xml קבצים. כפי שצוין קודם לכן, עבור כל activiti.cfg.xml קבצים, ProcessEngine ייווצר בצורה אופיינית.

ואילו, לכל activiti-context.xml קבצים, הוא ייווצר בדרך האביב - אני אצור את הקשר היישום של האביב ואשיג את ProcessEngine מזה. במהלך ביצוע התהליך יבקרו בכל השלבים לפי הסדר שמוגדר בקובץ BPMN.

במהלך ביצוע התהליך יבקרו בכל השלבים לפי הסדר המוגדר בקובץ BPMN.

4.1. הגדרת תהליך ומונחים קשורים

א הגדרת תהליך מייצג תהליך עסקי. הוא משמש להגדרת מבנה והתנהגות שלבים שונים בתהליך. פירוש הגדרת תהליך פירושו טעינת הגדרת התהליך למסד הנתונים של Activiti.

הגדרות התהליך מוגדרות בעיקר על ידי תקן BPMN 2.0. אפשר גם להגדיר אותם באמצעות קוד Java. כל המונחים המוגדרים בסעיף זה זמינים גם כשיעורי Java.

ברגע שנתחיל להריץ הגדרת תהליך, ניתן להתייחס אליה כאל תהליך

א ProcessInstance הוא ביצוע אחד של א הגדרת תהליך.

א StartEvent קשורה לכל תהליך עסקי. זה מציין את נקודת הכניסה של התהליך. באופן דומה, יש EndEvent מה שמעיד על סיום התהליך. אנו יכולים להגדיר תנאים על פני אירועים אלה.

כל השלבים (או האלמנטים) בין ההתחלה לסוף מכונים משימות. משימות יכול להיות מסוגים שונים. המשימות הנפוצות ביותר הן משימות משתמש ו משימות שירות.

משימות משתמש, כפי שהשם מרמז, הם כאלה שהם צריכים להתבצע באופן ידני על ידי משתמש.

משימות שירות, לעומת זאת, מוגדרים עם פיסת קוד. בכל פעם שההוצאה לפועל תגיע אליהם, בלוק הקוד שלהם יבוצע.

SequenceFlows לחבר את משימות. אנחנו יכולים להגדיר את SequenceFlows לפי מקור ואלמנטים היעד שהם יחברו. שוב, אנו יכולים גם להגדיר תנאים מעל SequenceFlows ליצור מסלולים מותנים בתהליך.

4.2. שירותים

נדון בקצרה בשירותים שמספקת Activiti:

  • RepositoryService עוזר לנו לתפעל את פריסת הגדרות התהליך. שירות זה עוסק בנתונים הסטטיים הקשורים להגדרת התהליך
  • RuntimeService מנהל את ProcessInstances (כרגע פועלים תהליכים) כמו גם משתני התהליך
  • TaskService עוקב אחר משימות משתמש. ה משימות שצריכים להתבצע באופן ידני על ידי משתמש הם בבסיס ה- API של Activiti. אנו יכולים ליצור משימה, לתבוע ולהשלים משימה, לתפעל את מקבל המשימה וכו 'באמצעות שירות זה
  • FormService הוא שירות אופציונלי. ניתן להשתמש בממשק ה- API בלעדיו, ומבלי לוותר על אף אחד מהתכונות שלו. הוא משמש להגדרת טופס ההתחלה וצורת המשימות בתהליך.
  • שירות זהות מנהל את משתמשים ו קבוצות
  • שירות היסטוריה עוקב אחר ההיסטוריה של Activiti Engine. אנו יכולים גם לקבוע רמות היסטוריה שונות.
  • ניהול שירות קשור למטא נתונים ובדרך כלל אינו נדרש בעת יצירת יישום
  • DynamicBpmnService עוזר לנו לשנות כל דבר בתהליך מבלי לפרוס אותו מחדש

5. עבודה עם שירותי Activiti

כדי ללמוד כיצד אנו יכולים לעבוד עם שירותים שונים ולהפעיל תהליך, ניקח דוגמה לתהליך "בקשת חופשת עובדים":

קובץ BPMN 2.0, VacationRequest.bpmn20.xml, לתהליך זה מוגדר אירוע ההתחלה כ:

באופן דומה, משימת המשתמש הראשונה, שהוקצתה לקבוצת המשתמשים "ניהול", תיראה כך:

 $ {employeeName} רוצה לקחת {{NumberOfDays} ימים (ים) לחופשה (מוטיבציה: $ {סיבה}). הַנהָלָה 

עם ה ServiceTask, עלינו להגדיר את פיסת הקוד שתבוצע. יש לנו את פיסת הקוד הזו ככיתה של Java:

הזרימה המותנית תוצג על ידי הוספת ה- "תנאי ביטוי" התג ב- "רצף זרימה":

פה, חופשה מאושרת האם ה formProperty של ה UserTask המוצג לעיל.

כפי שניתן לראות בתרשים, זהו תהליך פשוט מאוד. העובד מגיש בקשת חופשה ומספק את מספר הימים ותאריך תחילת החופשה. הבקשה עוברת למנהל. הם יכולים לאשר / לא לאשר את הבקשה.

אם היא מאושרת, מוגדרת משימת שירות לשליחת דוא"ל האישור. אם לא אושר, העובד יכול לבחור לשנות ולשלוח שוב את הבקשה, או לא לעשות דבר.

משימות השירות מסופקות עם פיסת קוד כלשהי לביצוע (כאן, כמעמד Java). נתנו את הכיתה SendEmailServiceTask.java.

סוגים אלה של שיעורים צריכים להרחיב את JavaDelegate. כמו כן, עלינו לבטל את זה לבצע() שיטה, שתבוצע כאשר ביצוע התהליך יגיע לשלב זה.

5.1. פריסת תהליך

כדי להכיר את התהליך שלנו למנוע Activiti, עלינו לפרוס את התהליך. אנו יכולים לעשות זאת בתכנות באמצעות RepositoryService. בוא נכתוב מבחן JUnit כדי להראות זאת:

@Test הציבור בטל givenBPMN_whenDeployProcess_thenDeployed () {ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine (); RepositoryService repositoryService = processEngine.getRepositoryService (); repositoryService.createDeployment () .addClasspathResource ("org / activiti / test / vacationRequest.bpmn20.xml") .deploy (); ספירה ארוכה = repositoryService.createProcessDefinitionQuery (). Count (); assertEquals ("1", count.toString ()); }

פריסה פירושה שהמנוע ינתח את קובץ ה- BPMN וימיר אותו למשהו הפעלה. כמו כן, יתווסף רשומה לטבלת המאגר לכל פריסה.

לפיכך, לאחר מכן אנו יכולים לשאול את ה- מאגר שירות לקבלת התהליכים הפרוסים; ה הגדרות תהליך.

5.2. החל א ProcessInstance

לאחר פריסת ה- הגדרת תהליך ל- Activiti Engine, נוכל לבצע את התהליך על ידי יצירת ProcessInstances. ה הגדרת תהליך הוא תכנית מתאר, ו ProcessInstance הוא ביצוע זמן הריצה שלו.

לסינגל הגדרת תהליך, יכול להיות מספר רב ProcessInstances.

כל הפרטים הקשורים ל ProcessInstances ניתן לגשת דרך RuntimeService.

בדוגמה שלנו, באירוע ההתחלה, עלינו להעביר את מספר ימי החופשה, תאריך ההתחלה והסיבה. נשתמש במשתני התהליך ונעביר אותם תוך כדי יצירת ה- ProcessInstance.

בוא נכתוב מקרה מבחן JUnit כדי לקבל מושג טוב יותר:

@ Test public void givenDeployedProcess_whenStartProcessInstance_thenRunning () {// לפרוס את הגדרת התהליך משתני מפה = HashMap חדש> (); variables.put ("עובד שם", "ג'ון"); variables.put ("numberOfDays", 4); variables.put ("vacationMotivation", "אני צריך הפסקה!"); RuntimeService runtimeService = processEngine.getRuntimeService (); ProcessInstance processInstance = runtimeService .startProcessInstanceByKey ("vacationRequest", משתנים); ספירה ארוכה = runtimeService.createProcessInstanceQuery (). Count (); assertEquals ("1", count.toString ()); }

המופעים המרובים של הגדרת תהליך אחת ישתנו בהתאם למשתני התהליך.

ישנן מספר דרכים להתחיל מופע תהליך. כאן אנו משתמשים במפתח התהליך. לאחר התחלת מופע התהליך, אנו יכולים לקבל את המידע אודותיו על ידי שאילתת ה- RuntimeService.

5.3. השלמת המשימות

כאשר מופע התהליך שלנו מתחיל לפעול, השלב הראשון הוא משימת משתמש, המוקצית לקבוצת המשתמשים "הַנהָלָה".

למשתמש עשויה להיות תיבת דואר נכנס שתוכל לבצע רשימת משימות על ידם. כעת, אם אנו רוצים להמשיך בביצוע התהליך, המשתמש צריך לסיים את המשימה הזו. עבור Activiti Engine, זה נקרא "השלמת המשימה".

אנחנו יכולים לשאול את TaskService, כדי להשיג את אובייקט המשימה ואז להשלים אותו.

הקוד שאנחנו צריכים לכתוב בשביל זה נראה כמו:

@Test הציבור בטל givenProcessInstance_whenCompleteTask_thenGotNextTask () {// לפרוס תהליך ולהתחיל מופע תהליך TaskService taskService = processEngine.getTaskService (); רשימת משימות = taskService.createTaskQuery () .taskCandidateGroup ("ניהול"). רשימה (); משימה משימה = משימות.גט (0); מפה taskVariables = HashMap חדש (); taskVariables.put ("vacationApproved", "false"); taskVariables.put ("הערות", "יש לנו תאריך יעד צפוף!"); taskService.complete (task.getId (), taskVariables); משימה currentTask = taskService.createTaskQuery () .taskName ("שנה בקשת חופשה"). SingleResult (); assertNotNull (הנוכחי משימה); }

שים לב שה- לְהַשְׁלִים() שיטה של TaskService לוקח גם את משתני התהליך הנדרשים. אנו מעבירים את תשובת המנהל.

לאחר מכן, מנוע התהליך ימשיך לשלב הבא. כאן, השלב הבא שואל את העובד אם בקשת החופשה אמורה להישלח מחדש או לא.

אז שלנו ProcessInstance מחכה עכשיו על זה UserTask, שיש לו את השם “שנה חופשה בַּקָשָׁה".

5.4. השעיה והפעלת תהליך

אנחנו יכולים להשעות א הגדרת תהליך וגם א ProcessInstance. אם נשעה א תהליך הגדרה, איננו יכולים ליצור מופע שלו בזמן שהוא מושעה. אנו יכולים לעשות זאת באמצעות ה- מאגר שירות:

@Test (צפוי = ActivitiException.class) חלל ציבורי givenDeployedProcess_whenSuspend_thenNoProcessInstance () {// לפרוס את הגדרת התהליך repositoryService.suspendProcessDefinitionByKey ("vacationRequest"); runtimeService.startProcessInstanceByKey ("vacationRequest"); } 

כדי להפעיל אותו שוב, אנחנו רק צריכים להתקשר לאחד מה- repositoryService.activateProcessDefinitionXXX שיטות.

באופן דומה, אנו יכולים להשעות א תהליךInstance, משתמש ב RuntimeService.

6. מסקנה

במאמר זה ראינו כיצד נוכל להשתמש ב- Activiti עם Java. יצרנו מדגם ProcessEngineCofiguration קובץ, שעוזר לנו ליצור את ProcessEngine.

באמצעותו, ניגשנו לשירותים שונים הניתנים על ידי ה- API. שירותים אלה עוזרים לנו לנהל ולעקוב אחריהם הגדרות תהליך, ProcessInstances, משימות משתמש, וכו.

כמו תמיד, הקוד לדוגמאות שראינו במאמר מונח על GitHub.