这是原作者的博客地址

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&lt;Person&gt; <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&lt;Person&gt; 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>&lt;<span class="hljs-built_in">String</span>, <span class="hljs-built_in">Object</span>&gt; variables = <span class="hljs-keyword">new</span> HashMap&lt;<span class="hljs-built_in">String</span>, <span class="hljs-built_in">Object</span>&gt;();
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&lt;Task&gt; 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>&lt;<span class="hljs-built_in">String</span>, <span class="hljs-built_in">Object</span>&gt; taskVariables = <span class="hljs-keyword">new</span> HashMap&lt;<span class="hljs-built_in">String</span>, <span class="hljs-built_in">Object</span>&gt;();
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&lt;TaskRepresentation&gt; <span class="hljs-title">getTasks</span><span class="hljs-params">(@RequestParam String assignee)</span> </span>{
List&lt;Task&gt; tasks = myService.getTasks(assignee);
List&lt;TaskRepresentation&gt; dtos = <span class="hljs-keyword">new</span> ArrayList&lt;TaskRepresentation&gt;();
<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用户的任务,返回结果为:

  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集成实战 转的更多相关文章

  1. 图书-技术-SpringBoot:《Spring Boot 企业级应用开发实战》

    ylbtech-图书-技术-SpringBoot:<Spring Boot 企业级应用开发实战> Spring Boot 企业级应用开发实战,全书围绕如何整合以 Spring Boot 为 ...

  2. Spring Boot 如何快速集成 Redis 哨兵?

    上一篇:Spring Boot 如何快速集成 Redis? 前面的分享栈长介绍了如何使用 Spring Boot 快速集成 Redis,上一篇是单机版,也有粉丝留言说有没有 Redis Sentine ...

  3. spring boot / cloud (三) 集成springfox-swagger2构建在线API文档

    spring boot / cloud (三) 集成springfox-swagger2构建在线API文档 前言 不能同步更新API文档会有什么问题? 理想情况下,为所开发的服务编写接口文档,能提高与 ...

  4. Spring Boot HikariCP 一 ——集成多数据源

    其实这里介绍的东西主要是参考的另外一篇文章,数据库读写分离的. 参考文章就把链接贴出来,里面有那位的代码,简单明了https://gitee.com/comven/dynamic-datasource ...

  5. Spring Boot系列——如何集成Log4j2

    上篇<Spring Boot系列--日志配置>介绍了Spring Boot如何进行日志配置,日志系统用的是Spring Boot默认的LogBack. 事实上,除了使用默认的LogBack ...

  6. 【ELK】4.spring boot 2.X集成ES spring-data-ES 进行CRUD操作 完整版+kibana管理ES的index操作

    spring boot 2.X集成ES 进行CRUD操作  完整版 内容包括: ============================================================ ...

  7. Spring Boot 从入门到实战汇总

    之前写过几篇spring boot入门到实战的博文,因为某些原因没能继续. 框架更新迭代很快,之前还是基于1.x,现在2.x都出来很久了.还是希望能从基于该框架项目开发的整体有一个比较系统的梳理,于是 ...

  8. 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 ...

  9. 14、Spring Boot 2.x 集成 Druid 数据源

    14.Spring Boot 2.x 集成 Druid 数据源 完整源码: Spring-Boot-Demos

随机推荐

  1. Laravel 批量替换某个字段

    Likeword::offset(16854)->chunk(100, function ($word_list) { foreach ($word_list as $word) { $new ...

  2. Thinkphp 不足之处

    1.报错机制 //控制器里面直接输出如下内容,代码不提示.TP报错机制已经开启 echo $aaaaaa; bbbbbbbbb; eco bbbbbbbb; 正常应该给出以下提示 Notice: Un ...

  3. Ajax--解析JSON数据与解析XML数据

    一.Ajax解析JSON数据 nav.json(json数据) [ { "link":"http://www.jd.com", "src": ...

  4. ecshop二次开发之电子票

    前台效果展示: 2. 3. 后台展示效果: 代码实现: 一.             添加菜单项:路径admin\includes\inc_menu.PHP $modules['18_ticket_m ...

  5. Android平台本地(离线)打包指南 - Android Studio

    预备环境 AndroidStudio开发环境,要求安装Android4.0或以上(API 14)SDK. 下载HBuilder离线打包Android版SDK(5+ SDK下载). 离线打包SDK目录说 ...

  6. 动态生成能够局部刷新的验证码【AJAX技术】---看了不懂赔你钱

    在开发JavaWeb应用时,动态生成能够局部刷新的验证码是一项必须的功能,在这里我们将会详细的讲解如何实现这一功能. 一.涉及技术 该功能需要用到AJAX异步传输技术,这样能保证在点击"看不 ...

  7. UE4 Pak 相关知识总结

    转载自:https://arcecho.github.io/2017/07/02/UE4-Pak-%E7%9B%B8%E5%85%B3%E7%9F%A5%E8%AF%86%E6%80%BB%E7%BB ...

  8. 初识Django(DNS原理及web框架)

    DNS的原理 假设www.abc.com的主机要查询www.xyz.abc.com的服务器ip地址. 知识点 1.hosts文件:以静态映射的方式提供IP地址与主机名的对照表,类似ARP表 2.域:a ...

  9. Java练习 SDUT-3848_Shift Dot

    Shift Dot Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 给出平面直角坐标系中的一点,并顺序给出n个向量,求该 ...

  10. bzoj1614 架设电话线

    Description Farmer John打算将电话线引到自己的农场,但电信公司并不打算为他提供免费服务.于是,FJ必须为此向电信公司支付一定的费用. FJ的农场周围分布着N(1 <= N ...