文档章节

spring boot与activiti集成实战

fengyexjtu
 fengyexjtu
发布于 2016/11/23 23:47
字数 1590
阅读 9512
收藏 15
点赞 2
评论 2

这是原作者的博客地址

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;
	
	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服务

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);
	}
}

 

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;
	
	//开启流程实例
	@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所用的数据库和我们的业务数据库,并自动发布我们的流程。

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

此时用户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。

本文转载自:http://wiselyman.iteye.com/blog/2285223

共有 人打赏支持
fengyexjtu

fengyexjtu

粉丝 5
博文 49
码字总数 20075
作品 0
西安
程序员
加载中

评论(2)

l
long

引用来自“a43430096”的评论

你好 按照你分享的 我配置完了后 请求http://localhost:8080/activiti 弹出需要用户名密码 请问怎么处理啊
路人甲,推测你是不是用了比较高的spring boot版本。我遇到好像出现这种情况,要把spring security 验证功能关闭,才行。
a43430096
a43430096
你好 按照你分享的 我配置完了后 请求http://localhost:8080/activiti 弹出需要用户名密码 请问怎么处理啊
kft-activiti-demo 1.13.0 发布,Activiti 快速入门 Demo

时隔一年再次更新,主要是针对Activiti 5.17+版本做了支持,自动初始化Demo数据等 Activiti Modeler从5.17开始结构和整合到项目的方式有些变化,另外官方Activiti Explorer整合的方式也有Spr...

咖啡兔
2015/11/25
1K
3
十分钟认识Activiti6.0工作流引擎

概述 了解Activiti 假如你还不知道Activiti是什么,那么工作流引擎对你来说一定也是新的,解决Activiti和工作流知识盲点,所以看到到这里就对了,还有Android同学会误以为是“Activity”,工...

JimmyNo1
06/13
0
0
一文读懂Spring Boot、微服务架构和大数据治理之间的故事

微服务架构 微服务的诞生并非偶然,它是在互联网高速发展,技术日新月异的变化以及传统架构无法适应快速变化等多重因素的推动下诞生的产物。互联网时代的产品通常有两类特点:需求变化快和用...

纯洁微笑
05/10
0
0
高手问答第 204 期 —— Java EE 开发专家教你用 Spring Boot 2 高效开发企业应用

OSCHINA 本期高手问答(2018 年 7 月 10 日 — 7 月 16 日)我们请来了@肖文吉 为大家解答关于 Spring Boot 2 方面的问题。 肖文吉,Java EE 应用开发专家,疯狂 Java 团队精英讲师。15年以上软...

局长
07/09
0
0
tanghc/fastmybatis

fastmybatis fastmybatis是一个mybatis开发框架,目的为简化mybatis的开发,让开发更高效。 零配置快速上手 无需编写xml文件即可完成CRUD操作 支持mysql,sqlserver,oracle,postgresql,sq...

tanghc
06/20
0
0
m.toutiao.im/whatsmars

whatsmars $ Java生态研究(Spring Boot + Redis + Dubbo + RocketMQ) Spring Boot 系列(Servlet, Tomcat, Spring, SpringMVC, Spring Boot) Modules intro Module Intro whatsmars-common m......

m.toutiao.im
2017/12/25
0
0
Spring Boot Admin 2.0.0 发布,使用 Vue.js 重写 UI

Spring Boot Admin 2.0.0 已发布。 要注意的是,由于 Spring Cloud Finchley 尚未发布,因此该版本不包含对 Spring Cloud Discovery 的支持。 2.0.0 值得关注的变化包括 UI、客户端和后端的改...

淡漠悠然
06/11
0
0
Spring Boot整合 Thymeleaf 模板引擎

什么是Thymeleaf Thymeleaf是一款用于渲染XML、XHTML、HTML5内容的模板引擎。类似Velocity,FreeMaker模板引擎,它也可以轻易的与Spring MVC等Web框架进行集成作为Web应用的模板引擎。 Thym...

Java技术栈
06/08
0
0
Spring Boot Admin 2.0开箱体验

概述 在我之前的 《Spring Boot应用监控实战》 一文中,讲述了如何利用 Spring Boot Admin 1.5.X 版本来可视化地监控 Spring Boot 应用。说时迟,那时快,现在 Spring Boot Admin 都更新到 ...

CodeSheep
昨天
0
0
论代码所需要的环境、版本的重要性

学员们在参与“基于Spring Boot的博客系统实战”课程的时候,可能没有太注意版本的问题。其实,版本是一个非常重要也是一个非常容易忽略的问题。 版本不一致会导致各种奇怪的问题,比如: 应...

老卫
06/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

about git flow

  昨天元芳做了git分支管理规范的分享,为了拓展大家关于git分支的认知,这里我特意再分享这两个关于git flow的链接,大家可以看一下。 Git 工作流程 Git分支管理策略   git flow本质上是...

qwfys
今天
1
0
Linux系统日志文件

/var/log/messages linux系统总日志 /etc/logrotate.conf 日志切割配置文件 参考https://my.oschina.net/u/2000675/blog/908189 dmesg命令 dmesg’命令显示linux内核的环形缓冲区信息,我们可...

chencheng-linux
今天
1
0
MacOS下给树莓派安装Raspbian系统

下载镜像 前往 树莓派官网 下载镜像。 点击 最新版Raspbian 下载最新版镜像。 下载后请,通过 访达 双击解压,或通过 unzip 命令解压。 检查下载的文件 ls -lh -rw-r--r-- 1 dingdayu s...

dingdayu
今天
0
0
spring boot使用通用mapper(tk.mapper) ,id自增和回显等问题

最近项目使用到tk.mapper设置id自增,数据库是mysql。在使用通用mapper主键生成过程中有一些问题,在总结一下。 1、UUID生成方式-字符串主键 在主键上增加注解 @Id @GeneratedValue...

北岩
今天
2
0
告警系统邮件引擎、运行告警系统

告警系统邮件引擎 cd mail vim mail.py #!/usr/bin/env python#-*- coding: UTF-8 -*-import os,sysreload(sys)sys.setdefaultencoding('utf8')import getoptimport smtplibfr......

Zhouliang6
今天
0
0
Java工具类—随机数

Java中常用的生成随机数有Math.random()方法及java.util.Random类.但他们生成的随机数都是伪随机的. Math.radom()方法 在jdk1.8的Math类中可以看到,Math.random()方法实际上就是调用Random类...

PrivateO2
今天
2
0
关于java内存模型、并发编程的好文

Java并发编程:volatile关键字解析    volatile这个关键字可能很多朋友都听说过,或许也都用过。在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果。在...

DannyCoder
昨天
0
0
dubbo @Reference retries 重试次数 一个坑

在代码一中设置 成retries=0,也就是调用超时不用重试,结果DEBUG的时候总是重试,不是0吗,0就不用重试啊。为什么还是调用了多次呢? 结果在网上看到 这篇文章才明白 https://www.cnblogs....

奋斗的小牛
昨天
2
0
数据结构与算法3

要抓紧喽~~~~~~~放羊的孩纸回来喽 LowArray类和LowArrayApp类 程序将一个普通的Java数组封装在LowArray类中。类中的数组隐藏了起来,它是私有的,所以只有类自己的方法才能访问他。 LowArray...

沉迷于编程的小菜菜
昨天
0
0
spring boot应用测试框架介绍

一、spring boot应用测试存在的问题 官方提供的测试框架spring-boot-test-starter,虽然提供了很多功能(junit、spring test、assertj、hamcrest、mockito、jsonassert、jsonpath),但是在数...

yangjianzhou
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部