Activiti - Mesin proses bisnis

Activiti framework (Java) - deskripsi aliran tugas XML (bpm) dan manajemennya. Di sini saya akan menjelaskan konsep dasar dasar dan cara membangun proses bisnis sederhana.

Konsep utama Activiti adalah proses dan tugas. Suatu proses adalah semua tugas yang saling berhubungan oleh aliran dan cabang yang diarahkan.

Saya akan menyentuh aspek-aspek tersebut:

  • - Activiti dalam bentuk yang paling murni
  • - Pengguna, Peran
  • - Hubungkan SpringBoot
  • - REST API
  • - Pekerjaan dan Delegasi

Pergerakan arus berjalan dalam langkah-langkah dari tugas ke tugas, setiap langkah tersebut menghentikan sementara proses sambil menunggu input dan penyelesaian tugas, semua tindakan menengah disimpan dalam database.

Di mana, apa yang harus diambil, saya akan tunjukkan di bawah ini. Mari kita mulai dengan contoh sederhana - proses pengembangan program, yang terdiri dari penulisan kode dan pengujian. Di bawah ini adalah diagram proses.

gambar

Ini semua proses, memiliki ID, Nama, dan karakteristik lainnya.

gambar

Itu memiliki:

Awal proses, dua tugas "Kembangkan" dan "Uji", satu cabang (gateway) dan akhir proses. Dengan kata lain, semuanya terjadi seperti ini:

  • memuat deskripsi bpm
  • mulai prosesnya
  • setelah memulai, kami langsung jatuh ke tugas Mengembangkan
  • setelah eksekusi Develop, ia pergi ke pengujian dan sesuai dengan hasil pengujian, proses berakhir atau kembali lagi ke pengembangan.

Activiti terdiri dari serangkaian layanan

Inilah yang utama:

  • RepositoryService: mengontrol pemuatan deskripsi proses
  • RuntimeService: memulai proses
  • TaskService: melakukan tugas
  • FormService: akses ke variabel tugas
  • HistoryService: akses ke riwayat proses
  • IdentityService: Pengguna dan Peran

Activiti dalam bentuk paling murni


Tapi itu semua dimulai dengan konfigurasi dan file - activiti.cfg.xml.

Dari sini

ProcessEngineConfiguration cfg = ProcessEngineConfiguration .createProcessEngineConfigurationFromResource("activiti.cfg.xml"); 

Jika Anda tidak menggunakan konfigurasi Anda, maka Activiti akan menyebarkan database dalam memori H2 itu sendiri, ini tidak cocok untuk saya, tetapi Oracle yang saya cintai penuh, ada opsi untuk menghubungkan database yang berbeda.

Ini konfigurasi saya

activiti.cfg.xml
 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"> <property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:xe" /> <property name="jdbcDriver" value="oracle.jdbc.driver.OracleDriver" /> <property name="jdbcUsername" value="BPM" /> <property name="jdbcPassword" value="1" /> <!-- Database configurations --> <property name="databaseSchemaUpdate" value="false" /> <property name="asyncExecutorActivate" value="false" /> <!-- mail server configurations --> <property name="mailServerPort" value="5025" /> </bean> </beans> 


Kami mengubah nilai dalam "nama properti = jdbc *" dan menghubungkan database lain

Struktur proyek



POM
 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>DemoActiviti</groupId> <artifactId>DemoActiviti</artifactId> <version>1.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.activiti</groupId> <version>6.0.0</version> <artifactId>activiti-spring-boot-starter-integration</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.21</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.21</version> </dependency> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> <version>11.2.0</version> </dependency> </dependencies> <build> <plugins> <!-- Maven Assembly Plugin --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>2.4.1</version> <configuration> <!-- get all project dependencies --> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <!-- MainClass in mainfest make a executable jar --> <archive> <manifest> <mainClass>com.example.DemoActiviti</mainClass> </manifest> </archive> </configuration> <executions> <execution> <id>make-assembly</id> <!-- bind to the packaging phase --> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project> 


Kehadiran plugin "maven-assembly-plugin" di POM akan memungkinkan Anda untuk membangun (paket) botol yang diluncurkan dengan dependensi dan dijalankan -
 java -jar DemoActiviti-1.0-SNAPSHOT-jar-with-dependencies.jar 

