activiti 学习之 与SpringBoot整合(Bean方式)

本次整合过程全程使用了Bean方式的配置,因为是初学者,配置可能有问题,还忘指出,感谢感谢感谢

使用到的技术栈:mybatis-plus、springboot、activiti和druid连接池

依赖

// 版本
// springboot                         :'2.4.3', // SpringBoot版本号
// activiti                           :'7.0.0.Beta5',  // activiti 版本
// mybatis                            :'3.5.6',      // mybatis 版本
// mybatisSpringBoot                  :'2.2.0',      // mybatis-spring-boot
// mybatisPlus                        :'3.4.3',    // mybatisPlus 版本
project('anyboot-web') {
    dependencies { // 配置子模块依赖
        compile(project(':anyboot-common')) // 引入其他子模块
        compile('org.springframework.boot:spring-boot-starter-actuator') //引入springboot actuator依赖
        compile('org.springframework.boot:spring-boot-starter-aop') //引入springboot aop相关依赖
//        compile('org.springframework.boot:spring-boot-starter-data-redis')  // redis
        // 引入activiti 依赖
        compile(libraries.'activiti-engine')
        compile(libraries.'activiti-spring')
        // 引入连接mysql的依赖
        compile(libraries.'mysql-connector-java')
        // 引入druid的依赖
        compile(libraries.'druid')
        // 引入mybatis的依赖
        compile(libraries.'mybatis')
        compile(libraries.'mybatis-spring-boot-starter')
        compile(libraries.'mybatis-plus')
        compile(libraries.'fastjson')
    }
}

application.yml 的基本信息

server:
  port: 80  # 配置端口

# 日志配置
logging:
  config: classpath:logback/logback-spring.xml

shiro:
  userNativeSessionManager: true # 允许采用非HTTP的模式进行访问


spring:

  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/study-springboot-activiti
    username: root
    password: 123456
    druid: # druid相关配置
      initial-size: 5 # 初始化连接池大小
      min-idle: 10  # 最小维持的连接池大小
      max-active: 50  # 最大支持的连接池大小
      max-wait: 60000 # 最大等待时间(毫秒)
      time-between-eviction-runs-millis: 60000  # 关闭空闲连接间隔(毫秒)
      min-evictable-idle-time-millis: 30000 # 连接最小生存时间(毫秒)
      validation-query: SELECT 1 FROM dual # 数据库状态检测
      test-while-idle: true # 申请连接的时候检测连接是否有效
      test-on-borrow: false   # 申请连接时检测连接是否有效
      test-on-return: false   # 归还连接时检测连接是否有效
      pool-prepared-statements: false # PSCache缓存
      max-pool-prepared-statement-per-connection-size: 20 # 配置PS缓存


mybatis-plus:
  config-location: classpath:META-INF/mybatis/mybatis.cfg.xml
  type-aliases-package: com.any.entity
  mapper-locations: classpath:META-INF/mybatis/mapper/**/*.xml # 所有的mapper映射文件
  global-config:
    db-config:
      logic-not-delete-value: 0 # 数据删除前
      logic-delete-value: 1 # 数据删除后

druid数据源的配置类

package com.any.config;

import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.filter.logging.Slf4jLogFilter;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.List;

/**
 * DruidDataSourceConfiguration
 *
 * @author 15821
 * @date 13:11 2021/12/11
 */
@Configuration
public class DruidDataSourceConfiguration {

