Spring + Activiti + Drools整合的请假例子

标签: spring activiti drools | 发表时间:2015-08-20 17:53 | 作者:mn960mn
出处:http://blog.csdn.net
业务规则是这样的(没有实际意义,只是做demo演示)


如果请假总天数大于等于3天,则需要总经理审批,否则不需要总经理审批


如果当次请假小于3天,则请假总天数等于当次请假天数+2
否则,请假总天数等于当次请假次数+5


其中,总的请假次数的计算逻辑交给drools处理


新建maven项目,目录结构如下:


一:加入maven依赖:

<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>

drools貌似不能用6.x版本的


spring配置文件:

<?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

<?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

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对象:

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.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.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 , 总经理审批

作者:mn960mn 发表于2015/8/20 9:53:28 原文链接
阅读:73 评论:0 查看评论

相关 [spring activiti drools] 推荐:

Spring + Activiti + Drools整合的请假例子

- - CSDN博客推荐文章
业务规则是这样的(没有实际意义,只是做demo演示). 如果请假总天数大于等于3天,则需要总经理审批,否则不需要总经理审批. 如果当次请假小于3天,则请假总天数等于当次请假天数+2. 否则,请假总天数等于当次请假次数+5. 其中,总的请假次数的计算逻辑交给drools处理. 新建maven项目,目录结构如下:.

Activiti入门篇之二 Spring 与Activiti的入门整合

- - 行业应用 - ITeye博客
Activiti相对Jbpm来说,与Spring整合更加完美,具体可见本文的详细介绍. 1.     Maven的环境任务,请参考第一篇 (Activiti入门篇—Maven的环境准备). 2.     Activiti的Eclipse插件安装.               插件更新地址:http://activiti.org/designer/update/.

Activiti 5.3:配置与Spring整合

- - CSDN博客推荐文章
Activiti 5.3:配置与Spring整合. Activiti 5.3与Spring整合也比较简单,其基本思想就是,通过Spring的IOC容器来管理Activiti的流程引擎实例以及相关服务,可见,主要是基于Activiti在与Spring整合上努力上,做好配置即可. 这里基于前面的的例子来进行,可以参考: Activiti 5.3:流程活动自动与手工触发执行,简单的流程,如图所示:.

drools引擎使用决策表

- - 行业应用 - ITeye博客
前提准备:java 虚拟机 .                  Drools核心库.                  Junit4.0以上版本.                  规则Excel模板表(将下面的图片的内容新建到Excel中). 典型的用法就是根据excel创建KnowledgeBase,然后将它丢给session执行,执行的参数和结果都在params里面.

Activiti用户指南之Activiti的API

- - ITeye博客
 一、流程引擎的API和服务(services).      引擎的API是影响Activiti最常见的一种方法. 我们一开始最关注的中心是ProcessEngine,像之前描述的那样,流程引擎可以被多种方式创建. 从这个流程引擎里面,你能获得各个包含workflow/BPM方法的服务. 流程引擎和这些获得的服务是线程安全的.

Activiti学习笔记

- - 企业架构 - ITeye博客
第一个Activiti的HelloWorld. 获取核心ProcessEngine对象 2. 根据需求,获取对应的服务实例 3. 使用服务方法,做事情 * * @author Administrator * */ public class HelloWorld {. // 加载核心API ProcessEngine.

Activiti工作流demo

- - CSDN博客综合推荐文章
继上篇《 Activiti工作流的环境配置》.        前几篇对Activiti工作流进行了介绍,并讲解了其环境配置. 本篇将会用一个demo来展示Activiti工作流具体的体现,直接上干货.        以HelloWorld程序为例.       首先说一下业务流程,员工张三提交了一个申请,然后由部门经理李四审核,审核通过后再由总经理王五审核,通过则张三申请成功.

Activiti - 设置会签

- - 企业架构 - ITeye博客
前些天在群里聊工作流和Activiti,群里有人分享了自己的工作流引擎开源项目,大伙纷纷问这问那(比如为什么突然自己搞个process engine、有没有eclipse plugin、能不能绘制流程图等等). 现实生活中的工作流程,我们也经常碰到需要会签的情况,支持会签是很必要的. 正好有两个人问道:支持会签吗.

activiti工作流使用

- - 行业应用 - ITeye博客
activiti 开发流程. JBPM 与 Activiti. jBPM项目于2002年3月由Tom Baeyens发起,2003年12月发布1.0版本. 2004年10月18日,发布了2.0版本,并在同一天加入了JBoss. 2011 年 jBPM的创建者Tom Baeyens离开JBoss了, 他的离开产生了两个结果:.

ACTIVITI 学习笔记 - 监听

- - 企业架构 - ITeye博客
ACTIVITI 学习笔记 - 监听. 所有分发的事件都是org.activiti.engine.delegate.event.ActivitiEvent的子类. 监听器监听的流程引擎已经创建完毕,并准备好接受API调用. 监听器监听的流程引擎已经关闭,不再接受API调用. 创建了一个新实体,初始化也完成了.