Spring + Activiti + Drools整合的请假例子
如果请假总天数大于等于3天,则需要总经理审批,否则不需要总经理审批
如果当次请假小于3天,则请假总天数等于当次请假天数+2
否则,请假总天数等于当次请假次数+5
其中,总的请假次数的计算逻辑交给drools处理
新建maven项目,目录结构如下:
一:加入maven依赖:
[html] view plain copy
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <activiti.version>5.17.0</activiti.version>
- <drools.version>5.6.0.Final</drools.version>
- </properties>
- <dependencies>
- <dependency>
- <groupId>org.drools</groupId>
- <artifactId>drools-core</artifactId>
- <version>${drools.version}</version>
- </dependency>
- <dependency>
- <groupId>org.drools</groupId>
- <artifactId>drools-compiler</artifactId>
- <version>${drools.version}</version>
- </dependency>
- <dependency>
- <groupId>org.activiti</groupId>
- <artifactId>activiti-engine</artifactId>
- <version>${activiti.version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.activiti</groupId>
- <artifactId>activiti-bpmn-layout</artifactId>
- <version>${activiti.version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.activiti</groupId>
- <artifactId>activiti-spring</artifactId>
- <version>${activiti.version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.postgresql</groupId>
- <artifactId>postgresql</artifactId>
- <version>9.4-1201-jdbc41</version>
- </dependency>
- </dependencies>
-
<properties>
-
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
扫描二维码关注公众号,回复: 4350734 查看本文章 -
<activiti.version>5.17.0</activiti.version>
-
<drools.version>5.6.0.Final</drools.version>
-
</properties>
-
<dependencies>
-
<dependency>
-
<groupId>org.drools</groupId>
-
<artifactId>drools-core</artifactId>
-
<version>${drools.version}</version>
-
</dependency>
-
<dependency>
-
<groupId>org.drools</groupId>
-
<artifactId>drools-compiler</artifactId>
-
<version>${drools.version}</version>
-
</dependency>
-
<dependency>
-
<groupId>org.activiti</groupId>
-
<artifactId>activiti-engine</artifactId>
-
<version>${activiti.version}</version>
-
<scope>provided</scope>
-
</dependency>
-
<dependency>
-
<groupId>org.activiti</groupId>
-
<artifactId>activiti-bpmn-layout</artifactId>
-
<version>${activiti.version}</version>
-
<scope>provided</scope>
-
</dependency>
-
<dependency>
-
<groupId>org.activiti</groupId>
-
<artifactId>activiti-spring</artifactId>
-
<version>${activiti.version}</version>
-
<scope>provided</scope>
-
</dependency>
-
<dependency>
-
<groupId>org.postgresql</groupId>
-
<artifactId>postgresql</artifactId>
-
<version>9.4-1201-jdbc41</version>
-
</dependency>
-
</dependencies>
drools貌似不能用6.x版本的
spring配置文件:
[html] view plain copy
- <?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="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
- <property name="driverClass" value="org.postgresql.Driver" />
- <property name="url" value="jdbc:postgresql://127.0.0.1/activiti17" />
- <property name="username" value="admin" />
- <property name="password" value="root" />
- </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="customPostDeployers">
- <list>
- <bean class="org.activiti.engine.impl.rules.RulesDeployer" />
- </list>
- </property>
- <!--
- <property name="deploymentResources" value="classpath*:/bpmn/*.bpmn" />
- -->
- </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" />
- </beans>
-
<?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="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
-
<property name="driverClass" value="org.postgresql.Driver" />
-
<property name="url" value="jdbc:postgresql://127.0.0.1/activiti17" />
-
<property name="username" value="admin" />
-
<property name="password" value="root" />
-
</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="customPostDeployers">
-
<list>
-
<bean class="org.activiti.engine.impl.rules.RulesDeployer" />
-
</list>
-
</property>
-
<!--
-
<property name="deploymentResources" value="classpath*:/bpmn/*.bpmn" />
-
-->
-
</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" />
-
</beans>
ppleave.bpmn
[html] view plain copy
- <?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="leave" name="请假审批" isExecutable="true">
- <startEvent id="startevent1" name="Start"></startEvent>
- <endEvent id="endevent1" name="End"></endEvent>
- <userTask id="usertask1" name="部门经理审批"></userTask>
- <businessRuleTask id="businessruletask1" name="天数判断" activiti:ruleVariablesInput="${leave}" activiti:rules="leave1,leave2" activiti:resultVariable="reason"></businessRuleTask>
- <serviceTask id="servicetask1" name="获取变量" activiti:class="com.lala.service.DroolsService"></serviceTask>
- <userTask id="usertask2" name="HR审批"></userTask>
- <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
- <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="businessruletask1"></sequenceFlow>
- <sequenceFlow id="flow3" sourceRef="businessruletask1" targetRef="servicetask1"></sequenceFlow>
- <userTask id="usertask3" name="总经理审批"></userTask>
- <sequenceFlow id="flow4" sourceRef="servicetask1" targetRef="usertask3">
- <conditionExpression xsi:type="tFormalExpression"><![CDATA[${reason[0].total >= 10}]]></conditionExpression>
- </sequenceFlow>
- <sequenceFlow id="flow5" sourceRef="servicetask1" targetRef="usertask2">
- <conditionExpression xsi:type="tFormalExpression"><![CDATA[${reason[0].total < 10}]]></conditionExpression>
- </sequenceFlow>
- <sequenceFlow id="flow6" sourceRef="usertask3" targetRef="usertask2"></sequenceFlow>
- <sequenceFlow id="flow7" sourceRef="usertask2" targetRef="endevent1"></sequenceFlow>
- </process>
- </definitions>
-
<?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="leave" name="请假审批" isExecutable="true">
-
<startEvent id="startevent1" name="Start"></startEvent>
-
<endEvent id="endevent1" name="End"></endEvent>
-
<userTask id="usertask1" name="部门经理审批"></userTask>
-
<businessRuleTask id="businessruletask1" name="天数判断" activiti:ruleVariablesInput="${leave}" activiti:rules="leave1,leave2" activiti:resultVariable="reason"></businessRuleTask>
-
<serviceTask id="servicetask1" name="获取变量" activiti:class="com.lala.service.DroolsService"></serviceTask>
-
<userTask id="usertask2" name="HR审批"></userTask>
-
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
-
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="businessruletask1"></sequenceFlow>
-
<sequenceFlow id="flow3" sourceRef="businessruletask1" targetRef="servicetask1"></sequenceFlow>
-
<userTask id="usertask3" name="总经理审批"></userTask>
-
<sequenceFlow id="flow4" sourceRef="servicetask1" targetRef="usertask3">
-
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${reason[0].total >= 10}]]></conditionExpression>
-
</sequenceFlow>
-
<sequenceFlow id="flow5" sourceRef="servicetask1" targetRef="usertask2">
-
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${reason[0].total < 10}]]></conditionExpression>
-
</sequenceFlow>
-
<sequenceFlow id="flow6" sourceRef="usertask3" targetRef="usertask2"></sequenceFlow>
-
<sequenceFlow id="flow7" sourceRef="usertask2" targetRef="endevent1"></sequenceFlow>
-
</process>
-
</definitions>
流程图如下:
drools规则文件:product.drl
[plain] view plain copy
- package com.product;
- import com.lala.bean.Leave;
- rule "leave1"
- when
- u : Leave(day < 3);
- then
- u.setTotal(u.getDay() + 2);
- end
- rule "leave2"
- when
- u : Leave(day >= 3);
- then
- u.setTotal(u.getDay() + 5);
- end
-
package com.product;
-
import com.lala.bean.Leave;
-
rule "leave1"
-
when
-
u : Leave(day < 3);
-
then
-
u.setTotal(u.getDay() + 2);
-
end
-
rule "leave2"
-
when
-
u : Leave(day >= 3);
-
then
-
u.setTotal(u.getDay() + 5);
-
end
Fact对象:
[java] view plain copy
- package com.lala.bean;
- import java.io.Serializable;
- public class Leave implements Serializable
- {
- private static final long serialVersionUID = 1L;
- private String name;
- private Integer day; //当前请假天数
- private Integer total = 0; //总共请假天数
- public Leave(String name, Integer day)
- {
- this.name = name;
- this.day = day;
- }
- public Integer getDay()
- {
- return day;
- }
- public void setDay(Integer day)
- {
- this.day = day;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public Integer getTotal() {
- return total;
- }
- public void setTotal(Integer total) {
- this.total = total;
- }
- public String toString()
- {
- return "[name="+name+",day="+day+",total="+total+"]";
- }
- }
-
package com.lala.bean;
-
import java.io.Serializable;
-
public class Leave implements Serializable
-
{
-
private static final long serialVersionUID = 1L;
-
private String name;
-
private Integer day; //当前请假天数
-
private Integer total = 0; //总共请假天数
-
public Leave(String name, Integer day)
-
{
-
this.name = name;
-
this.day = day;
-
}
-
public Integer getDay()
-
{
-
return day;
-
}
-
public void setDay(Integer day)
-
{
-
this.day = day;
-
}
-
public String getName() {
-
return name;
-
}
-
public void setName(String name) {
-
this.name = name;
-
}
-
public Integer getTotal() {
-
return total;
-
}
-
public void setTotal(Integer total) {
-
this.total = total;
-
}
-
public String toString()
-
{
-
return "[name="+name+",day="+day+",total="+total+"]";
-
}
-
}
[java] view plain copy
- package com.lala.service;
- import org.activiti.engine.delegate.DelegateExecution;
- import org.activiti.engine.delegate.JavaDelegate;
- public class DroolsService implements JavaDelegate
- {
- public void execute(DelegateExecution execution) throws Exception
- {
- System.out.println("++++++++++++++++++++++++++++++++++++++");
- System.out.println(execution.getVariable("reason"));
- System.out.println("++++++++++++++++++++++++++++++++++++++");
- }
- }
-
package com.lala.service;
-
import org.activiti.engine.delegate.DelegateExecution;
-
import org.activiti.engine.delegate.JavaDelegate;
-
public class DroolsService implements JavaDelegate
-
{
-
public void execute(DelegateExecution execution) throws Exception
-
{
-
System.out.println("++++++++++++++++++++++++++++++++++++++");
-
System.out.println(execution.getVariable("reason"));
-
System.out.println("++++++++++++++++++++++++++++++++++++++");
-
}
-
}
测试:
[java] view plain copy
- package com.lala.spring;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import org.activiti.engine.RepositoryService;
- import org.activiti.engine.RuntimeService;
- import org.activiti.engine.TaskService;
- import org.activiti.engine.repository.DeploymentBuilder;
- import org.activiti.engine.runtime.ProcessInstance;
- import org.activiti.engine.task.Task;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import com.lala.bean.Leave;
- public class Main
- {
- static void run(ApplicationContext context) throws Exception
- {
- RepositoryService repositoryService = (RepositoryService)context.getBean("repositoryService");
- /**
- * 注意这里:必须要把drl文件一起deploy
- */
- DeploymentBuilder deploy = repositoryService.createDeployment();
- deploy.addClasspathResource("rule/product.drl");
- deploy.addClasspathResource("bpmn/ppleave.bpmn");
- deploy.deploy();
- RuntimeService runtimeService = (RuntimeService)context.getBean("runtimeService");
- ProcessInstance pi = runtimeService.startProcessInstanceByKey("leave");
- TaskService taskService = (TaskService)context.getBean("taskService");
- Map<String, Object> vars = new HashMap<String, Object>();
- vars.put("leave", new Leave("白展堂", 12));
- /**
- * 当前任务
- */
- List<Task> tasks = taskService.createTaskQuery().processInstanceId(pi.getId()).list();
- for(Task task : tasks)
- {
- System.out.println(task.getId() + " , " + task.getName());
- taskService.complete(task.getId(), vars);
- }
- /**
- * 下一步任务
- */
- tasks = taskService.createTaskQuery().processInstanceId(pi.getId()).list();
- for(Task task : tasks)
- {
- System.out.println(task.getId() + " , " + task.getName());
- }
- }
- public static void main( String[] args )throws Exception
- {
- ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
- run(context);
- context.close();
- }
- }
-
package com.lala.spring;
-
import java.util.HashMap;
-
import java.util.List;
-
import java.util.Map;
-
import org.activiti.engine.RepositoryService;
-
import org.activiti.engine.RuntimeService;
-
import org.activiti.engine.TaskService;
-
import org.activiti.engine.repository.DeploymentBuilder;
-
import org.activiti.engine.runtime.ProcessInstance;
-
import org.activiti.engine.task.Task;
-
import org.springframework.context.ApplicationContext;
-
import org.springframework.context.support.ClassPathXmlApplicationContext;
-
import com.lala.bean.Leave;
-
public class Main
-
{
-
static void run(ApplicationContext context) throws Exception
-
{
-
RepositoryService repositoryService = (RepositoryService)context.getBean("repositoryService");
-
/**
-
* 注意这里:必须要把drl文件一起deploy
-
*/
-
DeploymentBuilder deploy = repositoryService.createDeployment();
-
deploy.addClasspathResource("rule/product.drl");
-
deploy.addClasspathResource("bpmn/ppleave.bpmn");
-
deploy.deploy();
-
RuntimeService runtimeService = (RuntimeService)context.getBean("runtimeService");
-
ProcessInstance pi = runtimeService.startProcessInstanceByKey("leave");
-
TaskService taskService = (TaskService)context.getBean("taskService");
-
Map<String, Object> vars = new HashMap<String, Object>();
-
vars.put("leave", new Leave("白展堂", 12));
-
/**
-
* 当前任务
-
*/
-
List<Task> tasks = taskService.createTaskQuery().processInstanceId(pi.getId()).list();
-
for(Task task : tasks)
-
{
-
System.out.println(task.getId() + " , " + task.getName());
-
taskService.complete(task.getId(), vars);
-
}
-
/**
-
* 下一步任务
-
*/
-
tasks = taskService.createTaskQuery().processInstanceId(pi.getId()).list();
-
for(Task task : tasks)
-
{
-
System.out.println(task.getId() + " , " + task.getName());
-
}
-
}
-
public static void main( String[] args )throws Exception
-
{
-
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
-
run(context);
-
context.close();
-
}
-
}
运行结果:
请假天数小于3天时,输出结果:
5009 , 部门经理审批
++++++++++++++++++++++++++++++++++++++
[[name=白展堂,day=2,total=4]]
++++++++++++++++++++++++++++++++++++++
5019 , HR审批
否则,输出结果:
7509 , 部门经理审批
++++++++++++++++++++++++++++++++++++++
[[name=白展堂,day=22,total=27]]
++++++++++++++++++++++++++++++++++++++
7519 , 总经理审批