    @Bean("defaultDruidDataSource")
    public DruidDataSource getDruidDataSource(
            @Value("${spring.datasource.driver-class-name}")
                    String driverClassName, // 数据库驱动程序
            @Value("${spring.datasource.url}")
                    String url, // 数据库连接地址
            @Value("${spring.datasource.username}")
                    String username, // 数据库的用户名
            @Value("${spring.datasource.password}")
                    String password, // 数据库的用户名
            @Value("${spring.datasource.druid.initial-size}")
                    int initialSize, // 初始化连接数
            @Value("${spring.datasource.druid.min-idle}")
                    int minIdle, // 最小维持连接数
            @Value("${spring.datasource.druid.max-active}")
                    int maxActive, // 最大连接数
            @Value("${spring.datasource.druid.max-wait}")
                    long maxWait, // 最长等待时间
            @Value("${spring.datasource.druid.time-between-eviction-runs-millis}")
                    long timeBetweenEvictionRunsMillis, // 关闭空闲连接间隔
            @Value("${spring.datasource.druid.min-evictable-idle-time-millis}")
                    long minEvictableIdleTimeMillis, // 最小存活时间
            @Value("${spring.datasource.druid.validation-query}")
                    String validationQuery, // 验证查询
            @Value("${spring.datasource.druid.test-while-idle}")
                    boolean testWhileIdle, // 测试空闲连接是否可用
            @Value("${spring.datasource.druid.test-on-borrow}")
                    boolean testOnBorrow, // 测试后返回连接
            @Value("${spring.datasource.druid.test-on-return}")
                    boolean testOnReturn, // 测试后归还
            @Value("${spring.datasource.druid.pool-prepared-statements}")
                    boolean poolPreparedStatements, // 是否缓存PSTMT
            @Value("${spring.datasource.druid.max-pool-prepared-statement-per-connection-size}")
                    int maxPoolPreparedStatementPerConnectionSize,   // PSTMT缓存个数
            @Autowired Slf4jLogFilter slf4jLogFilter
    ) {
        DruidDataSource dataSource = new DruidDataSource(); // 实例化DataSource子类对象
        dataSource.setDriverClassName(driverClassName); // 数据库驱动程序
        dataSource.setUrl(url); // 数据库的连接地址
        dataSource.setUsername(username); // 数据库用户名
        dataSource.setPassword(password); // 数据库密码
        dataSource.setInitialSize(initialSize); // 连接池初始化大小
        dataSource.setMinIdle(minIdle); // 最小维持的连接数量
        dataSource.setMaxActive(maxActive); // 最大的连接数量
        dataSource.setMaxWait(maxWait); // 最大等待时间
        dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); // 检查的间隔时间
        dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); // 存活时间
        dataSource.setValidationQuery(validationQuery); // 验证SQL
        dataSource.setTestWhileIdle(testWhileIdle); // 测试连接是否可用
        dataSource.setTestOnBorrow(testOnBorrow); // 获取时检测
        dataSource.setTestOnReturn(testOnReturn); // 归还时检测
        dataSource.setPoolPreparedStatements(poolPreparedStatements); // 是否缓存PSTMT
        dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize); // 缓存个数
        List<Filter> filterList = new ArrayList<>();
        filterList.add(slf4jLogFilter);
        dataSource.setProxyFilters(filterList);
        return dataSource;
    }

    /**
     * Druid 日志监控配置类
     *
     * @author nni
     * @date 10:24 2021/10/25
     */
    @Bean("logFilter")
    public Slf4jLogFilter getLogFilter(){
        Slf4jLogFilter slf4jLogFilter = new Slf4jLogFilter();
        slf4jLogFilter.setDataSourceLogEnabled(true);
        slf4jLogFilter.setStatementExecuteAfterLogEnabled(true);
        return slf4jLogFilter;
    }
}

mybatis-plus的配置类

    package com.any.config;

    import com.baomidou.mybatisplus.annotation.DbType;
    import com.baomidou.mybatisplus.core.config.GlobalConfig;
    import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
    import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
    import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
    import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.io.Resource;
    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    import org.springframework.core.io.support.ResourcePatternResolver;
    import javax.sql.DataSource;

    /**
     * 单数据源,mybatisplus 配置
     *
     * @author nni
     * @date 14:57 2021/10/25
     */
    @Configuration
    public class MybatisPlusConfig {

        private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();

        @Bean
        public MybatisPlusInterceptor getMybatisPlusInterceptor(){ // 创建分页拦截器
            MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
            mybatisPlusInterceptor.addInnerInterceptor(
                    new PaginationInnerInterceptor(DbType.MYSQL)
            );
            return  mybatisPlusInterceptor;
        }

        @Bean("mybatisSqlSessionFactoryBean")
        public MybatisSqlSessionFactoryBean getMybatisSqlSessionFactoryBean(
                @Autowired DataSource dataSource,   // 配置数据源
                @Value("${mybatis-plus.config-location}")Resource configLocaltion, // 配置 mybatis.xml 位置
                @Value("${mybatis-plus.type-aliases-package}") String typeAliasesPackage,  // 配置需要扫描的实体
                @Value("${mybatis-plus.mapper-locations}") String mapperLocations, // 配置mapper文件
                @Value("${mybatis-plus.global-config.db-config.logic-not-delete-value}") String logicNotDeleteValue,// 配置逻辑删除前
                @Value("${mybatis-plus.global-config.db-config.logic-delete-value}") String logicDeleteValue // 配置逻辑删除后
        ) throws Exception {
            MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean();
            factoryBean.setDataSource(dataSource);// 配置数据源
            factoryBean.setVfs(SpringBootVFS.class);    //配置程序的扫描类
            factoryBean.setConfigLocation(configLocaltion);
            factoryBean.setTypeAliasesPackage(typeAliasesPackage);// 配置需要扫描的实体
            Resource[] mappings = this.resourcePatternResolver.getResources(mapperLocations);
            factoryBean.setMapperLocations(mappings);
            GlobalConfig.DbConfig dbConfig = new GlobalConfig.DbConfig();
            dbConfig.setLogicNotDeleteValue(logicNotDeleteValue);// 配置逻辑删除前
            dbConfig.setLogicDeleteField(logicDeleteValue);// 配置逻辑删除后
            GlobalConfig globalConfig = new GlobalConfig();
            globalConfig.setDbConfig(dbConfig); // 注入 dbConfig
            factoryBean.setGlobalConfig(globalConfig); // 注入 globalConfig
            return factoryBean;
        }


    }

