spring boot 集成activiti

项目结构如上图,

<?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.megalith</groupId>
    <artifactId>security_simple</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>security_simple</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <pagehelper.version>1.1.0</pagehelper.version>
        <mybatis.generator.version>1.3.2</mybatis.generator.version>
        <fastjson.version>1.2.31</fastjson.version>
        <jackson.version>2.9.7</jackson.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
           <!--  <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions> -->
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
   <!--   <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency> -->
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!-- aop -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <!-- json处理 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>${fastjson.version}</version>
        </dependency>

        <!-- jackson json begin -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-jaxb-annotations</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <!-- jackson json end -->
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.3.2</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.uuid</groupId>
            <artifactId>java-uuid-generator</artifactId>
            <version>3.1.3</version>
        </dependency>


        <!-- druid datasource -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.27</version>
        </dependency>
        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>
        <!--mybatis代码生成器 -->
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>${mybatis.generator.version}</version>
        </dependency>
        <!-- bean验证 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

        <!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- spring boot 开发工具 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- 测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <!--spring-security-oauth2 begin-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.oauth.boot</groupId>
            <artifactId>spring-security-oauth2-autoconfigure</artifactId>
            <version>2.0.6.RELEASE</version>
        </dependency>
        <!--spring-security-oauth2 end-->
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>
 

ActivitiConfiguration是activiti的配置类

package activitiPro;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.activiti.designer.test.test;
import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.ManagementService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.spring.SpringProcessEngineConfiguration;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import com.alibaba.druid.pool.DruidDataSource;

@Configuration
public class ActivitiConfiguration {
    private static final Logger log = LogManager.getLogger(ActivitiConfiguration.class);
    @Autowired
    private TestService testService;
     
     
    @Bean(name = "activitiDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.activiti")
    public DataSource activitiDataSource(){
        log.info("activitiDataSource 初始化...");
        return new DruidDataSource();
    }
    @Bean
    public PlatformTransactionManager txManager() {
        return new DataSourceTransactionManager(activitiDataSource());
    }
    @Bean
    public ProcessEngine processEngine() throws IOException {
  
        SpringProcessEngineConfiguration configuration = new SpringProcessEngineConfiguration();
    //自动部署已有的流程文件
    Resource[] resources = new PathMatchingResourcePatternResolver().getResources(ResourceLoader.CLASSPATH_URL_PREFIX + "diagrams/*.bpmn");
    configuration.setTransactionManager(txManager());
    configuration.setDataSource(activitiDataSource());
    configuration.setDatabaseSchemaUpdate("true");
    configuration.setDeploymentResources(resources);
    configuration.setDbIdentityUsed(false);
 
    
    Map<Object, Object>beans=new HashMap<Object, Object>();
    beans.put("testService",testService);
    configuration.setBeans(beans);   

   return configuration.buildProcessEngine();
}

@Bean
public RepositoryService repositoryService(ProcessEngine processEngine) {
    return processEngine.getRepositoryService();
}

@Bean
public RuntimeService runtimeService(ProcessEngine processEngine) {
    return processEngine.getRuntimeService();
}

@Bean
public TaskService taskService(ProcessEngine processEngine) {
    return processEngine.getTaskService();
}

@Bean
public HistoryService historyService(ProcessEngine processEngine) {
    return processEngine.getHistoryService();
}

@Bean
public ManagementService managementService(ProcessEngine processEngine) {
    return processEngine.getManagementService();
}

@Bean
public IdentityService identityService(ProcessEngine processEngine) {
    return processEngine.getIdentityService();
}
}

 

configuration.setBeans(beans);   //如果流程设计中需要使用${}或者#{}表达式,就需要把这个bean进行暴露,如果不进行暴露则报未知标识符错误

如果使用spring则在配置文件中设置:

<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
  ...
  <property name="beans">
    <map>
      <entry key="printer" value-ref="printer" />
    </map>
  </property>
</bean>

  <bean id="printer" class="org.activiti.examples.spring.Printer" />

测试中 :

 ProcessInstance  pi=    runtimeService.startProcessInstanceByKey("myProcess");  //标识启动流程,一般前端填写表达时进行调用后端这句话进行启动

同时会在流程表中穿件记录

流程执行过程中是根据流程id查询流程状态和执行流程。

如下:
            List<Task> task = taskService.createTaskQuery().processInstanceId(pi.getId()).list(); //查询流程状态
            taskService.complete(task.get(0).getId());//执行流程

只有执行了流程,流程才会流转到下一步


            List<Task> task1 = taskService.createTaskQuery().processInstanceId(pi.getId()).list();//查询流程状态
            System.out.println(task1.get(0).getAssignee());
            askService.complete(task1.get(0).getId());//执行流程

以此类推

   TaskQuery taskQuery = taskService.createTaskQuery().taskCandidateOrAssigned(userId);//根据人查询自己的任务

流程启动之后会在流程表act_ru_execution存储一条记录,

流程执行之后会修改act_ru_execution表中ACT_ID_字段,对应流程任务id,如下图

 

同时在流程任务表中存储流程任务信息

如果流程任务有对应的候选人会在对应act_ru_identitylink表中产生候选人任务对应数据

流程执行完之后会清空act_ru_*表中数据,产生历史数据

 

 

判断

可以通过 

     Map<String,Object>pa=new HashMap<String, Object>();
             pa.put("type",0);
             ProcessInstance  pi=    runtimeService.startProcessInstanceByKey("myProcess",pa);

进行参数设置,

或者在流程执行时执行

taskService.complete(task.get(0).getId(),pa);

开发中发现使用

(排他网管)进行判断,

 

红框中的配置和之上一样,代码写法也一样。

 

