flowable6.7.2在Spring boot项目中兼容人大金仓

源码分析

根据flowable中文文档的说明可知processEngine流程引擎是通过org.flowable.spring.ProcessEngineFactoryBean工厂类来创建的,因此先把目光聚集到这里

/**
* 这个方法即是生成流程引擎的方法
*/
public ProcessEngine getObject() throws Exception {
        this.configureExternallyManagedTransactions();
        if (this.processEngineConfiguration.getBeans() == null) {
            this.processEngineConfiguration.setBeans(new SpringBeanFactoryProxyMap(this.applicationContext));
        }
        // 显然,引擎室通过配置类的buildProcessEngine方法来创建的
        this.processEngine = this.processEngineConfiguration.buildProcessEngine();
        return this.processEngine;
}

根据上述源码,我们可以把目光转向配置类信息,先来看看配置类的继承结构
在这里插入图片描述

从上图中可以看出蓝色主线标识了主要过程的继承逻辑,buildProcessEngine经过AbstractEngineConfigurationProcessEngineConfigurationProcessEngineConfigurationImplSpringProcessEngineConfiguration;

通过查看3个类的buildProcessEngine的实现,可知引擎对象是先由ProcessEngineConfigurationImpl初始化后再教给SpringProcessEngineConfiguration进行扩展。那就转到ProcessEngineConfigurationImpl的源码中查看。

    // 引擎构建的初次实现
    public ProcessEngine buildProcessEngine() {
        // 初始化工作
        this.init();
        // 根据当前的配置信息初始化引擎实现
        ProcessEngineImpl processEngine = new ProcessEngineImpl(this);
        if (this.handleProcessEngineExecutorsAfterEngineCreate) {
            processEngine.startExecutors();
        }

        if (this.flowable5CompatibilityEnabled && this.flowable5CompatibilityHandler != null) {
            this.commandExecutor.execute(new Command<Void>() {
                public Void execute(CommandContext commandContext) {
                    ProcessEngineConfigurationImpl.this.flowable5CompatibilityHandler.getRawProcessEngine();
                    return null;
                }
            });
        }

        this.postProcessEngineInitialisation();
        return processEngine;
    }
    // init 方法太长,省略部分本次不考虑的因素
    public void init() {
        this.initEngineConfigurations();
        this.initConfigurators();
        ...
        if (this.usingRelationalDatabase) {
           // 如果是关系型数据库,初始化数据源
            this.initDataSource();
        } else {
            this.initNonRelationalDataSource();
        }
        ...

    }

如果仔细看过启动的异常堆栈就知道实际抛出异常的就是 this.initDataSource();这个方法了,那就点进去看看。后续源码就不一个个放了,直接看根本造成问题的AbstractEngineConfiguration.initDatabaseType()方法

// 初始化数据类型
public void initDatabaseType() {
        Connection connection = null;

        try {
            connection = this.dataSource.getConnection();
            DatabaseMetaData databaseMetaData = connection.getMetaData();
            // 获取到数据库名,此处是根据相应驱动中配置来获取到的值,【KingbaseES】
            String databaseProductName = databaseMetaData.getDatabaseProductName();
           ...

            // 根据数据库名获取相应数据库类型
            this.databaseType = this.databaseTypeMappings.getProperty(databaseProductName);
            if (this.databaseType == null) {
                throw new FlowableException("couldn't deduct database type from database product name '" + databaseProductName + "'");
            }
            ...

    }

看到这里基本已经看到跟堆栈最终一致的异常错误了,很明显this.databaseTypeMappings.getProperty(databaseProductName);是获取不到相应的数据库类型,因为databaseTypeMappings是由getDefaultDatabaseTypeMappings()这个静态方法构建的,所以我们的目标就是要重写这个静态方法,一种非常简单方法就是把AbstractEngineConfiguration这个类再相同路径下覆盖一遍重写的时候加上,这也是网上比较多的做法。但我有另一种新的想法。

新的实现

首先先一个类来继承SpringProcessEngineConfiguration保证他们再一个调用过程中

public class CustomEngineConfiguration extends SpringProcessEngineConfiguration {


    /**
     * 构造方法
     * 由于AbstractEngineConfiguration没有提供特定的方法来对databaseTypeMappings属性进行操作,
     * 因此就只能在构造方法中重新赋值
     */
    public CustomEngineConfiguration(){
        super();
        super.databaseTypeMappings = extendDefaultDatabaseTypeMappings();

    }

    /**
     * 扩展原有的getDefaultDatabaseTypeMappings,支持人大金仓
     * @return
     */
    public Properties extendDefaultDatabaseTypeMappings() {
        Properties databaseTypeMappings = getDefaultDatabaseTypeMappings();
        databaseTypeMappings.setProperty("KingbaseES", DATABASE_TYPE_POSTGRES);
        return databaseTypeMappings;
    }

}

这里我们通过扩展getDefaultDatabaseTypeMappings()方法,添加了kingbase的类型支持,并将它覆盖了父类中的databaseTypeMappings属性。那么现在问题来了,怎么能让CustomEngineConfiguration被加载呢,这时候就要把目光放到自动装配上面。查看flowable的自动装配配置文件
在这里插入图片描述

重点就上面圈中的自动配置类,我们可以看到在该配置类中创建了SpringProcessEngineConfiguration并进行了配置,因此我们只要替换这个类并修改SpringProcessEngineConfiguration的构建方法就可以搞定了


/**
* 继承ProcessEngineAutoConfiguration保证原有功能不变
*/
@Configuration
@Primary
public class CustomProcessEngineAutoConfiguration extends ProcessEngineAutoConfiguration {


    public CustomProcessEngineAutoConfiguration(...) {
        super(...);
    }

    /**
     * 重写springProcessEngineConfiguration的类过程,其实整个过程都没有变
     * 只是在构造SpringProcessEngineConfiguration方法的时候构造的是我们自定义的配置类,添加了关于人大金仓的支持
     */
    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    @Bean
    @Primary
    @Override
    public SpringProcessEngineConfiguration springProcessEngineConfiguration(...) throws IOException {
        // 此处替换成构造自己定义的支持人大金仓的配置类
        SpringProcessEngineConfiguration conf = new CustomEngineConfiguration();
       ...

}

只需要以上两个配置类即可解决人大金仓下使用flowable时的启动问题。

新的问题

解决上述问题后我尝试在空的人大金仓数据库中生成flowable相关的表结构,但是依然抛出了异常。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值