美文网首页
spring boot 2.2 + Activiti 7 + J

spring boot 2.2 + Activiti 7 + J

作者: 风中吃西瓜 | 来源:发表于2019-11-20 13:53 被阅读0次

    项目中分为了2个数据库 Activiti 数据库和 业务数据库 下面直接上代码

    • pom.xml
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
            <activiti-dependencies.version>7.1.0.M4</activiti-dependencies.version>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
            <skipTests>true</skipTests>
        </properties>
    
        <!-- 引入Activiti相关依赖 -->
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.activiti.dependencies</groupId>
                    <artifactId>activiti-dependencies</artifactId>
                    <version>${activiti-dependencies.version}</version>
                    <scope>import</scope>
                    <type>pom</type>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
            <dependency>
                <groupId>org.activiti</groupId>
                <artifactId>activiti-spring-boot-starter</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-data-jpa</artifactId>
          </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
        
        </dependencies>
    
    • application.yml
    spring:
      datasource:
        druid:
          master:
            # 业务数据库
            type: com.alibaba.druid.pool.DruidDataSource
            driver-class-name: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://127.0.0.1:3306/manage_test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=CTT&rewriteBatchedStatements=true&autoReconnect=true&failOverReadOnly=false
            username: root
            password: root@123
          activiti:
            # Activiti 数据库
            type: com.alibaba.druid.pool.DruidDataSource
            driver-class-name: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://127.0.0.1:3306/activiti_test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=CTT&rewriteBatchedStatements=true&autoReconnect=true&failOverReadOnly=false&allowMultiQueries=true&nullCatalogMeansCurrent=true
            # url换为jdbc-url 解决jdbcUrl is required with driverClassName错误
            jdbc-url: ${spring.datasource.druid.activiti.url}
            username: root
            password: root@123
    
          # 连接池配置
          # 初始化大小,最小,最大
          initial-size: 10
          min-idle: 10
          max-active: 20
          # 配置一个连接在池中最小生存的时间,单位是毫秒
          min-evictable-idle-time-millis: 300000
         # max-evictable-idle-time-millis: 600000
          max-open-prepared-statements: 60000
          # 打开PSCache,并且指定每个连接上PSCache的大小
          pool-prepared-statements: true
          max-pool-prepared-statement-per-connection-size: 20
          #最大等待超时时间
          max-wait: 60000
          test-on-borrow: false
          test-on-return: false
          test-while-idle: true
          # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
          time-between-eviction-runs-millis: 60000
          validation-query: SELECT 1 FROM DUAL
          validation-query-timeout: 60000
          query-timeout: 60000
          transaction-threshold-millis: 60000
          remove-abandoned-timeout-millis: 30000
          # 配置监控统计拦截的filters,采用log4j2作为日志实现
          filters: stat,wall,log4j2
          # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
          connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
          # 合并多个DruidDataSource的监控数据
          use-global-data-source-stat: true
          # 监控配置 WebStatFilter配置
          web-stat-filter:
            enabled: true
            exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'
            principal-cookie-name: admin
            principal-session-name: admin
            profile-enable: true
            session-stat-enable: false
            session-stat-max-count: 1000
            url-pattern: '/*'
          stat-view-servlet:
            # IP 白名单
            allow: 127.0.0.1
            #  IP黑名单(共同存在时,deny优先于allow)
            deny: 192.168.0.10
            enabled: true
            # 控制台用户名和密码
            login-password: admin
            login-username: admin
            reset-enable: false
            url-pattern: '/druid/*'
          # 配置日志输出
          filter:
            slf4j:
              enabled: true
              statement-create-after-log-enabled: false
              statement-close-after-log-enabled: false
              result-set-open-after-log-enabled: false
            stat:
              #慢查询
              log-slow-sql: true
              #慢查询时长,默认3秒
              slow-sql-millis: 1000
              merge-sql: false
            wall:
              config:
                multi-statement-allow: true
    
      # jta atomikos 配置
      jta:
        atomikos:
          datasource:
            min-pool-size: 10
            max-pool-size: 20
            borrow-connection-timeout: 60
          connectionfactory:
            min-pool-size: 10
            max-pool-size: 20
            borrow-connection-timeout: 60
     jpa:
        open-in-view: true
        database: MYSQL
        generate-ddl: true
        show-sql: true
        database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
        hibernate:
          ddl-auto: update
          # update:表示自动根据model对象来更新表结构,启动 hibernate 时会自动检查数据库,如果缺少表则自动建表;缺少列则自动添加列;
          # create: 启动hibernate时,自动删除原来的表,新建所有的表,所以每次启动后的以前数据都会丢失。
          # create-drop:应用停下来的时候,自动会把表和数据删掉、
          # none: 什么也不做;
          # validate:会验证类里的属性和表字段是否一致,不一致,则会报错;
          naming:
            physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy    # 策略会有大小写区别 在进行领域映射时,首字母小写,大写字母变为下划线加小写 自动根据实体类重新生成表时(实体类即使配置了@Table 如果大小写不匹配也会生成表) 表名和字段都为小写
        properties:
            hibernate:
                format_sql: true
    
      activiti:
        # 数据源指定
        database-schema: ACTIVITI
        # 建表规则: 服务启动时检查数据库表,不存在则创建
        database-schema-update: true
        # 表示哪种情况下使用历史表,这里配置为all表示全部记录历史,方便绘制流程图; 记录历史等级 可配置的历史级别有none, acitivity, audit, full
        history-level: full
        # 表示使用历史表,如果不配置,则工程启动后可以检查数据库
        db-history-used: true
        # spring jpa使用
        jpa-enabled: true
        # 暂时不检查
        check-process-definitions: false
    
    
    • 业务数据库 数据源配置
    /***
     * 文件名称: JpaRepositoriesConfig.java
     * 文件描述: 默认数据源 主库持久化配置
     * 公 司:
     * 内容摘要:
     * 其他说明:  @EnableTransactionManagement  开启注解事物  
     *             @EnableJpaRepositories 开启JPA存储库扫描
     *            @EntityScan 配置 实体类所在的路径  解决: Not a managed type:
     * 完成日期:
     * 修改记录:
     * @version 1.0
     * @author 
     */
    @Configuration
    @DependsOn("transactionManager")
    @EntityScan(basePackages = {"test.base.entity"})
    @EnableJpaRepositories(basePackages = {"test.base.repository.jpa"},
            entityManagerFactoryRef = "masterEntityManager", transactionManagerRef = "transactionManager")
    public class JpaRepositoriesConfig {
    
        @Autowired
        private JpaVendorAdapter jpaVendorAdapter;
    
        @Autowired
        private JpaProperties jpaProperties;
    
        @Autowired
        private HibernateProperties hibernateProperties;
    
        @Bean("masterDruidDataSource")
        @ConfigurationProperties(prefix = "spring.datasource.druid.master")
        public DruidDataSource masterDruidDataSource() {
            return new DruidDataSource();
        }
    
        /**
         * 默认数据库
         * @return
         */
        @Primary
        @Bean(name = "dataSource", initMethod = "init", destroyMethod = "close")
        public DataSource masterDataSource() throws SQLException {
            DruidDataSource dataSourceProperties = masterDruidDataSource();
            MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
            mysqlXaDataSource.setUrl(dataSourceProperties.getUrl());
            mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
            mysqlXaDataSource.setUser(dataSourceProperties.getUsername());
            mysqlXaDataSource.setPassword(dataSourceProperties.getPassword());
            AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
            xaDataSource.setXaDataSource(mysqlXaDataSource);
            xaDataSource.setUniqueResourceName("masterDataSource");
            xaDataSource.setBorrowConnectionTimeout(60);
            xaDataSource.setMaxIdleTime(60);
            xaDataSource.setMaxPoolSize(dataSourceProperties.getMaxActive());
            xaDataSource.setMinPoolSize(dataSourceProperties.getMinIdle());
            return xaDataSource;
    
        }
    
        /**
         * 默认数据源事物配置
         * @return
         * @throws Throwable
         */
        @Primary
        @Bean(name = "masterEntityManager")
        @DependsOn("transactionManager")
        public LocalContainerEntityManagerFactoryBean masterEntityManager() throws Throwable {
            HashMap<String, Object> properties = new HashMap<String, Object>();
            // 标注transaction是JTA和JTA平台是AtomikosJtaPlatform.class.getName()
            properties.put("hibernate.transaction.jta.platform", AtomikosJtaPlatform.class.getName());
            properties.put("javax.persistence.transactionType", "JTA");
            LocalContainerEntityManagerFactoryBean entityManager = new LocalContainerEntityManagerFactoryBean();
            entityManager.setJtaDataSource(masterDataSource());
            entityManager.setJpaVendorAdapter(jpaVendorAdapter);
            entityManager.setPackagesToScan("pers.liujunyi.cloud.photo.entity", "pers.liujunyi.cloud.security.entity");
            entityManager.setPersistenceUnitName("masterPersistenceUnit");
            // 设置jpa属性  使用 hibernateProperties.determineHibernateProperties(properties, new HibernateSettings()) 解决不按照配置的JPA 命令策略生成表的问题
            entityManager.setJpaPropertyMap(hibernateProperties.determineHibernateProperties(properties, new
                    HibernateSettings()));
            return entityManager;
        }
    
    }
    
    
    • Activiti 数据库 数据源配置
    /***
     * 文件名称: ActivitiConfig.java
     * 文件描述:  Activiti 据源配置
     * 公 司:
     * 内容摘要:
     * 其他说明:
     *   @EnableTransactionManagement  开启注解事物  
     *   @EnableJpaRepositories 开启JPA存储库扫描
     * 完成日期:
     * 修改记录:
     * @version 1.0
     * @author 
     */
    @Configuration
    @DependsOn("transactionManager")
    @EntityScan(basePackages = {"test.activiti.entity"})
    @EnableJpaRepositories(basePackages = {"test..activiti.repository"},
            entityManagerFactoryRef = "activitiEntityManager", transactionManagerRef = "transactionManager")
    public class ActivitiDataSourceConfig extends AbstractProcessEngineAutoConfiguration {
    
        @Autowired
        private JpaVendorAdapter jpaVendorAdapter;
    
    
    
        @Bean("activitiDruidDataSource")
        @ConfigurationProperties(prefix = "spring.datasource.druid.activiti")
        public DruidDataSource activitiDruidDataSource() {
            return new DruidDataSource();
        }
    
        /**
         * Activiti 数据源
         * @return
         */
        @Bean(name = "activitiDataSource", initMethod = "init", destroyMethod = "close")
        public DataSource activitiDataSource() throws SQLException {
            DruidDataSource dataSourceProperties = activitiDruidDataSource();
            MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
            mysqlXaDataSource.setUrl(dataSourceProperties.getUrl());
            mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
            mysqlXaDataSource.setUser(dataSourceProperties.getUsername());
            mysqlXaDataSource.setPassword(dataSourceProperties.getPassword());
            AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
            xaDataSource.setXaDataSource(mysqlXaDataSource);
            xaDataSource.setUniqueResourceName("activitiDataSource");
            xaDataSource.setBorrowConnectionTimeout(60);
            xaDataSource.setMaxIdleTime(60);
            xaDataSource.setMaxPoolSize(dataSourceProperties.getMaxActive());
            xaDataSource.setMinPoolSize(dataSourceProperties.getMinIdle());
            return xaDataSource;
    
        }
    
        /**
         *
         * @return
         * @throws Throwable
         */
        @Bean(name = "activitiEntityManager")
        @DependsOn("transactionManager")
        public LocalContainerEntityManagerFactoryBean masterEntityManager() throws IOException, SQLException  {
            HashMap<String, Object> properties = new HashMap<>();
            // 标注transaction是JTA和JTA平台是AtomikosJtaPlatform.class.getName()
            properties.put("hibernate.transaction.jta.platform", AtomikosJtaPlatform.class.getName());
            properties.put("javax.persistence.transactionType", "JTA");
            LocalContainerEntityManagerFactoryBean entityManager = new LocalContainerEntityManagerFactoryBean();
            entityManager.setJtaDataSource(activitiDataSource());
            entityManager.setJpaVendorAdapter(jpaVendorAdapter);
            entityManager.setPackagesToScan("pers.liujunyi.cloud.activiti.entity");
            entityManager.setPersistenceUnitName("activitiPersistenceUnit");
            entityManager.setJpaPropertyMap(properties);
            return entityManager;
        }
    
    
        /**
         *  注入数据源和事务管理器
         *  这段代码很重要,如果没有这段代码无法初始化 activitiDataSource
         * @param transactionManager
         * @param springAsyncExecutor
         * @param activitiProperties
         * @param processDefinitionResourceFinder
         * @param processEngineConfigurationConfigurer
         * @param processEngineConfigurators
         * @param userGroupManager
         * @return
         * @throws IOException
         */
        @Bean
        public SpringProcessEngineConfiguration springProcessEngineConfiguration(
                PlatformTransactionManager transactionManager,
                SpringAsyncExecutor springAsyncExecutor,
                ActivitiProperties activitiProperties,
                ProcessDefinitionResourceFinder processDefinitionResourceFinder,
                @Autowired(required = false) DefaultActivityBehaviorFactoryMappingConfigurer processEngineConfigurationConfigurer,
                @Autowired(required = false) List<ProcessEngineConfigurator> processEngineConfigurators,
                UserGroupManager userGroupManager) throws IOException, SQLException {
    
            SpringProcessEngineConfiguration processEngineConfiguration = new SpringProcessEngineConfiguration();
            processEngineConfiguration.setConfigurators(processEngineConfigurators);
            configureProcessDefinitionResources(processDefinitionResourceFinder, processEngineConfiguration);
            processEngineConfiguration.setDataSource(activitiDataSource());
            processEngineConfiguration.setTransactionManager(transactionManager);
            if (springAsyncExecutor != null) {
                processEngineConfiguration.setAsyncExecutor(springAsyncExecutor);
            }
            processEngineConfiguration.setDeploymentName(activitiProperties.getDeploymentName());
            processEngineConfiguration.setDatabaseSchema(activitiProperties.getDatabaseSchema());
            processEngineConfiguration.setDatabaseSchemaUpdate(activitiProperties.getDatabaseSchemaUpdate());
            processEngineConfiguration.setDbHistoryUsed(activitiProperties.isDbHistoryUsed());
            processEngineConfiguration.setAsyncExecutorActivate(activitiProperties.isAsyncExecutorActivate());
            if (!activitiProperties.isAsyncExecutorActivate()) {
                ValidatorSet springBootStarterValidatorSet = new ValidatorSet("activiti-spring-boot-starter");
                springBootStarterValidatorSet.addValidator(new AsyncPropertyValidator());
                if (processEngineConfiguration.getProcessValidator() == null) {
                    ProcessValidatorImpl processValidator = new ProcessValidatorImpl();
                    processValidator.addValidatorSet(springBootStarterValidatorSet);
                    processEngineConfiguration.setProcessValidator(processValidator);
                } else {
                    processEngineConfiguration.getProcessValidator().getValidatorSets().add(springBootStarterValidatorSet);
                }
            }
            processEngineConfiguration.setMailServerHost(activitiProperties.getMailServerHost());
            processEngineConfiguration.setMailServerPort(activitiProperties.getMailServerPort());
            processEngineConfiguration.setMailServerUsername(activitiProperties.getMailServerUserName());
            processEngineConfiguration.setMailServerPassword(activitiProperties.getMailServerPassword());
            processEngineConfiguration.setMailServerDefaultFrom(activitiProperties.getMailServerDefaultFrom());
            processEngineConfiguration.setMailServerUseSSL(activitiProperties.isMailServerUseSsl());
            processEngineConfiguration.setMailServerUseTLS(activitiProperties.isMailServerUseTls());
    
            if (userGroupManager != null) {
                processEngineConfiguration.setUserGroupManager(userGroupManager);
            }
    
            processEngineConfiguration.setHistoryLevel(activitiProperties.getHistoryLevel());
            processEngineConfiguration.setCopyVariablesToLocalForTasks(activitiProperties.isCopyVariablesToLocalForTasks());
            processEngineConfiguration.setSerializePOJOsInVariablesToJson(activitiProperties.isSerializePOJOsInVariablesToJson());
            processEngineConfiguration.setJavaClassFieldForJackson(activitiProperties.getJavaClassFieldForJackson());
    
            if (activitiProperties.getCustomMybatisMappers() != null) {
                processEngineConfiguration.setCustomMybatisMappers(
                        getCustomMybatisMapperClasses(activitiProperties.getCustomMybatisMappers()));
            }
    
            if (activitiProperties.getCustomMybatisXMLMappers() != null) {
                processEngineConfiguration.setCustomMybatisXMLMappers(
                        new HashSet<>(activitiProperties.getCustomMybatisXMLMappers()));
            }
    
            if (activitiProperties.getCustomMybatisXMLMappers() != null) {
                processEngineConfiguration.setCustomMybatisXMLMappers(
                        new HashSet<>(activitiProperties.getCustomMybatisXMLMappers()));
            }
    
            if (activitiProperties.isUseStrongUuids()) {
                processEngineConfiguration.setIdGenerator(new StrongUuidGenerator());
            }
    
            if (activitiProperties.getDeploymentMode() != null) {
                processEngineConfiguration.setDeploymentMode(activitiProperties.getDeploymentMode());
            }
    
            processEngineConfiguration.setActivityBehaviorFactory(new DefaultActivityBehaviorFactory());
    
            if (processEngineConfigurationConfigurer != null) {
                processEngineConfigurationConfigurer.configure(processEngineConfiguration);
            }
    
            return processEngineConfiguration;
        }
    
        private void configureProcessDefinitionResources(
                ProcessDefinitionResourceFinder processDefinitionResourceFinder,
                SpringProcessEngineConfiguration conf) throws IOException {
            List<Resource> procDefResources = processDefinitionResourceFinder
                    .discoverProcessDefinitionResources();
            if (!procDefResources.isEmpty()) {
                conf.setDeploymentResources(procDefResources.toArray(new Resource[0]));
            }
        }
    
    }
    
    • atomikos的jta
    public class AtomikosJtaPlatform extends AbstractJtaPlatform {
    
        private static final long serialVersionUID = 8601225157421131143L;
    
        static TransactionManager transactionManager;
        static UserTransaction transaction;
    
        @Override
        protected TransactionManager locateTransactionManager() {
            return transactionManager;
        }
    
        @Override
        protected UserTransaction locateUserTransaction() {
            return transaction;
        }
    }
    
    • 数据源事物管理配置
    @Configuration
    @ComponentScan
    @EnableTransactionManagement(proxyTargetClass = true)
    public class DataSourceTransactionManagerConfig {
    
        /**
         * 事物超时时间  (秒)
         */
        @Value("${spring.datasource.druid.transaction-threshold-millis}")
        private Integer transactionTimeOut;
    
        @Bean
        public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
            return new PropertySourcesPlaceholderConfigurer();
        }
    
    
        /**
         * 设置JPA特性
         * @return
         */
        @Bean
        public JpaVendorAdapter jpaVendorAdapter() {
            HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
            //显示sql
            hibernateJpaVendorAdapter.setShowSql(true);
            //自动生成/更新表
            hibernateJpaVendorAdapter.setGenerateDdl(true);
            //设置数据库类型
            hibernateJpaVendorAdapter.setDatabase(Database.MYSQL);
            return hibernateJpaVendorAdapter;
        }
    
        @Bean(name = "userTransaction")
        public UserTransaction userTransaction() throws Throwable {
            UserTransactionImp userTransactionImp = new UserTransactionImp();
            userTransactionImp.setTransactionTimeout(60000);
            return userTransactionImp;
        }
    
        @Bean(name = "atomikosTransactionManager", initMethod = "init", destroyMethod = "close")
        public TransactionManager atomikosTransactionManager() throws Throwable {
            UserTransactionManager userTransactionManager = new UserTransactionManager();
            userTransactionManager.setForceShutdown(false);
            userTransactionManager.setTransactionTimeout(60000);
            AtomikosJtaPlatform.transactionManager = userTransactionManager;
            return userTransactionManager;
        }
    
        @Bean(name = "transactionManager")
        @DependsOn({"userTransaction", "atomikosTransactionManager"})
        public PlatformTransactionManager transactionManager() throws Throwable {
            UserTransaction userTransaction = userTransaction();
            AtomikosJtaPlatform.transaction = userTransaction;
            TransactionManager atomikosTransactionManager = atomikosTransactionManager();
            return new JtaTransactionManager(userTransaction, atomikosTransactionManager);
        }
    
    }
    
    
    • 启动项目 Activiti 数据库 自动生成 25张表


      image.png

    如果启动项目没有自动生成数据库表 请检查数据库连接地址配置中是否有nullCatalogMeansCurrent=true 配置

    相关文章

      网友评论

          本文标题:spring boot 2.2 + Activiti 7 + J

          本文链接:https://www.haomeiwen.com/subject/siprbctx.html