入门 #
需要两个依赖
<properties>
<flowable.version>6.7.2</flowable.version>
</properties>
<dependencies>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter</artifactId>
<version>${flowable.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.212</version>
</dependency>
</dependencies>
结合Spring:
只需将依赖项添加到类路径并使用*@SpringBootApplication*注释,幕后就会发生很多事情:
自动创建内存数据源(因为 H2 驱动程序位于类路径中)并传递给 Flowable 流程引擎配置
已创建并公开了 Flowable ProcessEngine、CmmnEngine、DmnEngine、FormEngine、ContentEngine 和 IdmEngine bean
所有 Flowable 服务都暴露为 Spring bean
Spring Job Executor 已创建
将自动部署流程文件夹中的任何 BPMN 2.0 流程定义。创建一个文件夹processes并将一个虚拟进程定义(名为one-task-process.bpmn20.xml)添加到此文件夹。该文件的内容如下所示。
<?xml version="1.0" encoding="UTF-8"?> <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:flowable="http://flowable.org/bpmn" targetNamespace="Examples"> <process id="oneTaskProcess" name="The One Task Process"> <startEvent id="theStart" /> <sequenceFlow id="flow1" sourceRef="theStart" targetRef="theTask" /> <userTask id="theTask" name="my task" flowable:assignee="kermit" /> <sequenceFlow id="flow2" sourceRef="theTask" targetRef="theEnd" /> <endEvent id="theEnd" /> </process> </definitions>
案例文件夹中的任何 CMMN 1.1 案例定义都将自动部署。
将自动部署dmn文件夹中的任何 DMN 1.1 dmn 定义。
表单文件夹中的任何表单定义都将自动部署。
java代码 在项目服务启动的时候就去加载一些数据
@SpringBootApplication(proxyBeanMethods = false)
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
@Bean
public CommandLineRunner init(final RepositoryService repositoryService,
final RuntimeService runtimeService,
final TaskService taskService) {
//该bean在项目服务启动的时候就去加载一些数据
return new CommandLineRunner() {
@Override
public void run(String... strings) throws Exception {
//有几个流程定义
System.out.println("Number of process definitions : "
+ repositoryService.createProcessDefinitionQuery().count());
//有多少个任务
System.out.println("Number of tasks : " + taskService.createTaskQuery().count());
runtimeService.startProcessInstanceByKey("oneTaskProcess");
//开启流程后有多少个任务(+1)
System.out.println("Number of tasks after process start: "
+ taskService.createTaskQuery().count());
}
};
}
}
更改数据库 #
添加依赖
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.29</version> </dependency>
application.yml中添加配置
spring: datasource: url: jdbc:mysql://localhost:3306/flowable-spring-boot?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&nullCatalogMeansCurrent=true username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver
Rest支持 #
web支持
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.7</version> </parent>
添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
使用Service启动流程及获取给定受让人的任务
@Service public class MyService { @Autowired private RuntimeService runtimeService; @Autowired private TaskService taskService; @Transactional public void startProcess() { runtimeService.startProcessInstanceByKey("oneTaskProcess"); } @Transactional public List<Task> getTasks(String assignee) { return taskService.createTaskQuery().taskAssignee(assignee).list(); } }
创建REST端点
@RestController public class MyRestController { @Autowired private MyService myService; @PostMapping(value="/process") public void startProcessInstance() { myService.startProcess(); } @RequestMapping(value="/tasks", method= RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE) public List<TaskRepresentation> getTasks(@RequestParam String assignee) { List<Task> tasks = myService.getTasks(assignee); List<TaskRepresentation> dtos = new ArrayList<TaskRepresentation>(); for (Task task : tasks) { dtos.add(new TaskRepresentation(task.getId(), task.getName())); } return dtos; } static class TaskRepresentation { private String id; private String name; public TaskRepresentation(String id, String name) { this.id = id; this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } }
使用下面语句进行测试
curl http://localhost:8080/tasks?assignee=kermit [] curl -X POST http://localhost:8080/process curl http://localhost:8080/tasks?assignee=kermit [{"id":"10004","name":"my task"}]
JPA支持 #
添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
创建一个实体类
@Entity class Person { @Id @GeneratedValue private Long id; private String username; private String firstName; private String lastName; private Date birthDate; public Person() { } public Person(String username, String firstName, String lastName, Date birthDate) { this.username = username; this.firstName = firstName; this.lastName = lastName; this.birthDate = birthDate; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public Date getBirthDate() { return birthDate; } public void setBirthDate(Date birthDate) { this.birthDate = birthDate; } }
属性文件添加
spring.jpa.hibernate.ddl-auto=update
添加Repository类
@Repository public interface PersonRepository extends JpaRepository<Person, Long> { Person findByUsername(String username); }
代码
添加事务
startProcess现在修改成:获取传入的受理人用户名,查找Person,并将PersonJPA对象作为流程变量放入流程实例中
在CommandLineRunner中初始化时创建用户
@Service @Transactional public class MyService { @Autowired private RuntimeService runtimeService; @Autowired private TaskService taskService; @Autowired private PersonRepository personRepository; public void startProcess(String assignee) { Person person = personRepository.findByUsername(assignee); Map<String, Object> variables = new HashMap<String, Object>(); variables.put("person", person); runtimeService.startProcessInstanceByKey("oneTaskProcess", variables); } public List<Task> getTasks(String assignee) { return taskService.createTaskQuery().taskAssignee(assignee).list(); } public void createDemoUsers() { if (personRepository.findAll().size() == 0) { personRepository.save(new Person("jbarrez", "Joram", "Barrez", new Date())); personRepository.save(new Person("trademakers", "Tijs", "Rademakers", new Date())); } } }
CommandRunner修改
@Bean public CommandLineRunner init(final MyService myService) { return new CommandLineRunner() { public void run(String... strings) throws Exception { myService.createDemoUsers(); } }; }
RestController修改
@RestController public class MyRestController { @Autowired private MyService myService; @PostMapping(value="/process") public void startProcessInstance(@RequestBody StartProcessRepresentation startProcessRepresentation) { myService.startProcess(startProcessRepresentation.getAssignee()); } ... static class StartProcessRepresentation { private String assignee; public String getAssignee() { return assignee; } public void setAssignee(String assignee) { this.assignee = assignee; } }
修改流程定义
<userTask id="theTask" name="my task" flowable:assignee="${person.id}"/>
测试
启动spring boot之后person表会有两条数据
启动流程实例
此时会把从数据库查找到的person传入流程图(变量)
curl -H "Content-Type: application/json" -d '{"assignee" : "jbarrez"}' http://localhost:8080/process
使用id获取任务列表
curl http://localhost:8080/tasks?assignee=1 [{"id":"12505","name":"my task"}]