Activiti-SpringBoot整合


Activiti-SpringBoot整合

  Activiti7發布正式版之后,它與springboot2.x已經完全支持整合開發;我們可以將activiti7與springboot整合開發的坐標引入到工程中,從而達到springboot支持activiti7整合;

  springboot整個activiti7的具體步驟如下:

    1.添加springboot整個activiti7的坐標;

    2.添加SpringSecurity安全框架的整合配置信息;

    3.使用activiti7新支持的類來實現工作流開發;

      ProcessRuntime接口;

      TaskRuntime接口;

    4.使用新的API實現工作流開發,主要包括;

      流程定義查詢

      啟動流程實例

      任務的查詢

      任務的完成

一、目錄展示

  

二、導入依賴

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.4.RELEASE</version>
  </parent>
<dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.4.5</version>
    </dependency>

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

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

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.activiti/activiti-spring-boot-starter -->
    <dependency>
      <groupId>org.activiti</groupId>
      <artifactId>activiti-spring-boot-starter</artifactId>
      <version>7.0.0.Beta2</version>
    </dependency>

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.38</version>
</dependency>

三、application.yml配置文件

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/activiti?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
    username : root
    password : root
    driver-class-name: com.mysql.jdbc.Driver
activiti:
  db-history-used: true

 四、添加 SpringSecurity安全框架整合配置

  因為Activiti7 與SpringBoot 整合后,默認情況下,集成了 SpringSecurity 安全框架,這樣我們就要去准備SpringSecurity 整合進來的相關用戶權限配置信息。

1、添加SecurityUtil類

  為了能夠快速實現 SpringSecurity 安全框架的配置,所添加的一個組件。

package com.zn.avtiviti;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;

import java.util.Collection;

@Component
public class SecurityUtil {
    @Autowired
    private UserDetailsService userDetailsService;

    public void logInAs(String username) {

        UserDetails user = userDetailsService.loadUserByUsername(username);
        if (user == null) {
            throw new IllegalStateException("User " + username + " doesn't exist, please provide a valid user");
        }

        SecurityContextHolder.setContext(new SecurityContextImpl(new Authentication() {
            @Override
            public Collection<? extends GrantedAuthority> getAuthorities() {
                return user.getAuthorities();
            }

            @Override
            public Object getCredentials() {
                return user.getPassword();
            }

            @Override
            public Object getDetails() {
                return user;
            }

            @Override
            public Object getPrincipal() {
                return user;
            }

            @Override
            public boolean isAuthenticated() {
                return true;
            }

            @Override
            public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {

            }

            @Override
            public String getName() {
                return user.getUsername();
            }
        }));
        org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(username);
    }

}

2、添加DemoApplicationConfig 

  在 Activiti7 官方下載的 Example 中找到 DemoApplicationConfig 類,它的作用是為了實現SpringSecurity   框架的用戶權限的配置,這樣我們就可以在系統中使用用戶權限信息。本次項目中基本是在文件中定義出來的用戶信息,當然也可以是數據庫中查詢的用戶權限信息。

package com.zn.avtiviti;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Configuration
@EnableWebSecurity
public class DemoApplicationConfiguration extends WebSecurityConfigurerAdapter {

    private Logger logger = LoggerFactory.getLogger(DemoApplicationConfiguration.class);