事务的配置

package com.any.config;

import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
import org.springframework.transaction.interceptor.TransactionAttribute;
import org.springframework.transaction.interceptor.TransactionInterceptor;

import java.util.HashMap;
import java.util.Map;

/**
 * 事务处理类
 * @return
 * @throws
 * @update 2021-11-01 10:42 by 15821
 */
@Configuration
public class TransactionConfig { // 事务配置类
    private static final int TRANSACTION_METHOD_TIMEOUT = 5; // 事务处理的超时时间
    private static final String AOP_POINTCUT_EXPRESSION = "execution (* com.any..service.*.*(..))";
    @Autowired
    private TransactionManager transactionManager; // 事务管理器
    @Bean("txAdvice")
    public TransactionInterceptor transactionInterceptorConfig() {
        // 配置数据读取事务规则
        RuleBasedTransactionAttribute readOnlyAttribute = new RuleBasedTransactionAttribute();
        readOnlyAttribute.setReadOnly(true); // 只读事务
        readOnlyAttribute.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED); // 非事务运行
        // 配置了数据更新事务规则
        RuleBasedTransactionAttribute requiredAttribute = new RuleBasedTransactionAttribute();
        requiredAttribute.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); // 事务开启
        requiredAttribute.setTimeout(TRANSACTION_METHOD_TIMEOUT); // 事务处理超时时间
        // 配置所有要进行事务处理的方法名称定义
        Map<String, TransactionAttribute> transactionAttributeMap = new HashMap<>();
        transactionAttributeMap.put("add*", requiredAttribute);
        transactionAttributeMap.put("edit*", requiredAttribute);
        transactionAttributeMap.put("delete*", requiredAttribute);
        transactionAttributeMap.put("list*", readOnlyAttribute);
        transactionAttributeMap.put("get*", readOnlyAttribute);
        NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
        source.setNameMap(transactionAttributeMap); // 配置方法名称的映射
        TransactionInterceptor interceptor = new TransactionInterceptor(transactionManager, source);
        return interceptor;
    }
    @Bean("txAdvisor")
    public Advisor transactionAdvisor(
            @Autowired @Qualifier("txAdvice") TransactionInterceptor interceptor
    ) {
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
        return new DefaultPointcutAdvisor(pointcut, interceptor);
    }
}

Activiti的配置

package com.any.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.spring.ProcessEngineFactoryBean;
import org.activiti.spring.SpringProcessEngineConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.transaction.PlatformTransactionManager;

import java.io.IOException;

/**
 * ActivitiConfiguration
 *
 * @author 15821
 */
@Configuration
public class ActivitiConfiguration {

    @Autowired
    @Qualifier("defaultDruidDataSource")
    private DruidDataSource druidDataSource;


    @Autowired
    private PlatformTransactionManager platformTransactionManager;