Driver jdbc untuk Oracle diinstal di repositori maven lokal

 mvn install:install-file -Dfile={Path/to/your/ojdbc6.jar} -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=11.2.0 -Dpackaging=jar 

log4j
 log4j.rootLogger=WARN, ACT log4j.appender.ACT=org.apache.log4j.ConsoleAppender log4j.appender.ACT.layout=org.apache.log4j.PatternLayout log4j.appender.ACT.layout.ConversionPattern= %d{hh:mm:ss,SSS} [%t] %-5p %c %x - %m%n 


Untuk proses ini, kami mendefinisikan 4 tindakan: pemuatan bpm, awal proses, pengembangan, dan pengujian. Setiap tindakan akan memiliki parameter yang sesuai: menyebarkan, memulai, mengembangkan, menguji.

Kami mengambil skrip untuk basis data
mulai aktif
ada di folder \ activiti-6.0.0 \ activiti-6.0.0 \ database \ create - skrip untuk membuat database

Pengguna, Peran


Siapkan pengguna dan peran:

Identitas
 public class DemoActiviti { private static final String DEV_PROCESS = "devProcess"; public static void main(String[] args) { Locale.setDefault(Locale.ENGLISH); ProcessEngineConfiguration cfg = ProcessEngineConfiguration .createProcessEngineConfigurationFromResource("activiti.cfg.xml"); ProcessEngine processEngine = cfg.buildProcessEngine(); createIdentity(processEngine, "programmer", "programmers"); createIdentity(processEngine, "tester", "testers"); } public static void createIdentity(ProcessEngine processEngine, String userName, String userGroup) { IdentityService identityService = processEngine.getIdentityService(); String userId = userName + "Id"; if (identityService.createUserQuery().userId(userId).count() == 0) { User user = identityService.newUser(userName); user.setId(userId); user.setEmail(userName + "@gmail.com"); identityService.saveUser(user); System.out.println("user created success fully"); } String groupId = userGroup + "Id"; if (identityService.createGroupQuery().groupId(groupId).count() == 0) { Group group = identityService.newGroup(userGroup); group.setName(userGroup); group.setId(groupId); identityService.saveGroup(group); System.out.println("group created success fully"); } if (identityService.createGroupQuery().groupId(groupId).list().size() > 0) { identityService.createMembership(userId, groupId); System.out.println("user to group success fully"); } } } 


Buat pengguna dan grup, pengembang dan penguji masing-masing.

Dalam database, semua tabel dibagi oleh layanan yang sesuai dan memiliki awalan

ACT_RE_ *: repositori.
ACT_RU_ *: runtime.
ACT_ID_ *: identitas.
ACT_HI _ *: sejarah
dan sebagainya

Setelah membuat pengguna dari, Anda dapat melihat di sini

gambar

Kami akan menugaskan tugas kami dalam deskripsi ke grup yang sesuai (CandidateGroup), misalnya, Mengembangkan tugas ke grup - programer

gambar

Dan hal pertama yang kita lakukan adalah menempatkannya di basis data "MyProcess.bpmn", jalankan program dengan perintah deploy

 java -jar DemoActiviti-1.0-SNAPSHOT-jar-with-dependencies.jar deploy 

selanjutnya, mulailah proses mulai

 java -jar DemoActiviti-1.0-SNAPSHOT-jar-with-dependencies.jar start 

Setelah delpoy dan memulai proses, entri yang sesuai akan muncul di database.

Repositori

gambar

Runtime tugas apa yang sedang dieksekusi

gambar

kepada siapa ditugaskan

gambar

Dalam kode tersebut, tampilannya seperti ini (kode lengkapnya ada di bawah):

menyebarkan

 deployment = repositoryService.createDeployment() .addClasspathResource("processes/MyProcess.bpmn").deploy() 

mulai

 ProcessInstance myProcess = runtimeService.startProcessInstanceByKey(DEV_PROCESS); 

berkembang

Setelah itu, Anda dapat mulai menyelesaikan tugas pengembangan.

 java -jar DemoActiviti-1.0-SNAPSHOT-jar-with-dependencies.jar develop 

  //    tasks = taskService.createTaskQuery().taskCandidateGroup("programmers").list(); 

Dalam tugas Mengembangkan, satu variabel "masalah" didefinisikan

gambar

