springboot整合activity自動(dòng)部署及部署文件命名流程
springboot整合activity自動(dòng)部署及部署文件命名流程
問題描述
springboot整合activity,部署流程定義的時(shí)候在數(shù)據(jù)庫總是會(huì)自動(dòng)的部署一次。
問題分析
查看啟動(dòng)日志,出現(xiàn)如下一段話:
ProcessEngine default created
Process deployed: {id: myProcess_1:1:db6bacd7-edbd-11ea-b883-1860249fb796, key: myProcess_1, name: null }
在項(xiàng)目啟動(dòng)的時(shí)候流程自動(dòng)部署
查閱相關(guān)資料總結(jié)
1.項(xiàng)目中包含流程定義的xml或者bpmn文件,項(xiàng)目在第一次啟動(dòng)的時(shí)候會(huì)自動(dòng)部署。
解決方案
在配置文件中增加如下配置:
#項(xiàng)目隨著spring啟動(dòng)自動(dòng)部署 spring.activiti.check-process-definitions=false
刪除數(shù)據(jù)庫中部署的流程定義,再次啟動(dòng)項(xiàng)目,沒有出現(xiàn)自動(dòng)部署的現(xiàn)象。
Spring Boot集成Activiti工作流
項(xiàng)目搭建
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
核心代碼
實(shí)體類
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;
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> {
}
Activiti服務(wù)
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 {
//注入為我們自動(dòng)配置好的服務(wù)
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
//開始流程,傳入申請(qǐng)者的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);
}
//獲得某個(gè)人的任務(wù)別表
public List<Task> getTasks(String assignee) {
return taskService.createTaskQuery().taskCandidateUser(assignee).list();
}
//完成任務(wù)
public void completeTasks(Boolean joinApproved, String taskId) {
Map<String, Object> taskVariables = new HashMap<String, Object>();
taskVariables.put("joinApproved", joinApproved);
taskService.complete(taskId, taskVariables);
}
}
Service Task服務(wù)
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("加入組織失敗");
}
}
//獲取符合條件的審批人,演示這里寫死,使用應(yīng)用使用實(shí)際代碼
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;
//開啟流程實(shí)例
@RequestMapping(value = "/process/{personId}/{compId}", method = RequestMethod.GET)
public void startProcessInstance(@PathVariable Long personId, @PathVariable Long compId) {
myService.startProcess(personId, compId);
}
//獲取當(dāng)前人的任務(wù)
@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;
}
//完成任務(wù)
@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);
}
//初始化模擬數(shù)據(jù)
@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);
}
}
};
}
}
看看演示吧
啟動(dòng)程序會(huì)自動(dòng)初始化Activiti所用的數(shù)據(jù)庫和我們的業(yè)務(wù)數(shù)據(jù)庫,并自動(dòng)發(fā)布我們的流程。




此時(shí)我們要加入的公司id為1,申請(qǐng)加入的人的id為2,使用PostMan訪問http://localhost:8080/process/2/1 此時(shí)數(shù)據(jù)庫發(fā)生如下變化


此時(shí)用戶admin和wtr具備審批申請(qǐng)的權(quán)利,此時(shí)我們?cè)L問http://localhost:8080/tasks?assignee=admin 查看admin用戶的任務(wù),返回結(jié)果為:
[
{
"id":"10",
"name":"Approval Task"
}
]
我們現(xiàn)在通過訪問http://localhost:8080/complete/true/10 完成任務(wù),true為同意(可以選擇false),10為task的id,任務(wù)完成后會(huì)自動(dòng)調(diào)用Service Task,此時(shí)wyf這條記錄的comp_compId為更新為當(dāng)前公司的id。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
java實(shí)現(xiàn)兩臺(tái)服務(wù)器間文件復(fù)制的方法
這篇文章主要介紹了java實(shí)現(xiàn)兩臺(tái)服務(wù)器間文件復(fù)制的方法,是對(duì)單臺(tái)服務(wù)器上文件復(fù)制功能的升級(jí)與改進(jìn),具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-01-01
java中的Serializable、transient關(guān)鍵字詳解
這篇文章主要介紹了java中的Serializable、transient關(guān)鍵字詳解,序列化只會(huì)保存屬性值,不會(huì)保存方法,通過反序列化可以把序列化后的內(nèi)容恢復(fù)成對(duì)象,需要的朋友可以參考下2023-09-09
解決feign微服務(wù)間的文件上傳報(bào)錯(cuò)問題
這篇文章主要介紹了解決feign微服務(wù)間的文件上傳報(bào)錯(cuò)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
關(guān)于Scanner對(duì)象的輸入結(jié)束標(biāo)記問題
這篇文章主要介紹了關(guān)于Scanner對(duì)象的輸入結(jié)束標(biāo)記問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05
SpringBoot Actuator未授權(quán)訪問漏洞解決方案
工作的時(shí)候遇到過提示Spring Boot后端存在Actuator未授權(quán)訪問漏洞,網(wǎng)上有很多詳細(xì)的解釋文章,在這里做一個(gè)簡(jiǎn)單的總結(jié)、介紹和分享,需要的朋友可以參考下2023-09-09
通過Spring AOP實(shí)現(xiàn)異常捕捉機(jī)制
在開發(fā)過程中,異常處理是一個(gè)不可忽視的重要環(huán)節(jié),合理、優(yōu)雅地處理異常不僅能提高代碼的魯棒性,還能提升系統(tǒng)的用戶體驗(yàn),本文將介紹如何通過Spring AOP實(shí)現(xiàn)一個(gè)高效的異常捕捉機(jī)制,使得異常處理變得更加優(yōu)雅和統(tǒng)一,需要的朋友可以參考下2024-08-08

