<?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 ><span >public</span> <span >Comp</span><span >(String compName)</span>
</span>{<span >this</span>.compName = compName;}

<span ><span >public</span> <span >Comp</span><span >()</span> </span>{

}

<span ><span >public</span> Long <span >getCompId</span><span >()</span> </span>{
<span >return</span> compId;
}

<span ><span >public</span> <span >void</span> <span >setCompId</span><span >(Long compId)</span> </span>{
<span >this</span>.compId = compId;
}

<span ><span >public</span> String <span >getCompName</span><span >()</span> </span>{
<span >return</span> compName;
}

<span ><span >public</span> <span >void</span> <span >setCompName</span><span >(String compName)</span> </span>{
<span >this</span>.compName = compName;
}

<span ><span >public</span> List<Person> <span >getPeople</span><span >()</span> </span>{
<span >return</span> people;
}

<span ><span >public</span> <span >void</span> <span >setPeople</span><span >(List<Person> people)</span> </span>{
<span >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 >//开始流程,传入申请者的id以及公司的id</span>
public <span >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 >new</span> HashMap<<span class="hljs-built_in">String</span>, <span class="hljs-built_in">Object</span>>();
variables.put(<span >"personId"</span>, personId);
variables.put(<span >"compId"</span>, compId);
runtimeService.startProcessInstanceByKey(<span >"joinProcess"</span>, variables);
}

<span >//获得某个人的任务别表</span>
public List<Task> getTasks(<span class="hljs-built_in">String</span> assignee) {
<span >return</span> taskService.createTaskQuery().taskCandidateUser(assignee).list();
}

<span >//完成任务</span>
public <span >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 >new</span> HashMap<<span class="hljs-built_in">String</span>, <span class="hljs-built_in">Object</span>>();
taskVariables.put(<span >"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 >//开启流程实例</span>
<span >@RequestMapping</span>(value = <span >"/process/{personId}/{compId}"</span>, method = RequestMethod.GET)
<span ><span >public</span> <span >void</span> <span >startProcessInstance</span><span >(@PathVariable Long personId, @PathVariable Long compId)</span> </span>{
myService.startProcess(personId, compId);
}

<span >//获取当前人的任务</span>
<span >@RequestMapping</span>(value = <span >"/tasks"</span>, method = RequestMethod.GET)
<span ><span >public</span> List<TaskRepresentation> <span >getTasks</span><span >(@RequestParam String assignee)</span> </span>{
List<Task> tasks = myService.getTasks(assignee);
List<TaskRepresentation> dtos = <span >new</span> ArrayList<TaskRepresentation>();
<span >for</span> (Task task : tasks) {
dtos.add(<span >new</span> TaskRepresentation(task.getId(), task.getName()));
}
<span >return</span> dtos;
}

<span >//完成任务</span>
<span >@RequestMapping</span>(value = <span >"/complete/{joinApproved}/{taskId}"</span>, method = RequestMethod.GET)
<span ><span >public</span> String <span >complete</span><span >(@PathVariable Boolean joinApproved, @PathVariable String taskId)</span> </span>{
myService.completeTasks(joinApproved, taskId);
<span >return</span> <span >"ok"</span>;
}

<span >//Task的dto</span>
<span >static</span> <span ><span >class</span> <span >TaskRepresentation</span>

</span>{
<span >private</span> String id;
<span >private</span> String name;

<span ><span >public</span> <span >TaskRepresentation</span><span >(String id, String name)</span> </span>{
<span >this</span>.id = id;
<span >this</span>.name = name;
}

<span ><span >public</span> String <span >getId</span><span >()</span> </span>{
<span >return</span> id;
}

<span ><span >public</span> <span >void</span> <span >setId</span><span >(String id)</span> </span>{
<span >this</span>.id = id;
}

<span ><span >public</span> String <span >getName</span><span >()</span> </span>{
<span >return</span> name;
}

<span ><span >public</span> <span >void</span> <span >setName</span><span >(String name)</span> </span>{
<span >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所用的数据库和我们的业务数据库,并自动发布我们的流程。

spring boot与activiti集成实战 转_BPM

spring boot与activiti集成实战 转_Activiti_02

spring boot与activiti集成实战 转_Activiti_03

spring boot与activiti集成实战 转_java经验集锦_04

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

spring boot与activiti集成实战 转_SpringBoot_05

spring boot与activiti集成实战 转_通用实践_06

此时用户admin和wtr具备审批申请的权利,此时我们访问http://localhost:8080/tasks?assignee=admin 查看admin用户的任务,返回结果为:

  1. [
  2. {
  3. "id":"10",
  4. "name":"Approval Task"
  5. }
  6. ]

 

我们现在通过访问http://localhost:8080/complete/true/10 完成任务,true为同意(可以选择false),10为task的id,任务完成后会自动调用Service Task,此时wyf这条记录的comp_compId为更新为当前公司的id。

spring boot与activiti集成实战 转_BPM_07


                                    </div>