Setelah memproses variabel menggunakan FormService, tugas berjalan

 for (Task task : tasks) { System.out.println("Task:" + task.getTaskDefinitionKey() + ", id=" + task.getId()); FormData formData = formService.getTaskFormData(task.getId()); Map<String, Object> variables = new HashMap<String, Object>(); //   for (FormProperty formProperty : formData.getFormProperties()) { System.out.println("Enter varName <" + formProperty.getName() +">:"); String value = scanner.nextLine(); variables.put(formProperty.getId(), value); } //   taskService.complete(task.getId(), variables); System.out.println("Task complete success:" + task.getTaskDefinitionKey()); } 

gambar

Untuk tugas Mengembangkan, Anda diminta untuk memasukkan variabel.

Di tabel historis, Anda bisa melihat variabel dan nilai tugas, proses

gambar

Dengan demikian, proses setelah tugas Mengembangkan akan berhenti di situ, negara akan disimpan dalam database.

Secara umum, loop terlihat seperti ini:

Meminta tugas untuk pelaksana

 tasks = taskService.createTaskQuery().taskCandidateGroup("...").list(); 

Definisi Variabel

 Map<String, Object> variables = new HashMap<String, Object>(); ... variables.put("var_1", value); 

Eksekusi tugas

 taskService.complete(task.getId(), variables); 

Memeriksa akhir proses

 ProcessInstance processInstance = runtimeService.createProcessInstanceQuery() .processInstanceId(processInstance.getId()).singleResult(); if (processInstance != null && !processInstance.isEnded()) 

Setelah setiap eksekusi tugas, proses ditangguhkan sampai tugas baru selesai.
Jadi, setelah menjalankan Develop, mari kita beralih ke tugas Uji, di sini kita juga akan diminta untuk memasukkan variabel "devResult" - hasil pengembangan (itu tidak berhasil dengan benar, bahkan sebelum Tes dimulai, masukkan hasilnya), dan kemudian hasilnya akan bercabang atau berakhir (Ok) atau pengembangan lagi (Tidak), lihat diagram proses.

gambar

Dalam hal ini, pengembangan, dll. Jika sekarang Anda meminta tugas untuk pengembang, mereka akan melakukannya, tetapi untuk pengujian - tidak.

Kode program
 package com.example; import org.activiti.engine.*; import org.activiti.engine.form.FormData; import org.activiti.engine.form.FormProperty; import org.activiti.engine.repository.Deployment; import org.activiti.engine.runtime.ProcessInstance; import org.activiti.engine.task.Task; import org.apache.commons.lang3.StringUtils; import java.util.*; public class DemoActiviti { private static final String DEV_PROCESS = "devProcess"; public static void main(String[] args) { Locale.setDefault(Locale.ENGLISH); ProcessEngineConfiguration cfg = ProcessEngineConfiguration .createProcessEngineConfigurationFromResource("activiti.cfg.xml"); ProcessEngine processEngine = cfg.buildProcessEngine(); RepositoryService repositoryService = processEngine.getRepositoryService(); String mode = StringUtils.EMPTY; if (args.length > 0) { mode = args[0]; } System.out.println("Processes mode: " + mode); Deployment deployment; if ("deploy".equals(mode)) { deployment = repositoryService.createDeployment() .addClasspathResource("processes/MyProcess.bpmn").deploy(); System.out.println("deploy process success"); System.exit(0); } else { List<Deployment> myProcesses = repositoryService.createDeploymentQuery() .processDefinitionKey(DEV_PROCESS).list(); deployment = myProcesses.get(myProcesses.size()-1); System.out.println("get process success:" + deployment.getId()); } // RuntimeService runtimeService = processEngine.getRuntimeService(); ProcessInstance processInstance; if ("start".equals(mode)){ ProcessInstance myProcess = runtimeService.startProcessInstanceByKey(DEV_PROCESS); System.out.println("start process success:" + myProcess.getName() +", id="+ myProcess.getId()); System.exit(0); } processInstance = runtimeService.createProcessInstanceQuery().deploymentId(deployment.getId()).singleResult(); TaskService taskService = processEngine.getTaskService(); FormService formService = processEngine.getFormService(); List<Task> tasks = new ArrayList<>(); if ("develop".equals(mode)) { System.out.println("develop mode"); //     tasks = taskService.createTaskQuery().taskCandidateGroup("programmers").list(); if (tasks.isEmpty()) { System.out.println("   "); System.exit(0); } } if ("test".equals(mode)) { System.out.println("test mode"); //     tasks = taskService.createTaskQuery().taskCandidateGroup("testers").list(); if (tasks.isEmpty()) { System.out.println("   "); System.exit(0); } } Scanner scanner = new Scanner(System.in); if (processInstance != null && !processInstance.isEnded()) { System.out.println("tasks count: [" + tasks.size() + "]"); for (Task task : tasks) { System.out.println("Task:" + task.getTaskDefinitionKey() + ", id=" + task.getId()); FormData formData = formService.getTaskFormData(task.getId()); Map<String, Object> variables = new HashMap<String, Object>(); //   for (FormProperty formProperty : formData.getFormProperties()) { System.out.println("Enter varName <" + formProperty.getName() +">:"); String value = scanner.nextLine(); variables.put(formProperty.getId(), value); } //   taskService.complete(task.getId(), variables); System.out.println("Task complete success:" + task.getTaskDefinitionKey()); } // Re-query the process instance, making sure the latest state is available //processInstance = runtimeService.createProcessInstanceQuery() // .processInstanceId(processInstance.getId()).singleResult(); } } } 


Hubungkan SpringBoot


Kami memodifikasi proyek menggunakan Spring

Tambahkan dependensi ke POM

POM dengan SpringBoot
  <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <dependencies> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-spring-boot-starter-basic</artifactId> <version>6.0.0</version> </dependency> <dependency> <groupId>org.activiti</groupId> <version>6.0.0</version> <artifactId>activiti-spring-boot-starter-integration</artifactId> </dependency> .... 


Kelas DemoActiviti sekarang menjadi seperti itu
DemoActiviti - SpringBootApplication
 @SpringBootApplication @ImportResource("classpath:activiti.cfg.xml") public class DemoActiviti { public static void main(String[] args) { Locale.setDefault(Locale.ENGLISH); SpringApplication.run(DemoActiviti.class, args); } } 


Saya menggunakan model campuran - ketika bagian kacang dijelaskan dalam konfigurasi xml (@ImportResource ("classpath: activiti.cfg.xml")), dan yang lainnya didefinisikan melalui anotasi.

activiti.cfg.xml - pegas
 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource"> <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe" /> <property name="driverClass" value="oracle.jdbc.driver.OracleDriver" /> <property name="username" value="BPM" /> <property name="password" value="1" /> </bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration"> <property name="dataSource" ref="dataSource" /> <property name="transactionManager" ref="transactionManager" /> <property name="databaseSchemaUpdate" value="true" /> <property name="asyncExecutorActivate" value="false" /> </bean> </beans> 


Sekarang Spring bertanggung jawab atas konfigurasi, itu bisa dilihat

 bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration" 

Tambahkan pemrosesan baris perintah standar untuk SpringBoot sebagai komponen

Commandline
 @Component public class CommandLine implements CommandLineRunner { @Autowired private DemoService demoService; public void run(String... args) { if ("test".equals(args[0])) { demoService.startTest(); } else if ("develop".equals(args[0])) { demoService.startDevelop(); } } } 


Yang akan memproses semua perintah itu, saya tidak akan mengimplementasikan semuanya, semuanya sederhana di sana, saya akan menunjukkan dua: menguji dan mengembangkan. Dan menambahkan layanan untuk memprosesnya

Layanan Demo
 @Service public class DemoService { @Autowired private TaskService taskService; @Autowired private FormService formService; public void startTest() { List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("testers").list(); if (tasks.isEmpty()) { System.out.println("   "); return; } processTasks(tasks); } public void startDevelop() { List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("develop").list(); if (tasks.isEmpty()) { System.out.println("   "); return; } processTasks(tasks); } private void processTasks(List<Task> tasks) { Scanner scanner = new Scanner(System.in); for (Task task : tasks) { ......    ,  } 


Dalam komponen CommandLine Autowir, mereka memiliki layanan DemoService, dan di dalamnya layanan Spring Activiti sudah disiapkan

 @Autowired private TaskService taskService; 

Kami mengumpulkan, menjalankan seperti sebelumnya dari baris perintah.

Jika kami ingin menggunakan eksekusi tugas dari Web, maka kami menghubungkan REST API.

API SISA


SpringBoot akan menyediakan server Tomcat tertanam secara default, dan kemudian masalah teknis.
Di POM, seperti apa adanya, tambahkan ketergantungan web spring

  <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> 

Kami menghapus komponen CommandLine, sekarang semuanya akan datang melalui URL melalui HTTP. Tambahkan RestController:

Restcontroller
 @RestController public class DemoRestController { @Autowired private DemoService demoService; @RequestMapping(value="/test", method= RequestMethod.GET, produces= {MediaType.APPLICATION_JSON_VALUE}) public List<String> startTest(@RequestParam String devResult) { List<String> strings = demoService.startTest(devResult); return strings; } @RequestMapping(value="/develop", method= RequestMethod.GET, produces= MediaType.APPLICATION_JSON_VALUE) public List<String> startDevelop(@RequestParam String issue) { List<String> strings = demoService.startDevelop(issue); return strings; } @RequestMapping(value="/start", method= RequestMethod.GET, produces= MediaType.APPLICATION_JSON_VALUE) public List<String> startProcess() { List<String> strings = demoService.startDevProcess(); return strings; } } 


Kami menjalankan perintah yang sama, sedikit mengubah respons dari layanan DemoService, yang Autowire berada di controller.

Layanan Demo
 @Service public class DemoService { @Autowired private TaskService taskService; @Autowired private FormService formService; @Autowired private RuntimeService runtimeService; public List<String> startTest(String devResult) { List<String> results = new ArrayList<>(); List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("testers").list(); if (tasks.isEmpty()) { results.add("The tasks for testing are not"); return results; } Object issue = runtimeService.getVariables(tasks.get(0).getProcessInstanceId()).get("issue"); processTasks(tasks, devResult); results.add("Task N " + issue + " - tested, result=" + devResult); return results; } public List<String> startDevelop(String issue) { List<String> results = new ArrayList<>(); List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("programmers").list(); if (tasks.isEmpty()) { results.add("There are no development tasks"); return results; } processTasks(tasks, issue); Object mIssue = runtimeService.getVariables(tasks.get(0).getProcessInstanceId()).get("issue"); results.add("Task N " + mIssue + " - taken in the develop"); return results; } public List<String> startDevProcess() { List<String> results = new ArrayList<>(); ProcessInstance myProcess = runtimeService.startProcessInstanceByKey("devProcess"); results.add("The process is started #"+myProcess.getId()); return results; } private void processTasks(List<Task> tasks, String param) { for (Task task : tasks) { FormData formData = formService.getTaskFormData(task.getId()); Map<String, Object> variables = new HashMap<>(); //   for (FormProperty formProperty : formData.getFormProperties()) { variables.put(formProperty.getId(), param); } //   taskService.complete(task.getId(), variables); } } } 


pengujian menggunakan curl, berikut hasilnya:

gambar

Saya mengubah port untuk Tomcat ke 8081 di application.properties
server.port = 8081

Pekerjaan aktiviti


Activiti memiliki banyak desain, misalnya, meluncurkan tugas yang dijadwalkan adalah "TimerStartEvent". Agar Ayub mulai menjalankan dalam pengekangan, Anda harus menentukan
property name="asyncExecutorActivate" value="true" (lihat activiti.cfg.xml), maka proses java akan tetap berjalan dan akan memeriksa jadwal dan menjalankan tugas.

Saya akan kembali ke proyek awal, di mana Activiti digunakan dalam bentuk yang paling murni.

Di kelas DemoActiviti saya akan meninggalkan dukungan hanya untuk dua perintah: deploy dan mulai saya akan membuat proses baru

gambar

Setelah dimulainya proses, ia akan pergi ke timer, yang menurut jadwal akan meluncurkan tugas "Mengembangkan". Timer akan memiliki jadwal - mulai setiap 10 detik, ekspresi cron - β€œ0/10 * * * * *?”.

gambar

Mari kita gunakan proses baru seperti sebelumnya, lalu mulai prosesnya (mulai). Semua - tugas berjalan setiap 10 detik.

Sebagai tugas, komponen Activiti dipilih - ServiceTask, yang darinya Anda dapat menentukan sebagai implementasi kelas Java

gambar

DemoDelegate kelas
 public class DemoDelegate implements JavaDelegate { @Override public void execute(DelegateExecution execution) { Date now = new Date(); execution.setVariable("issue", now.toString()); System.out.println("job start="+now); } } 


Pada tabel dalam database (pilih * dari ACT_RU_TIMER_JOB t) Anda dapat melihat

gambar

Aktivitas kerja, di bidang DUEDATE_ akan ada waktu untuk memulai berikutnya.

Variabel "masalah" dari Delegasi akan direkam dalam riwayat eksekusi

 select * from ACT_HI_VARINST t 

gambar

kode untuk DemoActiviti c Job
 public class DemoActiviti { private static final String DEV_PROCESS = "devProcessJob"; public static void main(String[] args) { Locale.setDefault(Locale.ENGLISH); ProcessEngineConfiguration cfg = ProcessEngineConfiguration .createProcessEngineConfigurationFromResource("activiti.cfg.xml"); ProcessEngine processEngine = cfg.buildProcessEngine(); RepositoryService repositoryService = processEngine.getRepositoryService(); String mode = StringUtils.EMPTY; if (args.length > 0) { mode = args[0]; } System.out.println("Processes mode: " + mode); Deployment deployment; if ("deploy".equals(mode)) { deployment = repositoryService.createDeployment() .addClasspathResource("processes/MyProcessJob.bpmn").deploy(); System.out.println("deploy process success"); System.exit(0); } else { List<Deployment> myProcesses = repositoryService.createDeploymentQuery() .processDefinitionKey(DEV_PROCESS).list(); deployment = myProcesses.get(myProcesses.size()-1); System.out.println("get process success:" + deployment.getId()); } // RuntimeService runtimeService = processEngine.getRuntimeService(); ProcessInstance processInstance; if ("start".equals(mode)){ ProcessInstance myProcess = runtimeService.startProcessInstanceByKey(DEV_PROCESS); System.out.println("start process success:" + myProcess.getName() +", id="+ myProcess.getId()); } } } 


Masih banyak yang tertinggal: Acara, Pendengar, JPA, dll., Mungkin saya akan kembali ke mereka.

Material
Activiti
Desainer gerhana

devProses bpmn
 <?xml version="1.0" encoding="UTF-8"?> <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test"> <process id="devProcess" name="Dev process" isExecutable="true"> <startEvent id="startevent1" name="Start" activiti:initiator="programmerId"></startEvent> <userTask id="develop" name="Develop" activiti:candidateGroups="programmers"> <extensionElements> <activiti:formProperty id="issue" name="issue" type="string" required="true"></activiti:formProperty> </extensionElements> </userTask> <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="develop"></sequenceFlow> <userTask id="test" name="Test" activiti:candidateGroups="testers"> <extensionElements> <activiti:formProperty id="devResult" name="devResult" type="string" default="No" required="true"></activiti:formProperty> </extensionElements> </userTask> <sequenceFlow id="flow2" sourceRef="develop" targetRef="test"></sequenceFlow> <exclusiveGateway id="gateway" name="Exclusive Gateway" default="flowNo"></exclusiveGateway> <sequenceFlow id="flow3" sourceRef="test" targetRef="gateway"></sequenceFlow> <sequenceFlow id="flowOk" name="Ok" sourceRef="gateway" targetRef="endevent1"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${devResult == "Ok"}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="flowNo" name="No" sourceRef="gateway" targetRef="develop"></sequenceFlow> <endEvent id="endevent1" name="End"></endEvent> </process> </definitions> 


devProcessJob bpmn
 <?xml version="1.0" encoding="UTF-8"?> <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test"> <process id="devProcessJob" name="Dev process Job" isExecutable="true"> <startEvent id="startevent" name="Start" activiti:initiator="programmerId"></startEvent> <sequenceFlow id="flow1" sourceRef="startevent" targetRef="timerstartevent"></sequenceFlow> <endEvent id="endevent" name="End"></endEvent> <startEvent id="timerstartevent" name="Timer start"> <extensionElements> <activiti:formProperty id="issue" name="issue" type="string"></activiti:formProperty> </extensionElements> <timerEventDefinition> <timeCycle>0/10 * * * * ?</timeCycle> </timerEventDefinition> </startEvent> <sequenceFlow id="flow2" sourceRef="timerstartevent" targetRef="servicetask1"></sequenceFlow> <sequenceFlow id="flow3" sourceRef="servicetask1" targetRef="endevent"></sequenceFlow> <serviceTask id="servicetask1" name="Develop" activiti:class="com.example.DemoDelegate"></serviceTask> </process> </definitions> 

Source: https://habr.com/ru/post/id416491/


All Articles