這是原做者的博客地址java
http://wiselyman.iteye.com/blog/2285223 mysql
代碼格式混亂,我修正了一下.項目源碼在:git
http://git.oschina.net/fengyexjtu/spring-boot-activitiweb
<?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>
流程解釋:spring
流程最左邊是開始,最右邊結束,左二小人圖標爲用戶任務(User Task)須要人蔘與操做,咱們選擇有權限的操做的人來源於Spring的bean方法activiti:candidateUsers=」${joinService.findUsers(execution)}」,左三齒輪圖標爲服務任務(Service Task),是自動執行的任務,自動調用Spring的bean方法。sql
<?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>
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
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; } }
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; public Comp(String compName) {this.compName = compName;} public Comp() { } public Long getCompId() { return compId; } public void setCompId(Long compId) { this.compId = compId; } public String getCompName() { return compName; } public void setCompName(String compName) { this.compName = compName; } public List<Person> getPeople() { return people; } public void setPeople(List<Person> people) { this.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> { }
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; //開始流程,傳入申請者的id以及公司的id public void startProcess(Long personId, Long compId) { Map<String, Object> variables = new HashMap<String, Object>(); variables.put("personId", personId); variables.put("compId", compId); runtimeService.startProcessInstanceByKey("joinProcess", variables); } //得到某我的的任務別表 public List<Task> getTasks(String assignee) { return taskService.createTaskQuery().taskCandidateUser(assignee).list(); } //完成任務 public void completeTasks(Boolean joinApproved, String taskId) { Map<String, Object> taskVariables = new HashMap<String, Object>(); taskVariables.put("joinApproved", joinApproved); taskService.complete(taskId, taskVariables); } }
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; //開啓流程實例 @RequestMapping(value = "/process/{personId}/{compId}", method = RequestMethod.GET) public void startProcessInstance(@PathVariable Long personId, @PathVariable Long compId) { myService.startProcess(personId, compId); } //獲取當前人的任務 @RequestMapping(value = "/tasks", method = RequestMethod.GET) public List<TaskRepresentation> getTasks(@RequestParam String assignee) { List<Task> tasks = myService.getTasks(assignee); List<TaskRepresentation> dtos = new ArrayList<TaskRepresentation>(); for (Task task : tasks) { dtos.add(new TaskRepresentation(task.getId(), task.getName())); } return dtos; } //完成任務 @RequestMapping(value = "/complete/{joinApproved}/{taskId}", method = RequestMethod.GET) public String complete(@PathVariable Boolean joinApproved, @PathVariable String taskId) { myService.completeTasks(joinApproved, taskId); return "ok"; } //Task的dto static class TaskRepresentation { private String id; private String name; public TaskRepresentation(String id, String name) { this.id = id; this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.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所用的數據庫和咱們的業務數據庫,並自動發佈咱們的流程。
express
此時咱們要加入的公司id爲1,申請加入的人的id爲2,使用PostMan訪問http://localhost:8080/process/2/1 此時數據庫發生以下變化apache
此時用戶admin和wtr具有審批申請的權利,此時咱們訪問http://localhost:8080/tasks?assignee=admin 查看admin用戶的任務,返回結果爲:app
咱們如今經過訪問http://localhost:8080/complete/true/10 完成任務,true爲贊成(能夠選擇false),10爲task的id,任務完成後會自動調用Service Task,此時wyf這條記錄的comp_compId爲更新爲當前公司的id。