    @Override
    @Autowired
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(myUserDetailsService());
    }

    @Bean
    public UserDetailsService myUserDetailsService() {

        InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();

        String[][] usersGroupsAndRoles = {
                {"salaboy", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"},
                {"ryandawsonuk", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"},
                {"erdemedeiros", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"},
                {"other", "password", "ROLE_ACTIVITI_USER", "GROUP_otherTeam"},
                {"admin", "password", "ROLE_ACTIVITI_ADMIN"},
        };

        for (String[] user : usersGroupsAndRoles) {
            List<String> authoritiesStrings = Arrays.asList(Arrays.copyOfRange(user, 2, user.length));
            logger.info("> Registering new user: " + user[0] + " with the following Authorities[" + authoritiesStrings + "]");
            inMemoryUserDetailsManager.createUser(new User(user[0], passwordEncoder().encode(user[1]),
                    authoritiesStrings.stream().map(s -> new SimpleGrantedAuthority(s)).collect(Collectors.toList())));
        }
        return inMemoryUserDetailsManager;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .httpBasic();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

五、流程bpmn文件

(將流程圖放在resources下的processes包里)

  

六、啟動類

package com.zn;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class StartActiviti {
    public static void main(String[] args) {
        SpringApplication.run(StartActiviti.class,args);
    }
} 

注意問題:
  1.Activiti7和SpringSecurity耦合,需要加入SpringSecurity的依賴和配置,我們可以使用Security中的用戶角色組定義流程執行的組
  2.流程默認可自動部署,但是需要再resources/processes文件夾,將流程文件放入當中
  3.默認歷史表不會生成,需要手動開啟配置

七、查詢流程定義

1、代碼塊

package com.zn.controller;

import com.zn.avtiviti.SecurityUtil;
import org.activiti.api.process.model.ProcessDefinition;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.api.task.runtime.TaskRuntime;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@RequestMapping("/activiti")
public class ActivitiController {
    @Resource
    private ProcessRuntime processRuntime;
    @Resource
    private TaskRuntime taskRuntime;
    @Resource
    private SecurityUtil securityUtil;

    /**
     * 查詢流程定義
     */
    @RequestMapping("/getProcess")
    public void getProcess(){
        //查詢所有流程定義信息
        Page<ProcessDefinition> processDefinitionPage = processRuntime.processDefinitions(Pageable.of(0, 10));
        System.out.println("當前流程定義的數量:"+processDefinitionPage.getTotalItems());
        //獲取流程信息
        for (ProcessDefinition processDefinition:processDefinitionPage.getContent()) {
            System.out.println("流程定義信息"+processDefinition);
        }
    }
}

2、數據庫

 

3、訪問localhost:8080/activiti/getProcess進行登錄

  

4、控制台

  

 八、啟動流程示例

1、代碼塊

package com.zn.controller;

import com.zn.avtiviti.SecurityUtil;
import org.activiti.api.process.model.ProcessDefinition;
import org.activiti.api.process.model.ProcessInstance;
import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.api.task.model.Task;
import org.activiti.api.task.model.builders.TaskPayloadBuilder;
import org.activiti.api.task.runtime.TaskRuntime;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@RequestMapping("/activiti")
public class ActivitiController {
    @Resource
    private ProcessRuntime processRuntime;
    @Resource
    private TaskRuntime taskRuntime;
    @Resource
    private SecurityUtil securityUtil;

    /**
     * 啟動流程示例
     */
    @RequestMapping("/startInstance")
    public void startInstance(){
        ProcessInstance instance = processRuntime.start(ProcessPayloadBuilder.start().withProcessDefinitionKey("demo").build());
        System.out.println(instance.getId());
    }
}

2、訪問localhost:8080/activiti/startInstance

3、數據庫

 九、拾取任務

1、代碼塊

package com.zn.controller;

import com.zn.avtiviti.SecurityUtil;
import org.activiti.api.process.model.ProcessDefinition;
import org.activiti.api.process.model.ProcessInstance;
import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.api.task.model.Task;
import org.activiti.api.task.model.builders.TaskPayloadBuilder;
import org.activiti.api.task.runtime.TaskRuntime;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@RequestMapping("/activiti")
public class ActivitiController {
    @Resource
    private ProcessRuntime processRuntime;
    @Resource
    private TaskRuntime taskRuntime;
    @Resource
    private SecurityUtil securityUtil;

    /**
     * 獲取任務,拾取任務,並且執行
     */
    @RequestMapping("/getTask")
    public void getTask(){
        securityUtil.logInAs("salaboy");        //指定組內任務人
        Page<Task> tasks = taskRuntime.tasks(Pageable.of(0, 10));
        if(tasks.getTotalItems()>0){
            for (Task task:tasks.getContent()) {
                System.out.println("任務名稱:"+task.getName());
                //拾取任務
                taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(task.getId()).build());
                //執行任務
                taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(task.getId()).build());
            }
        }
    }
}

2、訪問localhost:8080/activiti/getTask

3、控制台

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM