• Activiti7之整合spring和spring boot


    整合spring

    通过 org.activiti.spring.SpringProcessEngineConfiguration Spring 整合方式来创建ProcessEngine 对象。

    1.导入依赖

    jdk的版本是1.8

    junit的版本必须是4.12以上

      1 <dependencies>
      2     <dependency>
      3       <groupId>org.activiti</groupId>
      4       <artifactId>activiti-engine</artifactId>
      5       <version>7.0.0.Beta1</version>
      6     </dependency>
      7 
      8     <dependency>
      9       <groupId>org.activiti</groupId>
     10       <artifactId>activiti-bpmn-model</artifactId>
     11       <version>7.0.0.Beta1</version>
     12     </dependency>
     13 
     14     <dependency>
     15       <groupId>org.activiti</groupId>
     16       <artifactId>activiti-bpmn-converter</artifactId>
     17       <version>7.0.0.Beta1</version>
     18     </dependency>
     19 
     20     <dependency>
     21       <groupId>org.activiti</groupId>
     22       <artifactId>activiti-json-converter</artifactId>
     23       <version>7.0.0.Beta1</version>
     24     </dependency>
     25 
     26  <!--   <dependency>
     27       <groupId>org.activiti</groupId>
     28       <artifactId>activiti-bpmn-layout</artifactId>
     29       <version>7.0.0.Beta1</version>
     30     </dependency>-->
     31 
     32     <dependency>
     33       <groupId>org.activiti.cloud</groupId>
     34       <artifactId>activiti-cloud-services-api</artifactId>
     35       <version>7.0.0.Beta1</version>
     36     </dependency>
     37 
     38     <!--activiti和Spring整合依赖-->
     39     <dependency>
     40       <groupId>org.activiti</groupId>
     41       <artifactId>activiti-spring</artifactId>
     42       <version>7.0.0.Beta1</version>
     43     </dependency>
     44 
     45     <!--数据库依赖-->
     46     <dependency>
     47       <groupId>mysql</groupId>
     48       <artifactId>mysql-connector-java</artifactId>
     49       <version>5.1.38</version>
     50     </dependency>
     51 
     52 
     53     <!--单测依赖-->
     54     <dependency>
     55       <groupId>junit</groupId>
     56       <artifactId>junit</artifactId>
     57       <version>4.12</version>
     58     </dependency>
     59 
     60     <dependency>
     61       <groupId>org.springframework</groupId>
     62       <artifactId>spring-test</artifactId>
     63       <version>5.0.7.RELEASE</version>
     64     </dependency>
     65 
     66 
     67     <!-- log start -->
     68     <dependency>
     69       <groupId>log4j</groupId>
     70       <artifactId>log4j</artifactId>
     71       <version>${log4j.version}</version>
     72     </dependency>
     73     <dependency>
     74       <groupId>org.slf4j</groupId>
     75       <artifactId>slf4j-api</artifactId>
     76       <version>${slf4j.version}</version>
     77     </dependency>
     78     <dependency>
     79       <groupId>org.slf4j</groupId>
     80       <artifactId>slf4j-log4j12</artifactId>
     81       <version>${slf4j.version}</version>
     82     </dependency>
     83 
     84 
     85     <dependency>
     86       <groupId>org.mybatis</groupId>
     87       <artifactId>mybatis</artifactId>
     88       <version>3.4.5</version>
     89     </dependency>
     90 
     91 
     92     <!--数据源-->
     93     <dependency>
     94       <groupId>commons-dbcp</groupId>
     95       <artifactId>commons-dbcp</artifactId>
     96       <version>1.4</version>
     97     </dependency>
     98 
     99     <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
    100     <dependency>
    101       <groupId>commons-io</groupId>
    102       <artifactId>commons-io</artifactId>
    103       <version>2.4</version>
    104     </dependency>
    105 
    106   </dependencies>
    107   <repositories>
    108     <repository>
    109       <id>alfresco</id>
    110       <name>Activiti Releases</name>
    111       <url>https://artifacts.alfresco.com/nexus/content/repositories/activiti-releases/</url>
    112       <releases>
    113         <enabled>true</enabled>
    114       </releases>
    115     </repository>
    116   </repositories>
    依赖

    2.配置Activiti

     1 配置内容:1.数据源         2.配置processEngine对象        3.配置XXXXService
     2                 <!--数据源-->
     3                 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
     4                     <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
     5                     <property name="url" value="jdbc:mysql://localhost:3306/activiti-y2170"/>
     6                     <property name="username" value="root"/>
     7                     <property name="password" value="root"/>
     8                 </bean>
     9 
    10                 <!--配置ProcessEngineConfiguration-->
    11                 <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
    12                     <!--数据源-->
    13                     <property name="dataSource" ref="dataSource"/>
    14                     <!--配置事务-->
    15                     <property name="transactionManager" ref="transactionManager"/>
    16                     <!--数据生成策略    true   false   create   drop-create -->
    17                     <property name="databaseSchemaUpdate" value="true"/>
    18                 </bean>
    19 
    20                 <!--配置ProcessEngine-->
    21                 <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
    22                     <property name="processEngineConfiguration" ref="processEngineConfiguration"/>
    23                 </bean>
    24 
    25                 <!--配置RepositoryService-->
    26                 <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService"/>
    27                 <!--配置RuntimeService-->
    28                 <bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService"/>
    29                 <!--配置TaskService-->
    30                 <bean id="taskService" factory-bean="processEngine" factory-method="getTaskService"/>
    31                 <!--配置HistoryService-->
    32                 <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService"/>
    33                 
    34                 <!--配置事务管理器-->
    35                 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    36                     <property name="dataSource" ref="dataSource"/>
    37                 </bean>
    配置

    3.测试

     1 package com.wish;
     2 
     3 import static org.junit.Assert.assertTrue;
     4 
     5 import org.activiti.engine.RepositoryService;
     6 import org.junit.Test;
     7 import org.junit.runner.RunWith;
     8 import org.springframework.test.context.ContextConfiguration;
     9 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    10 
    11 import javax.annotation.Resource;
    12 
    13 /**
    14  * Unit test for simple App.
    15  */
    16 @RunWith(SpringJUnit4ClassRunner.class)     //测试方式  junit4.12+
    17 @ContextConfiguration("classpath:springActibiti.xml")   //配置
    18 public class AppTest 
    19 {
    20     @Resource
    21     private RepositoryService repositoryService;
    22     @Test
    23     public void shouldAnswerWithTrue()
    24     {
    25         System.out.println("部署对象:"+repositoryService);
    26     }
    27 }
    测试

    运行结果:接下来就可以部署了

    使用RepositoryService 进行部署

     1    /**
     2      * 测试流程部署
     3      */
     4     @Test
     5     public void deployment(){
     6         repositoryService.createDeployment()
     7                 .addClasspathResource("flowchart/process.bpmn")
     8                 .name("测试Spring流程部署")
     9                 .deploy();
    10     }
    repositoryService部署

    运行结果

     

    执行流程分析

    下面我们一起来分析Activiti 与Spring 整合加载的过程。如下图所示:

    从图中我们可以看出,首先我们加载 activiti-spring.xml 配置文件,而该配置文件中又会加载SpringProcessEngineConfiguration 对 象 ,

    这 个 对 象 它 需 要 依 赖 注 入 dataSource 对 象 和transactionManager 对象。

    其次会加载ProcessEngineFactoryBean 工厂来创建ProcessEngine 对象,而ProcessEngineFactoryBean 工厂又需要 依赖注 入 processEngineConfiguration 对 象。

    最后 由processEngine 对象来负责创建我们的 Service 对象,从而简化 Activiti 的开发过程。在程序代码中我们可以根据实际需求来决定使用的Service 对象。

     

    Activiti7的新特性

    Activiti7的GitHub官方网站:https://github.com/Activiti/activiti-7-developers-guide/blob/51a1681c0e4bb5e2f96a6dea73516c9fd53 d8521/getting-started/getting-started-activiti-core.md

    下载 Activiti-Core 的Example 示例:https://github.com/Activiti/activiti-examples

    Activiti7 为了简化对工作流的操作,特别在原有 API 的基础上再次进行封闭,这样我们原来所学习的Activiti 基本API 就被封闭起来了。

    具体要学习的包括:

    ProcessRuntime 接口TaskRuntime 接口

    ProcessRuntime 接口

    通过上面的分析,我们发现使用 Activiti7 开发时,只要注入ProcessRuntime 的实现对象,就可以实现流程定义信息的操作。

    当然这个过程中因为 Activiti7 与SpringSecurity 的强耦合,引导我们也必须将SpringSecurity 加入进来。

    TaskRuntime 接口

     

    上面部分给我们介绍了如何引入Activiti Core 所需的坐标,同时介绍了如何添加 TaskRuntime 实现对象,源码介绍等。我们会发现TaskRuntime 本身就是对于TaskService 的一个封装。

    SpringBoot整合Activiti7

     导入依赖

     1    <parent>
     2         <groupId>org.springframework.boot</groupId>
     3         <artifactId>spring-boot-starter-parent</artifactId>
     4         <version>2.1.4.RELEASE</version>
     5     </parent>
     6 
     7 
     8 <dependency>
     9             <groupId>org.springframework.boot</groupId>
    10             <artifactId>spring-boot-starter-jdbc</artifactId>
    11         </dependency>
    12         <dependency>
    13             <groupId>org.springframework.boot</groupId>
    14             <artifactId>spring-boot-starter-web</artifactId>
    15         </dependency>
    16         <dependency>
    17             <groupId>org.springframework.boot</groupId>
    18             <artifactId>spring-boot-starter-test</artifactId>
    19             <scope>test</scope>
    20         </dependency>
    21         <!-- https://mvnrepository.com/artifact/org.activiti/activiti-spring-boot-starter -->
    22         <dependency>
    23             <groupId>org.activiti</groupId>
    24             <artifactId>activiti-spring-boot-starter</artifactId>
    25             <version>7.0.0.Beta2</version>
    26         </dependency>
    27         <dependency>
    28             <groupId>org.mybatis</groupId>
    29             <artifactId>mybatis</artifactId>
    30             <version>3.4.5</version>
    31         </dependency>
    32         <dependency>
    33             <groupId>mysql</groupId>
    34             <artifactId>mysql-connector-java</artifactId>
    35             <version>5.1.38</version>
    36         </dependency>
    依赖

    配置application.yml

    1 spring:
    2   datasource:
    3     url: jdbc:mysql://localhost:3306/activiti-wn?useUnicode=true&characterEncoding=utf8&serverT imezone=GMT
    4     username : root
    5     password : 123456
    6     driver-class-name: com.mysql.jdbc.Driver
    7   activiti:
    8     db-history-used: true   #开启历史信息
    配置application.yml

    将SpringSecurity配置添加到项目当中

    SecurityUtil关于权限登陆

     1 package com.wish.activiti;
     2 
     3 import org.springframework.beans.factory.annotation.Autowired;
     4 import org.springframework.security.core.Authentication;
     5 import org.springframework.security.core.GrantedAuthority;
     6 import org.springframework.security.core.context.SecurityContextHolder;
     7 import org.springframework.security.core.context.SecurityContextImpl;
     8 import org.springframework.security.core.userdetails.UserDetails;
     9 import org.springframework.security.core.userdetails.UserDetailsService;
    10 import org.springframework.stereotype.Component;
    11 
    12 import java.util.Collection;
    13 
    14 @Component
    15 public class SecurityUtil {
    16 
    17     @Autowired
    18     private UserDetailsService userDetailsService;
    19 
    20     public void logInAs(String username) {
    21 
    22          UserDetails user = userDetailsService.loadUserByUsername(username);
    23         if (user == null) {
    24             throw new IllegalStateException("User " + username + " doesn't exist, please provide a valid user");
    25         }
    26 
    27         SecurityContextHolder.setContext(new SecurityContextImpl(new Authentication() {
    28             @Override
    29             public Collection<? extends GrantedAuthority> getAuthorities() {
    30                 return user.getAuthorities();
    31             }
    32 
    33             @Override
    34             public Object getCredentials() {
    35                 return user.getPassword();
    36             }
    37 
    38             @Override
    39             public Object getDetails() {
    40                 return user;
    41             }
    42 
    43             @Override
    44             public Object getPrincipal() {
    45                 return user;
    46             }
    47 
    48             @Override
    49             public boolean isAuthenticated() {
    50                 return true;
    51             }
    52 
    53             @Override
    54             public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
    55 
    56             }
    57 
    58             @Override
    59             public String getName() {
    60                 return user.getUsername();
    61             }
    62         }));
    63         org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(username);
    64     }
    65 }
    SecurityUtil

    DemoApplicationConfiguration 关于权限配置

     1 /*
     2  * Copyright 2018 Alfresco, Inc. and/or its affiliates.
     3  *
     4  * Licensed under the Apache License, Version 2.0 (the "License");
     5  * you may not use this file except in compliance with the License.
     6  * You may obtain a copy of the License at
     7  *
     8  *       http://www.apache.org/licenses/LICENSE-2.0
     9  *
    10  * Unless required by applicable law or agreed to in writing, software
    11  * distributed under the License is distributed on an "AS IS" BASIS,
    12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  * See the License for the specific language governing permissions and
    14  * limitations under the License.
    15  */
    16 
    17 package com.wish.activiti;
    18 
    19 import org.slf4j.Logger;
    20 import org.slf4j.LoggerFactory;
    21 import org.springframework.beans.factory.annotation.Autowired;
    22 import org.springframework.context.annotation.Bean;
    23 import org.springframework.context.annotation.Configuration;
    24 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    25 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    26 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    27 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    28 import org.springframework.security.core.authority.SimpleGrantedAuthority;
    29 import org.springframework.security.core.userdetails.User;
    30 import org.springframework.security.core.userdetails.UserDetailsService;
    31 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    32 import org.springframework.security.crypto.password.PasswordEncoder;
    33 import org.springframework.security.provisioning.InMemoryUserDetailsManager;
    34 import java.util.Arrays;
    35 import java.util.List;
    36 import java.util.stream.Collectors;
    37 
    38 @Configuration
    39 @EnableWebSecurity
    40 public class DemoApplicationConfiguration extends WebSecurityConfigurerAdapter {
    41 
    42     private Logger logger = LoggerFactory.getLogger(DemoApplicationConfiguration.class);
    43 
    44     @Override
    45     @Autowired
    46     public void configure(AuthenticationManagerBuilder auth) throws Exception {
    47         auth.userDetailsService(myUserDetailsService());
    48     }
    49 
    50     @Bean
    51     public UserDetailsService myUserDetailsService() {
    52 
    53         InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();
    54 
    55         String[][] usersGroupsAndRoles = {
    56                 {"salaboy", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"},
    57                 {"ryandawsonuk", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"},
    58                 {"erdemedeiros", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"},
    59                 {"other", "password", "ROLE_ACTIVITI_USER", "GROUP_otherTeam"},
    60                 {"admin", "password", "ROLE_ACTIVITI_ADMIN"},
    61         };
    62 
    63         for (String[] user : usersGroupsAndRoles) {
    64             List<String> authoritiesStrings = Arrays.asList(Arrays.copyOfRange(user, 2, user.length));
    65             logger.info("> Registering new user: " + user[0] + " with the following Authorities[" + authoritiesStrings + "]");
    66             inMemoryUserDetailsManager.createUser(new User(user[0], passwordEncoder().encode(user[1]),
    67                     authoritiesStrings.stream().map(s -> new SimpleGrantedAuthority(s)).collect(Collectors.toList())));
    68         }
    69 
    70 
    71         return inMemoryUserDetailsManager;
    72     }
    73 
    74 
    75     @Override
    76     protected void configure(HttpSecurity http) throws Exception {
    77         http
    78                 .csrf().disable()
    79                 .authorizeRequests()
    80                 .anyRequest()
    81                 .authenticated()
    82                 .and()
    83                 .httpBasic();
    84 
    85 
    86     }
    87 
    88     @Bean
    89     public PasswordEncoder passwordEncoder() {
    90         return new BCryptPasswordEncoder();
    91     }
    92 }
    DemoApplicationConfiguration

    启动工程

     1 package com.wish;
     2 
     3 import org.springframework.boot.SpringApplication;
     4 import org.springframework.boot.autoconfigure.SpringBootApplication;
     5 
     6 @SpringBootApplication
     7 public class StartActiviti {
     8     public static void main(String[] args) {
     9         SpringApplication.run(StartActiviti.class,args);
    10     }
    11 }
    启动项目

    运行成功,数据库创建表

    注意问题:
    1.Activiti7和SpringSecurity耦合,需要加入SpringSecurity的依赖和配置,我们可以使用Security中的用户角色组定义流程执行的组
    2.流程默认可自动部署,但是需要再resources/processes文件夹,将流程文件放入当中
    3.默认历史表不会生成,需要手动开启配置

    执行流程

     1 package com.wish.controller;
     2 
     3 
     4 import com.wish.activiti.SecurityUtil;
     5 import org.activiti.api.process.model.ProcessDefinition;
     6 import org.activiti.api.process.model.ProcessInstance;
     7 import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
     8 import org.activiti.api.process.runtime.ProcessRuntime;
     9 import org.activiti.api.runtime.shared.query.Page;
    10 import org.activiti.api.runtime.shared.query.Pageable;
    11 import org.activiti.api.task.model.Task;
    12 import org.activiti.api.task.model.builders.TaskPayloadBuilder;
    13 import org.activiti.api.task.runtime.TaskRuntime;
    14 import org.springframework.web.bind.annotation.RequestMapping;
    15 import org.springframework.web.bind.annotation.RestController;
    16 
    17 import javax.annotation.Resource;
    18 
    19 @RestController
    20 @RequestMapping("/activiti")
    21 public class ActivitiController {
    22     @Resource
    23     private ProcessRuntime processRuntime;
    24     @Resource
    25     private TaskRuntime taskRuntime;
    26     @Resource
    27     private SecurityUtil securityUtil;
    28     /**
    29      * 查询流程定义
    30      */
    31     @RequestMapping("/getProcess")
    32     public void getProcess(){
    33         //查询所有流程定义信息
    34         Page<ProcessDefinition> processDefinitionPage = processRuntime.processDefinitions(Pageable.of(0, 10));
    35         System.out.println("当前流程定义的数量:"+processDefinitionPage.getTotalItems());
    36         //获取流程信息
    37         for (ProcessDefinition processDefinition:processDefinitionPage.getContent()) {
    38             System.out.println("流程定义信息"+processDefinition);
    39         }
    40     }
    41 
    42     /**
    43      * 启动流程示例
    44      */
    45     @RequestMapping("/startInstance")
    46     public void startInstance(){
    47         ProcessInstance instance = processRuntime.start(ProcessPayloadBuilder.start().withProcessDefinitionKey("demo").build());
    48         System.out.println(instance.getId());
    49     }
    50 
    51     /**
    52      * 获取任务,拾取任务,并且执行
    53      */
    54     @RequestMapping("/getTask")
    55     public void getTask(){
    56         securityUtil.logInAs("salaboy");        //指定组内任务人
    57         Page<Task> tasks = taskRuntime.tasks(Pageable.of(0, 10));
    58         if(tasks.getTotalItems()>0){
    59             for (Task task:tasks.getContent()) {
    60                 System.out.println("任务名称:"+task.getName());
    61                 //拾取任务
    62                 taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(task.getId()).build());
    63                 //执行任务
    64                 taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(task.getId()).build());
    65             }
    66         }
    67     }
    68 }
    执行流程

    执行查询流程定义操作

     

    执行启动流程示例

    执行获取任务,拾取任务,并且执行操作

  • 相关阅读:
    day15---作业
    day14---函数的参数
    day14作业
    day--13函数的基本使用
    day13--函数练习(作业)
    day12--文件处理
    day12--作业
    Python函数对象、函数嵌套和闭包函数
    每日作业以及周末作业
    Python名称空间与作用域
  • 原文地址:https://www.cnblogs.com/wishsaber/p/12669702.html
Copyright © 2020-2023  润新知