最近在研究工作流引擎Activiti,所以从搭建环境写demo开始说起。环境是JDK1.8+SpingBoot+MyBatis+Activiti
由于IDEA自己集成了Springboot的插件,因此如果采用IDEA去搭建环境,可以直接选择New一个Springboot的项目,然后根据自己需要勾选选项。比如Web,SQL,NOSQL等一些与SpringBoot集成的组件。这样会自动帮你在pom文件下载所需依赖,而不用自己手动去引了;如果是Eclipse的话,想要实现以上方式,也能做到。在上方导航栏Help中选择Eclipse Marketplace,然后搜索STS,下载安装即可集成至Eclipse里面去。这样在新建项目的时候,也是可以直接选择SpringBoot项目,比较省事方便。当然,以上两种方式都只是针对IDE,我们依然可以像以前一样,选择创建普通的Maven工程,然后在pom.xml文件中手动添加依赖。所需依赖如下:
<?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.0http://maven.apache.org/xsd/maven-4.0.0.xsd";>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-basic</artifactId>
<version>5.21.0</version>
</dependency>
<!-- 内存数据库 -->
<!-- <dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency> -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<!-- <scope>runtime</scope> -->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency> -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<distributionManagement>
<repository>
<id>Releases</id>
<name>Nexus Release Repository</name>
<url>http://anxpp.com/nexus/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id>Snapshots</id>
<name>Nexus Snapshot Repository</name>
<url>http://anxpp.com/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
<repositories>
<repository>
<id>nexus</id>
<name>Nexus</name>
<url>http://anxpp.com/nexus/content/groups/public/</url>
<layout>default</layout>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</project>
主要有效信息都在dependency中。其中spring-boot-starter为我们在SpringBoot下使用Activiti做了以下这样的配置:
1、自动创建Activiti ProcessEngine的Bean
2、所有的Activiti Service都被自动注册成Spring的Bean
3、创建一个Spring Job Executor
4、会自动扫描位于src/main/resource/processess目录下的流程处理文件(.bpmn)
Activiti自带的是叫做h2的内存型数据库,这里我们使用了mysql。
SpringBoot项目的目录结构大概如上图所示,其中主要的区别就是:
1、会有一个启动类DemoApplication,里面一个main方法用来执行启动该应用。
2、在resource下会有两个自带的文件夹,一个叫做template(用来存放html页面),一个static(用来存放静态资源,比如js、css)当然这是SpringBoot推荐的做法
3、resource下有一个叫做application.properties的配置文件,这个文件是在应用启动时默认读取加载的。里面什么都可以写,包括JDBC或者是mybatis等组件的配置,当然,你也可以什么都不写,也不会影响。
application.properties文件的配置:
spring.jpa.hibernate.ddl-auto=update
spring.jpa.database=MYSQL
spring.datasource.url=jdbc:mysql://localhost:3306/spring-boot-activiti?characterEncoding=utf8&useSSL=true
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
mybatis.typeAliasesPackage=com.example.demo.entity(可以给实体类起别名)
mybatis.mapperLocations=classpath:mappers/*.xml(扫描此路径下的mapper文件)
spring.activiti.check-process-definitions=false
spring.activiti.check-process-definitions=false//这个需要指定为false或者是要注释掉,它的意思是在启动应用时是否扫描processes下的流程文件,指定为false即为不扫描。当然可以不写,我这里只是记录一下当时我犯的一个错误。
这行代码最早是怎么来的呢,是因为最开始为了测试SpringBoot应用启动的时候去加的,因为这个时候还没有画流程图,即没有.bpmn文件,项目在启动时候扫描不到该文件就会报错。
在resource下新建processes目录,然后在此目录下新建选择Activiti Diagram,会生成一个以.bpmn结尾的文件,进行组件的拖拽画一个流程图就可以了。界面如下:
上图是一个比较简单的demo,右侧是可拖拽的各种组件,结束部分的圆圈是EndEvent,连线属于SequenceFlow,我在图中忘记标识了。大致流程就是发起一个请假流程,然后到项目经理审批,再到人事经理审批,最后结束这样的一个流程。
接下来简单介绍下上图用到的组件分别代表什么含义:
- 开始事件(StartEvent):流程的开始
- 业务任务(ServiceTask):表示一个业务操作,比如上图修改状态为进行中或者是已完成(也可以用0/1表示)
- 用户任务(UserTask):审批人,参与人,交与谁进行流程的继续。主要有id,name等属性
- 排它网关(ExclusiveGateway):该网关可以看作是一个开关或者是阀门。它只能选择一条可以继续下去的流程路线。不管申请被谁驳回都是直接结束。
- 顺序流(SequenceFlow):主要有id,name和condition。condition表示满足该顺序流执行的条件表达式。
SpringBoot启动类:
注意需要加注解@SpringBootApplication,这标识为它是一个启动类。@MapperScan是扫描mapper接口的,当然也可以在每一个dao接口上去加@Mapper,二者作用相同。
SpringApplication.run(DemoApplication.class, args);//这行代码就是启动应用的,以当前类为参数,后面一个参数可填可不填。
注意事项:
1、注意activiti-spring-boot-starter-basic的版本号,推荐使用5.21.0。如果使用的5.17的版本,在启动流程的时候,不会自动帮你部署,因此在这之前需要自己手动的部署一次。5.21.0版本的话就不会出现这个问题。
2、注意启动流程引擎的时候传入的key要和流程配置文件中的id保持一致。(以xml文件格式打开查看)
或者是以Activiti Diagram Editor图形化界面打开,就是下图这样。
启动流程的代码部分:
这里需要一个RuntimeService实例调用startProcessInstanceByKey(String processDefinitionKey,String bussinessKey)
如果这里传入的key和流程文件中的id对应不上的话,就会报一个找不到该key对应的流程被部署的异常。
3、如果需要手动部署的话,核心代码如下:
@Resource
RepositoryService repositoryService;
//需要一个RepositoryService实例去调用方法,读取类路径下processes目录下面的MyProcess.bpmn文件,进行部署。
repositoryService.createDeployment().name("qjlc111").addClasspathResource("processes/MyProcess.bpmn").deploy();
4、不管是我们手动部署,还是它已经自动帮我们部署了,我们都可以通过检查库表中的记录来确定。
如果流程已经被发布出去,那么在该表中会生成两条记录。一个是bpmn结尾的文件名,一个是生成的.png结尾的流程图。而且多次发布同一个流程,会生成不同的版本号,来作为区分。(DEPLOYMENT_ID_)
主要的注意事项就这么多了,剩下的想到再说。
源码地址:https://github.com/Anthony-Lu/springboot-activiti-test.git
附:一个完整的带有前端页面的示例