spring boot与activiti集成实战 转
这是原作者的博客地址
http://wiselyman.iteye.com/blog/2285223
代码格式混乱,我修正了一下.项目源码在:
http://git.oschina.net/fengyexjtu/spring-boot-activiti
流程设计
<?xml version='1.0' encoding='UTF-8'?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:activiti="http://activiti.org/bpmn"
typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath"
targetNamespace="http://www.activiti.org/test">
<process id="joinProcess" name="Join process" isExecutable="true">
<startEvent id="startevent1" name="Start">
<extensionElements>
<activiti:formProperty id="personId" name="person id" type="long"
required="true"></activiti:formProperty>
<activiti:formProperty id="compId" name="company Id" type="long"
required="true"></activiti:formProperty>
</extensionElements>
</startEvent>
<endEvent id="endevent1" name="End"></endEvent>
<userTask id="ApprovalTask" name="Approval Task"
activiti:candidateUsers="${joinService.findUsers(execution)}" isForCompensation="true">
<extensionElements>
<activiti:formProperty id="joinApproved" name="Join Approved" type="enum">
<activiti:value id="true" name="Approve"></activiti:value>
<activiti:value id="false" name="Reject"></activiti:value>
</activiti:formProperty>
</extensionElements>
</userTask>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="ApprovalTask"></sequenceFlow>
<serviceTask id="AutoTask" name="Auto Task"
activiti:expression="${joinService.joinGroup(execution)}"></serviceTask>
<sequenceFlow id="flow2" sourceRef="ApprovalTask" targetRef="AutoTask"></sequenceFlow>
<sequenceFlow id="flow3" sourceRef="AutoTask" targetRef="endevent1"></sequenceFlow>
</process>
</definitions>
流程解释:
流程最左边是开始,最右边结束,左二小人图标为用户任务(User Task)需要人参与操作,我们选择有权限的操作的人来源于Spring的bean方法activiti:candidateUsers=”${joinService.findUsers(execution)}”,左三齿轮图标为服务任务(Service Task),是自动执行的任务,自动调用Spring的bean方法。
项目搭建
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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.fengye.example</groupId>
<artifactId>spring-boot-activiti</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-boot-activiti</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.0.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<activiti.version>5.21.0</activiti.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-basic</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties配置
spring.jpa.hibernate.ddl-auto=update
spring.jpa.database=MYSQL
spring.datasource.url=jdbc:mysql://127.0.0.1:3307/spring-boot-activiti?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
核心代码
实体类
Person.java
package com.fengye.example.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
/**
- Created by jery on 2016/11/23.
*/
@Entity
public class Person {
@Id
@GeneratedValue
private Long personId;
private String personName;
@ManyToOne(targetEntity = Comp.class)
private Comp comp;
public Person() {
}
public Person(String personName) {
this.personName = personName;
}
public Long getPersonId() {
return personId;
}
public void setPersonId(Long personId) {
this.personId = personId;
}
public String getPersonName() {
return personName;
}
public void setPersonName(String personName) {
this.personName = personName;
}
public Comp getComp() {
return comp;
}
public void setComp(Comp comp) {
this.comp = comp;
}
}
Comp.java
package com.fengye.example.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import java.util.List;
/**
- Created by jery on 2016/11/23.
*/
@Entity
public class Comp {
@Id
@GeneratedValue
private Long compId;
private String compName;
@OneToMany(mappedBy = "comp", targetEntity = Person.class)
private List<Person> people;
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Comp</span><span class="hljs-params">(String compName)</span>
</span>{<span class="hljs-keyword">this</span>.compName = compName;}
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Comp</span><span class="hljs-params">()</span> </span>{
}
<span class="hljs-function"><span class="hljs-keyword">public</span> Long <span class="hljs-title">getCompId</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">return</span> compId;
}
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setCompId</span><span class="hljs-params">(Long compId)</span> </span>{
<span class="hljs-keyword">this</span>.compId = compId;
}
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getCompName</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">return</span> compName;
}
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setCompName</span><span class="hljs-params">(String compName)</span> </span>{
<span class="hljs-keyword">this</span>.compName = compName;
}
<span class="hljs-function"><span class="hljs-keyword">public</span> List<Person> <span class="hljs-title">getPeople</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">return</span> people;
}
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setPeople</span><span class="hljs-params">(List<Person> people)</span> </span>{
<span class="hljs-keyword">this</span>.people = people;
}
}
DAO
package com.fengye.example.dao;
import com.fengye.example.model.Person;
import org.springframework.data.jpa.repository.JpaRepository;
/**
- Created by jery on 2016/11/23.
*/
public interface PersonRepository extends JpaRepository<Person, Long> {
public Person findByPersonName(String personName);
}
package com.fengye.example.dao;
import com.fengye.example.model.Comp;
import org.springframework.data.jpa.repository.JpaRepository;
public interface CompRepository extends JpaRepository<Comp, Long> {
}
Activiti服务
package com.fengye.example.service;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
- Created by jery on 2016/11/23.
*/
@Service
@Transactional
public class ActivitiService {
//注入为我们自动配置好的服务
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
<span class="hljs-comment">//开始流程,传入申请者的id以及公司的id</span>
public <span class="hljs-keyword">void</span> startProcess(Long personId, Long compId) {
<span class="hljs-built_in">Map</span><<span class="hljs-built_in">String</span>, <span class="hljs-built_in">Object</span>> variables = <span class="hljs-keyword">new</span> HashMap<<span class="hljs-built_in">String</span>, <span class="hljs-built_in">Object</span>>();
variables.put(<span class="hljs-string">"personId"</span>, personId);
variables.put(<span class="hljs-string">"compId"</span>, compId);
runtimeService.startProcessInstanceByKey(<span class="hljs-string">"joinProcess"</span>, variables);
}
<span class="hljs-comment">//获得某个人的任务别表</span>
public List<Task> getTasks(<span class="hljs-built_in">String</span> assignee) {
<span class="hljs-keyword">return</span> taskService.createTaskQuery().taskCandidateUser(assignee).list();
}
<span class="hljs-comment">//完成任务</span>
public <span class="hljs-keyword">void</span> completeTasks(<span class="hljs-built_in">Boolean</span> joinApproved, <span class="hljs-built_in">String</span> taskId) {
<span class="hljs-built_in">Map</span><<span class="hljs-built_in">String</span>, <span class="hljs-built_in">Object</span>> taskVariables = <span class="hljs-keyword">new</span> HashMap<<span class="hljs-built_in">String</span>, <span class="hljs-built_in">Object</span>>();
taskVariables.put(<span class="hljs-string">"joinApproved"</span>, joinApproved);
taskService.complete(taskId, taskVariables);
}
}
Service Task服务
package com.fengye.example.service;
import com.fengye.example.dao.CompRepository;
import com.fengye.example.dao.PersonRepository;
import com.fengye.example.model.Comp;
import com.fengye.example.model.Person;
import org.activiti.engine.delegate.DelegateExecution;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
/**
- Created by jery on 2016/11/23.
*/
@Service
public class JoinService {
@Autowired
PersonRepository personRepository;
@Autowired
private CompRepository compRepository;
//加入公司操作,可从DelegateExecution获取流程中的变量
public void joinGroup(DelegateExecution execution) {
Boolean bool = (Boolean) execution.getVariable("joinApproved");
if (bool) {
Long personId = (Long) execution.getVariable("personId");
Long compId = (Long) execution.getVariable("compId");
Comp comp = compRepository.findOne(compId);
Person person = personRepository.findOne(personId);
person.setComp(comp);
personRepository.save(person);
System.out.println("加入组织成功");
} else {
System.out.println("加入组织失败");
}
}
//获取符合条件的审批人,演示这里写死,使用应用使用实际代码
public List<String> findUsers(DelegateExecution execution) {
return Arrays.asList("admin", "wtr");
}
}
控制器
package com.fengye.example.controller;
/**
- Created by jery on 2016/11/23.
*/
import com.fengye.example.service.ActivitiService;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@RestController
public class MyRestController {
@Autowired
private ActivitiService myService;
<span class="hljs-comment">//开启流程实例</span>
<span class="hljs-meta">@RequestMapping</span>(value = <span class="hljs-string">"/process/{personId}/{compId}"</span>, method = RequestMethod.GET)
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">startProcessInstance</span><span class="hljs-params">(@PathVariable Long personId, @PathVariable Long compId)</span> </span>{
myService.startProcess(personId, compId);
}
<span class="hljs-comment">//获取当前人的任务</span>
<span class="hljs-meta">@RequestMapping</span>(value = <span class="hljs-string">"/tasks"</span>, method = RequestMethod.GET)
<span class="hljs-function"><span class="hljs-keyword">public</span> List<TaskRepresentation> <span class="hljs-title">getTasks</span><span class="hljs-params">(@RequestParam String assignee)</span> </span>{
List<Task> tasks = myService.getTasks(assignee);
List<TaskRepresentation> dtos = <span class="hljs-keyword">new</span> ArrayList<TaskRepresentation>();
<span class="hljs-keyword">for</span> (Task task : tasks) {
dtos.add(<span class="hljs-keyword">new</span> TaskRepresentation(task.getId(), task.getName()));
}
<span class="hljs-keyword">return</span> dtos;
}
<span class="hljs-comment">//完成任务</span>
<span class="hljs-meta">@RequestMapping</span>(value = <span class="hljs-string">"/complete/{joinApproved}/{taskId}"</span>, method = RequestMethod.GET)
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">complete</span><span class="hljs-params">(@PathVariable Boolean joinApproved, @PathVariable String taskId)</span> </span>{
myService.completeTasks(joinApproved, taskId);
<span class="hljs-keyword">return</span> <span class="hljs-string">"ok"</span>;
}
<span class="hljs-comment">//Task的dto</span>
<span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TaskRepresentation</span>
</span>{
<span class="hljs-keyword">private</span> String id;
<span class="hljs-keyword">private</span> String name;
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">TaskRepresentation</span><span class="hljs-params">(String id, String name)</span> </span>{
<span class="hljs-keyword">this</span>.id = id;
<span class="hljs-keyword">this</span>.name = name;
}
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getId</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">return</span> id;
}
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setId</span><span class="hljs-params">(String id)</span> </span>{
<span class="hljs-keyword">this</span>.id = id;
}
<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getName</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">return</span> name;
}
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setName</span><span class="hljs-params">(String name)</span> </span>{
<span class="hljs-keyword">this</span>.name = name;
}
}
}
入口类
import com.fengye.example.dao.CompRepository;
import com.fengye.example.dao.PersonRepository;
import com.fengye.example.model.Comp;
import com.fengye.example.model.Person;
import com.fengye.example.service.ActivitiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.orm.jpa.EntityScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories; /**
* Created by jery on 2016/11/23.
*/
@SpringBootApplication
@ComponentScan("com.fengye.example")
@EnableJpaRepositories("com.fengye.example.dao")
@EntityScan("com.fengye.example.model")
public class ActivitiApplication {
@Autowired
private CompRepository compRepository;
@Autowired
private PersonRepository personRepository; public static void main(String[] args) {
SpringApplication.run(ActivitiApplication.class, args);
} //初始化模拟数据
@Bean
public CommandLineRunner init(final ActivitiService myService) {
return new CommandLineRunner() {
public void run(String... strings) throws Exception {
if (personRepository.findAll().size() == 0) {
personRepository.save(new Person("wtr"));
personRepository.save(new Person("wyf"));
personRepository.save(new Person("admin"));
}
if (compRepository.findAll().size() == 0) {
Comp group = new Comp("great company");
compRepository.save(group);
Person admin = personRepository.findByPersonName("admin");
Person wtr = personRepository.findByPersonName("wtr");
admin.setComp(group); wtr.setComp(group);
personRepository.save(admin); personRepository.save(wtr);
}
}
};
}
}
演示
启动程序会自动初始化Activiti所用的数据库和我们的业务数据库,并自动发布我们的流程。