    /**
     * 注册 activiti的配置信息
     */
    @Bean("processEngineConfiguration")
    public SpringProcessEngineConfiguration getProcessEngineConfiguration(){
        SpringProcessEngineConfiguration configuration
                = new SpringProcessEngineConfiguration();
        configuration.setDataSource(druidDataSource);       // 添加数据源
        configuration.setTransactionManager(platformTransactionManager);    // 添加事务
        configuration.setDatabaseSchemaUpdate("true");  // 如果有表则不创建
        configuration.setDbHistoryUsed(true);   // 允许查看历史信息
        
        // 自动部署 bpmn文件
        Resource[] resources = null;
        try {
            resources= new PathMatchingResourcePatternResolver().getResources("classpath*:bpmn/*.bpmn");
        } catch (IOException e) {
            e.printStackTrace();
        }
        configuration.setDeploymentResources(resources);
        return configuration;
    }


    /**
     * 注册 ProcessEngineFactoryBean
     */
    @Bean
    public ProcessEngineFactoryBean processEngine(){
        ProcessEngineFactoryBean factoryBean = new ProcessEngineFactoryBean();
        factoryBean.setProcessEngineConfiguration(getProcessEngineConfiguration());
        return factoryBean;
    }

    /**
     * 注册 RepositoryService
     */
    @Bean
    public RepositoryService repositoryService() throws Exception{
        return processEngine().getObject().getRepositoryService();
    }

    /**
     * 注册 RuntimeService
     */
    @Bean
    public RuntimeService runtimeService() throws Exception{
        return processEngine().getObject().getRuntimeService();
    }

    /**
     * 注册 TaskService
     */
    @Bean
    public TaskService taskService() throws Exception{
        return processEngine().getObject().getTaskService();
    }

    /**
     * 注册 HistoryService
     */
    @Bean
    public HistoryService historyService() throws Exception{
        return processEngine().getObject().getHistoryService();
    }
}

测试

        开始流程

    @Autowired
    private RuntimeService runtimeService;

    /**
     * 测试启动流程
     *
     * @update 2021-12-11 17:17 by 15821
     */
    @RequestMapping("startProcess")
    public ServerResponse testStartProcess() {
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key);

        return ServerResponse.createBySuccess(processInstance.getId());

    }

        查看个人任务

    /**
     * 查看个人任务
     *
     * @update 2021-12-11 17:17 by 15821
     */
    @RequestMapping("queryTask")
    public ServerResponse testQueryPersonalTask(String assigness) {
        // 流程实例 的KEY
        System.out.println(assigness);
        Task task = taskService.createTaskQuery()
                .processDefinitionKey(key)
                .taskAssignee(assigness)
                .singleResult();
        return ServerResponse.createBySuccess(
                Map.of("流程实例id", task.getProcessInstanceId()
                        , "任务id", task.getId()
                        , "任务负责人", task.getAssignee()
                )
        );
    }

        查看组任务

    /**
     * 查看组任务
     *
     * @update 2021-12-11 17:17 by 15821
     */
    @RequestMapping("queryGroupTask")
    public ServerResponse testQueryGroupTask(String candidateUser) {
        Task task = taskService.createTaskQuery()
                .processDefinitionKey(key)
                .taskCandidateUser(candidateUser)
                .singleResult();
        System.out.println("流程实例的ID:"+task.getProcessInstanceId());
        System.out.println("任务ID:"+task.getId());
        System.out.println("任务负责人:"+task.getAssignee());
        return ServerResponse.createBySuccess(
                Map.of("流程实例的ID",task.getProcessInstanceId()
                        ,"任务Id",task.getId()));
    }

        拾取任务

    /**
     * 拾取任务
     *
     * @update 2021-12-11 17:17 by 15821
     */
    @RequestMapping("chaim")
    public ServerResponse testClaimTask(String taskId, String candidateUser) {
        taskService.claim(taskId,candidateUser);
        return ServerResponse.createBySuccess("taskId : " + taskId + "、用户:'" +         candidateUser + "'拾取任务成功");
    }

        完成任务

    /**
     * 完成任务
     *
     * @update 2021-12-11 17:17 by 15821
     */
    @RequestMapping("complete")
    public ServerResponse testComplete(String assigness) {
        List<Task> tasks = taskService.createTaskQuery()
                .processDefinitionKey("evectionGroup")
                .taskAssignee(assigness)
                .list();
        for (Task task : tasks){
            taskService.complete(task.getId());
        }

        return ServerResponse.createBySuccess("、用户:'" + assigness + "'完成任务");
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

倪家李子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值