事件监听 定义一个类实现TaskListener

public class MyStakLinster  implements TaskListener{

    @Override
    public void notify(DelegateTask delegateTask) {  

//通过代理对象可以实现各种设置
        delegateTask.setAssignee("kk");
        
        
    }

}

 

然后在流程图中配置上这个类,就可以了。

 

首先是我们已经对Activiti流程的开启有了了解之后,在进行下文

流程中用到最多的就是用户任务了,包括谁办理,什么时候办理,办理结果是什么,办理历史等等

 

下文先介绍下用户任务的办理相关操作

 

用户任务分类:

分为4中状态:未签收/待办理、已签收/办理中、运行中/办理中、已完成/已办结

 

首先,我们要了解下 TaskService 这个服务的作用:

1、查询分配给用户或组的任务

2、创建独立运行任务。这些任务与流程实例无关。

3、手工设置任务的执行者,或者这些用户通过何种方式与任务关联。

4、认领并完成一个任务。认领意味着一个人期望成为任务的执行者, 即这个用户会完成这个任务。完成意味着“做这个任务要求的事情”。 通常来说会有很多种处理形式。

 

状态:

通过TaskService来获得任务

 

API简述

从类 org.activiti.engine.impl.ServiceImpl 继承的字段

所有已实现的接口:TaskService

 

TaskService taskService = processEngine.getTaskService();

 

//这边我定义了几个通用 变量

//String userId = "Ypp";

//String userGroup = new String["Ypp1","Ypp101"];

 

 

1、未签收/待办理

 那么流程开启之后,如何能让下一个办理人取得待办任务呢?

 通过下面几种的方法,将取得指定签收人/办理人的待办数据

 //单人待签收/待办理

 List<Task> tasks = taskService.createTaskQuery().taskCandidateUser(userId).list();

 

 //用户组待签收/待办理

 List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup(userGroup).list();

 

 //进行签收操作,也就是将要接收办理这个任务

 //这边可以使用循环,也可以通过其他方法,常用的是先加载一个任务待办列表到页面上,签收任务传递后台一个taskId

 //task.getId() = taskId 

 taskService.claim(task.getId(), userId);//完成签收这个时候就任务Task的Assignee属性就有了值

 

 

 //已经签收过的任务列表,某种意义上我理解为真正的办理人

 List<Task> tasks = taskService.createTaskQuery().taskAssignee(userId).list();

 

2、办理

 通过 1、未签收/待办理 中取得需要办理的任务Task之后 

 //调用 task.getId() = taskId 完成任务的办理,taskService服务自动流转到下一个办理节点

 taskService.complete(task.getId());

 

 //taskService.complete()方法 提供了重载,提供了3种方式供你选择

 complete(String taskId)

 complete(String taskId, Map<String,Object> variables)  

 complete(String taskId, Map<String,Object> variables, boolean localScope) 

 

 如果更深的了解如何流转的可以查看源码

 

 ---------------------------------------------------------------------------

 插一下

 任务并不一定要先签收再办理,可以直接到待办理中,而不是待签收中

 可以把

 taskService.claim(task.getId(), userId);方法

 替换为

 setAssignee(String taskId, String userId) 

 

 经过以上步骤,任务已经在 办理中状态了

 

3、已完成/已办结

 任务的已完成(调用过complete方法)是指当前待办的任务状态,而非整个流程实例的完成状态

 流程中数据使用到 historyService 服务

 //查询指定用户发起的流程 (流程历史 用户发起 )

 //finished  完成的流程  

 //unfinish  还在运行中的流程

 List<HistoricActivityInstance> hais = 下面的3中方法

 historyService.createHistoricProcessInstanceQuery().finished().startedBy(name).orderByProcessInstanceStartTime().desc().listPage(firstResult, maxResults);

 //查询指定用户参与的流程信息 (流程历史  用户参与 )

 List hpis = historyService.createHistoricProcessInstanceQuery().involvedUser(name).orderByProcessInstanceStartTime().desc().listPage(firstResult, maxResults);

 //查询指定流程的任务流转路径 (流程历史 任务 流转 路经)

 historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).orderByHistoricTaskInstanceEndTime().asc().list();

 

 //查看流程是否完整的运行完毕方法也有好几种

 for (HistoricActivityInstance hai : hais) {

//如果下面的方法返回不是空,那就是已办结

hai.getEndTime()

 }

 //查看ACT_RU_TASK表

 Long long = taskService.createTaskQuery().processInstanceId("processInstanceId").taskId("taskId").count();

 //如果long为空,那么也是办结了

 taskService.createTaskQuery()查询条件是可选的

 可以是

 taskService.createTaskQuery().processInstanceId("processInstanceId")

 taskService.createTaskQuery().taskId("taskId")

 或者其他更多条件

 

总结:

//流程在流转中对于当前办理人/组和签收人/组来说,都是可以进行动态调整变化的

//需要对程序进行特殊处理,添加监听或者其他方法

 

 

//得到用户组待签收

    TaskService taskService = processEngine.getTaskService();

//单人待签收

//List<Task> tasks = taskService.createTaskQuery().taskCandidateUser(userId).list();

    List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup(userGroup).list();

    for (Task task : tasks) {

      // 签收

      taskService.claim(task.getId(), userId);

    }

 

    //得到用户待办

    tasks = taskService.createTaskQuery().taskAssignee(userId).list();

    for (Task task : tasks) {

 //办理

      taskService.complete(task.getId());

    }

 

    //顺便查看历史看看

    HistoryService historyService = processEngine.getHistoryService();

    HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(procId).singleResult();

可以参考http://www.mossle.com/docs/activiti/index.html#springExpressions

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章