此时我们要加入的公司id为1,申请加入的人的id为2,使用PostMan访问http://localhost:8080/process/2/1 此时数据库发生如下变化


此时用户admin和wtr具备审批申请的权利,此时我们访问http://localhost:8080/tasks?assignee=admin 查看admin用户的任务,返回结果为:
- [
- {
- "id":"10",
- "name":"Approval Task"
- }
- ]
我们现在通过访问http://localhost:8080/complete/true/10 完成任务,true为同意(可以选择false),10为task的id,任务完成后会自动调用Service Task,此时wyf这条记录的comp_compId为更新为当前公司的id。

spring boot与activiti集成实战 转的更多相关文章
- 图书-技术-SpringBoot:《Spring Boot 企业级应用开发实战》
ylbtech-图书-技术-SpringBoot:<Spring Boot 企业级应用开发实战> Spring Boot 企业级应用开发实战,全书围绕如何整合以 Spring Boot 为 ...
- Spring Boot 如何快速集成 Redis 哨兵?
上一篇:Spring Boot 如何快速集成 Redis? 前面的分享栈长介绍了如何使用 Spring Boot 快速集成 Redis,上一篇是单机版,也有粉丝留言说有没有 Redis Sentine ...
- spring boot / cloud (三) 集成springfox-swagger2构建在线API文档
spring boot / cloud (三) 集成springfox-swagger2构建在线API文档 前言 不能同步更新API文档会有什么问题? 理想情况下,为所开发的服务编写接口文档,能提高与 ...
- Spring Boot HikariCP 一 ——集成多数据源
其实这里介绍的东西主要是参考的另外一篇文章,数据库读写分离的. 参考文章就把链接贴出来,里面有那位的代码,简单明了https://gitee.com/comven/dynamic-datasource ...
- Spring Boot系列——如何集成Log4j2
上篇<Spring Boot系列--日志配置>介绍了Spring Boot如何进行日志配置,日志系统用的是Spring Boot默认的LogBack. 事实上,除了使用默认的LogBack ...
- 【ELK】4.spring boot 2.X集成ES spring-data-ES 进行CRUD操作 完整版+kibana管理ES的index操作
spring boot 2.X集成ES 进行CRUD操作 完整版 内容包括: ============================================================ ...
- Spring Boot 从入门到实战汇总
之前写过几篇spring boot入门到实战的博文,因为某些原因没能继续. 框架更新迭代很快,之前还是基于1.x,现在2.x都出来很久了.还是希望能从基于该框架项目开发的整体有一个比较系统的梳理,于是 ...
- 15、Spring Boot 2.x 集成 Swagger UI
1.15.Spring Boot 2.x 集成 Swagger UI 完整源码: Spring-Boot-Demos 1.15.1 pom文件添加swagger包 <swagger2.versi ...
- 14、Spring Boot 2.x 集成 Druid 数据源
14.Spring Boot 2.x 集成 Druid 数据源 完整源码: Spring-Boot-Demos
随机推荐
- 怎么去掉select的下拉箭头和输入框input类型为number时的上下箭头
一.去掉select的下拉箭头 方法一:在select外面加一个div,设置select宽度大于div的宽度,并加一个超出隐藏属性overflow:hidden,小三角会隐藏掉: 方法二:给selec ...
- poj 2288 Islands and Bridges——状压dp(哈密尔顿回路)
题目:http://poj.org/problem?id=2288 不知为什么记忆化搜索就是WA得不得了! #include<iostream> #include<cstdio> ...
- web前端学习(二)html学习笔记部分(6)--fileAPI
1.2.18 html5 File API的应用 1.2.18.1 实现可选择列表 通过为列表项增加一个选择框,进而实现列表的多选和对选择文件的删除.同时,在选择.取消选择时实现操作栏的切换. 1. ...
- 【JZOJ3296】【SDOI2013】刺客信条(assassin)
╰( ̄▽ ̄)╭ Description 故事发生在1486 年的意大利,Ezio 原本只是一个文艺复兴时期的贵族,后来因为家族成员受到圣殿骑士的杀害,决心成为一名刺客.最终,凭借着他的努力和出众的天赋 ...
- Serializable 可串行化接口
Serializable 可串行化接口 定义一个User类,实现Serializable接口: package com.monkey1025; import java.io.Serializable; ...
- 洛谷 P1420 最长连号【最长合法子序列/断则归一】
题目描述 输入n个正整数,(1<=n<=10000),要求输出最长的连号的长度.(连号指从小到大连续自然数) 输入输出格式 输入格式: 第一行,一个数n; 第二行,n个正整数,之间用空格隔 ...
- 怎么在 CentOS 6 上配置私有 NPM 仓库?
Sinopia 是一个简单易用的私有 NPM 仓库服务器.在 CentOS 6 上安装时,遇到如下报错(Node 版本 6.9.1) #error This version of node/NAN/v ...
- php的模板原理
下载了开源论坛phpbb的代码,突然对php模板初步了解了一下: php与Html在一起编写真的是很烦人,所以必须要把数据计算以及显示格式分离,这就需要模板来实现了. http://baike.bai ...
- oracle如何穿过防火墙连接数据库
这个问题只会在WIN平台出现,UNIX平台会自动解决. 解决方法: 在服务器端的SQLNET.ORA应类似 SQLNET.AUTHENTICATION_SERVICES= (NTS) NAMES.DI ...
- Kubernetes1.3新特性:支持GPU
(一) 背景资料 GPU就是图形处理器,是Graphics Processing Unit的缩写.电脑显示器上显示的图像,在显示在显示器上之前,要经过一些列处理,这个过程有个专有的名词叫" ...
