之前我们学习了Activiti的开发环境的搭建,下面我们开始学习如何在搭建的开发环境中进行Activiti的开发。为了进行一些简单的测试,我们采用Maven工程,然后采用spring-test和junit集成进行测试验证。
第一步:创建Maven工程,加载依赖包,具体的pom.xml文件如下:
<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>com.dfbhaiou.demo</groupId>
<artifactId>activiti</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 设定除中央仓库(repo1.maven.org/maven2/)外的其他仓库,按设定顺序进行查找. -->
<properties>
<jackson.version>2.2.3</jackson.version>
<activiti.version>5.18.0</activiti.version>
</properties>
<repositories>
<repository>
<id>oschina</id>
<name>oschina repository</name>
<url>http://maven.oschina.net/content/groups/public/</url>
</repository>
<repository>
<id>oschina-thirdparty</id>
<name>oschina thirdparty repository</name>
<url>http://maven.oschina.net/content/repositories/thirdparty/</url>
</repository>
<repository>
<id>central</id>
<name>Central Repository</name>
<url>http://repo.maven.apache.org/maven2</url>
</repository>
<repository>
<id>org.springframework.maven.milestone</id>
<name>Spring Framework Maven Milestone Repository</name>
<url>http://maven.springframework.org/milestone</url>
</repository>
<repository>
<id>Activiti</id>
<url>https://maven.alfresco.com/nexus/content/groups/public</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.29</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>3.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>3.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>3.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>3.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>3.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.5</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.6</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-model</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-converter</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-process-validation</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.6</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!-- jackson -->
<!-- JSON begin -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- JSON end -->
</dependencies>
<build>
<finalName>gtjTelManager</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<encoding>utf-8</encoding>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
<!-- 将资源包和src下的*.hbm.xml和*.xml打包 -->
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
</project>
第二步:配置数据库和activiti(数据库使用activiti-explorer工程的)
数据库的配置文件和activiti的配置文件可以使用activiti-explorer项目下的activiti-standalone-context.xml和db.properties。因为activiti-explorer项目使用的dbcp连接池,而我个人喜好使用c3p0的连接池,所以做了少许的改动,spring的配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="dataSource-dhcp" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/activiti" />
<property name="username" value="root" />
<property name="password" value="123456" />
<property name="defaultAutoCommit" value="false" />
</bean>
<!-- 配置数据源 start -->
<bean id="placeholderConfig"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:init.properties</value>
</property>
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass">
<value>${datasource.driverClassName}</value>
</property>
<property name="jdbcUrl">
<value>${datasource.url}</value>
</property>
<property name="user">
<value>${datasource.username}</value>
</property>
<property name="password">
<value>${datasource.password}</value>
</property>
<property name="acquireIncrement">
<value>${c3p0.acquireIncrement}</value>
</property>
<property name="initialPoolSize">
<value>${c3p0.initialPoolSize}</value>
</property>
<property name="minPoolSize">
<value>${c3p0.minPoolSize}</value>
</property>
<property name="maxPoolSize">
<value>${c3p0.maxPoolSize}</value>
</property>
<property name="maxIdleTime">
<value>${c3p0.maxIdleTime}</value>
</property>
<property name="idleConnectionTestPeriod">
<value>${c3p0.idleConnectionTestPeriod}</value>
</property>
<property name="maxStatements">
<value>${c3p0.maxStatements}</value>
</property>
<property name="numHelperThreads">
<value>${c3p0.numHelperThreads}</value>
</property>
</bean>
<bean id="processEngineConfiguration"
class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="dataSource" ref="dataSource" />
<property name="databaseType" value="mysql"/>
<property name="databaseSchemaUpdate" value="true" />
<property name="jobExecutorActivate" value="false" />
</bean>
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>
<bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
<bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
<bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
<bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
<bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
配置好这些后,我们就可以开始编写测试类了。
测试类如下:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring-activiti.xml"})
@TransactionConfiguration(transactionManager="transactionManager", defaultRollback=false)
@Transactional
public class ActivitiTestCase extends AbstractTransactionalJUnit4SpringContextTests{
@Test
public void test(){
System.out.println ("test");
}
}
运行上面的单元测试代码,如果在控制台输出test,那代表我们前面的配置都OK了。
下面我们就开始使用学习二中安装的插件画流程图并部署。
第一步:新建如下结构的目录
建好后,新建一个 activiti Diagram文件,如上图所示的MyProcess.bpmn,建好后,使用Activiti Diagram Editor打开MyProcess.bpmn文件,然后设计一个简单的流程:员工填写年度报告,提交后由主管进行审批,审批通过后,在由经理审批。流程有开始和结束节点,设计好的流程如下;
填写:由sales来进行操作
主管审批和经理审批:由management来进行操作
设计好流程后,如果没有生成对应的流程图片,打开window=>Preferences=>activiti
勾选Save Actions中的Create Process definition image选项:如下图:
保存后,过一会就会在同目录下生成一个图片:
流程设计好后,下面就是部署了,有2种方式,我们这里采用代码的方式进行部署并测试。代码部署方式如下:
<span style="font-family:Microsoft YaHei;font-size:18px;">public class BpmDefinitionTest extends ActivitiTestCase{
@Resource
private RepositoryService repositoryService;
@Resource
private RuntimeService runtimeService;
@Resource
private TaskService taskService;
@Resource
private HistoryService historyService;
@Test
public void testDeploy(){
String filePath="/diagrams/simpleProcess/MyProcess.bpmn";
try {
InputStream is = Class.class.getClass().getResource(filePath).openStream();
/*//读取bpmn文件,并发布
Deployment deployment=repositoryService.createDeployment().addInputStream("bpmn20.xml",is).deploy();
ProcessDefinition processDefinition = repositoryService.createProcessDefin.itionQuery().deploymentId(deployment.getId()).singleResult();
Long businessKey=new Double(1000000*Math.random()).longValue();
//启动流程
runtimeService.startProcessInstanceById(processDefinition.getId(),businessKey.toString());
//查询任务实例
List<Task> taskList=taskService.createTaskQuery().processDefinitionId(processDefinition.getId()).list();
for(Task task:taskList){
System.out.println("task name is " + task.getName() + " ,task key is " + task.getTaskDefinitionKey());
}*/
// 部署流程定义
repositoryService.createDeployment().addInputStream("bpmn20.xml",is).deploy();
// 启动流程实例
String procId = runtimeService.startProcessInstanceByKey("myProcess").getId();
/******************第一个任务开始******************************/
List<Task> taskList = taskService.createTaskQuery().taskCandidateGroup("sales").list();
for (Task task : taskList) {
System.out.println("Following task is available for sales group: " + task.getName());
// 认领任务这里由foozie认领,因为fozzie是sales组的成员
taskService.claim(task.getId(), "gonzo");
}
//查看fozzie是否能够获取该任务
taskList = taskService.createTaskQuery().taskAssignee("gonzo").list();
System.out.println("fozzie当前的任务数:" + taskList.size());
for(Task task : taskList){
System.out.println("the task name is :" + task.getName());
// 执行(完成)任务
taskService.complete(task.getId());
}
System.out.println("gonzo当前的任务数:" + taskService.createTaskQuery().taskAssignee("gonzo").count());
/******************第一个任务结束******************************/
/******************第二个任务开始******************************/
taskList = taskService.createTaskQuery().taskCandidateGroup("management").list();
for(Task task : taskList){
System.out.println("Following task is available for management group: " + task.getName());
taskService.claim(task.getId(), "kermit");
}
//查看kermit是否能够获取改任务
taskList = taskService.createTaskQuery().taskAssignee("kermit").list();
System.out.println("kermit当前任务数:" + taskList.size());
for(Task task : taskList){
System.out.println("the task name is :" + task.getName());
taskService.complete(task.getId());
}
System.out.println("kermit当前任务数:" + taskService.createTaskQuery().taskAssignee("kermit").count());
/******************第二个任务结束******************************/
/******************第三个任务开始******************************/
//获取第三个任务
taskList = taskService.createTaskQuery().taskCandidateGroup("management").list();
for(Task task : taskList){
System.out.println("Following task is available for management group: " + task.getName());
taskService.claim(task.getId(), "gonzo");
}
//查看gonzo是否能够获取改任务
taskList = taskService.createTaskQuery().taskAssignee("gonzo").list();
System.out.println("gonzo当前任务数:" + taskList.size());
for(Task task : taskList){
System.out.println("the task name is :" + task.getName());
taskService.complete(task.getId());
}
System.out.println("gonzo当前任务数:" + taskService.createTaskQuery().taskAssignee("gonzo").count());
/******************第三个任务结束******************************/
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
.processInstanceId(procId).singleResult();
System.out.println("流程结束时间:" + historicProcessInstance.getEndTime());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}<strong>
</strong></span>
这里只是简单的使用了activiti的几个api,具体的过程为:部署流程,然后启动流程实例,之后对应节点的用户组用户签收任务并处理直至流程结束。
部署bpmn并测试就到这里了,下一章我们将学习如何部署含有图片的流程实例。