Flowable源码注释(四)引擎配置抽象类

Flowable源码地址:https://github.com/flowable/flowable-engine

AbstractEngineConfiguration引擎配置抽象类

public abstract class AbstractEngineConfiguration {
   

    protected final Logger logger = LoggerFactory.getLogger(getClass());

    /** 表示“无租户”的租户id */
    public static final String NO_TENANT_ID = "";

    /**
     * 在创建表单引擎时,对照库检查DB模式的版本,如果版本不匹配,则引发异常。
     */
    public static final String DB_SCHEMA_UPDATE_FALSE = "false";
    public static final String DB_SCHEMA_UPDATE_CREATE = "create";
    public static final String DB_SCHEMA_UPDATE_CREATE_DROP = "create-drop";

    /**
     * 在创建表单引擎时创建模式,在关闭表单引擎时删除模式.
     */
    public static final String DB_SCHEMA_UPDATE_DROP_CREATE = "drop-create";

    /**
     * 构建流程引擎后,将执行检查,并在必要时更新模式.
     */
    public static final String DB_SCHEMA_UPDATE_TRUE = "true";

    protected boolean forceCloseMybatisConnectionPool = true;

    protected String databaseType;
    protected String jdbcDriver = "org.h2.Driver";
    protected String jdbcUrl = "jdbc:h2:tcp://localhost/~/flowable";
    protected String jdbcUsername = "sa";
    protected String jdbcPassword = "";
    protected String dataSourceJndiName;
    protected int jdbcMaxActiveConnections = 16;
    protected int jdbcMaxIdleConnections = 8;
    protected int jdbcMaxCheckoutTime;
    protected int jdbcMaxWaitTime;
    protected boolean jdbcPingEnabled;
    protected String jdbcPingQuery;
    protected int jdbcPingConnectionNotUsedFor;
    protected int jdbcDefaultTransactionIsolationLevel;
    protected DataSource dataSource;
    protected SchemaManager commonSchemaManager;
    protected SchemaManager schemaManager;
    protected Command<Void> schemaManagementCmd;

    protected String databaseSchemaUpdate = DB_SCHEMA_UPDATE_FALSE;

    /**
     * 执行数据库模式创建或更新操作时是否使用锁.
     */
    protected boolean useLockForDatabaseSchemaUpdate = false;

    protected String xmlEncoding = "UTF-8";

    // 命令执行器 ///

    protected CommandExecutor commandExecutor;
    protected Collection<? extends CommandInterceptor> defaultCommandInterceptors;
    protected CommandConfig defaultCommandConfig;
    protected CommandConfig schemaCommandConfig;
    protected CommandContextFactory commandContextFactory;
    protected CommandInterceptor commandInvoker;

    protected AgendaOperationRunner agendaOperationRunner = (commandContext, runnable) -> runnable.run();

    protected List<CommandInterceptor> customPreCommandInterceptors;
    protected List<CommandInterceptor> customPostCommandInterceptors;
    protected List<CommandInterceptor> commandInterceptors;

    protected Map<String, AbstractEngineConfiguration> engineConfigurations = new HashMap<>();
    protected Map<String, AbstractServiceConfiguration> serviceConfigurations = new HashMap<>();

    protected ClassLoader classLoader;
    /**
     * 使用Clas.forname方法或者ClassLoader.loadClass方法加载类。查看http://forums.activiti.org/content/reflectutilloadclass-and-custom- classloader
     */
    protected boolean useClassForNameClassLoading = true;

    protected List<EngineLifecycleListener> engineLifecycleListeners;

    // 事件注册 //
    protected Map<String, EventRegistryEventConsumer> eventRegistryEventConsumers = new HashMap<>();

    // MYBATIS SQL SESSION 工厂 /

    protected boolean isDbHistoryUsed = true;
    protected DbSqlSessionFactory dbSqlSessionFactory;
    protected SqlSessionFactory sqlSessionFactory;
    protected TransactionFactory transactionFactory;
    protected TransactionContextFactory transactionContextFactory;

    /**
     * 如果设置为true,则启用批量插入(将sql插入分组在一起)。默认为true.
     * 对于某些数据库(例如DB2+z/OS),需要将其设置为false.
     */
    protected boolean isBulkInsertEnabled = true;

    /**
     * 一些数据库对一条sql insert的参数有限制(例如sql Server,最多2000个参数(不等于插入语句))。如果异常很多时,请调整此参数
     * 放入到一个大容量插入中,或者如果数据库能够处理,并且有大量数据需要插入,则将其提高.
     * 默认情况下:100(mssql server为55,因为它在语句中有2000个参数的硬限制)
     */
    protected int maxNrOfStatementsInBulkInsert = 100;

    public int DEFAULT_MAX_NR_OF_STATEMENTS_BULK_INSERT_SQL_SERVER = 55; // 目前执行的参数最多(35). 2000 / 35 = 57.

    protected String mybatisMappingFile;
    protected Set<Class<?>> customMybatisMappers;
    protected Set<String> customMybatisXMLMappers;
    protected List<Interceptor> customMybatisInterceptors;

    protected Set<String> dependentEngineMyBatisXmlMappers;
    protected List<MybatisTypeAliasConfigurator> dependentEngineMybatisTypeAliasConfigs;
    protected List<MybatisTypeHandlerConfigurator> dependentEngineMybatisTypeHandlerConfigs;

    // SESSION 工厂 ///
    protected List<SessionFactory> customSessionFactories;
    protected Map<Class<?>, SessionFactory> sessionFactories;

    protected boolean enableEventDispatcher = true;
    protected FlowableEventDispatcher eventDispatcher;
    protected List<FlowableEventListener> eventListeners;
    protected Map<String, List<FlowableEventListener>> typedEventListeners;
    protected List<EventDispatchAction> additionalEventDispatchActions;

    protected LoggingListener loggingListener;

    protected boolean transactionsExternallyManaged;

    /**
     * 使用可设置为配置或不配置关系数据库的标志。这对于完全不使用关系数据库的自定义实现非常有用.
     *
     * 如果为true(默认值),将使用{@link AbstractEngineConfiguration#getDatabaseSchemaUpdate()}值来确定数据库模式需要执行的操作.
     *
     * 如果为false,则不会进行验证或模式创建。这意味着之前必须“手动”创建数据库模式,但引擎不会验证该模式是否正确。将不使用{@link AbstractEngineConfiguration#getDatabaseSchemaUpdate()}值.
     */
    protected boolean usingRelationalDatabase = true;
    
    /**
     * 可设置为配置是否使用模式的标志。这对于完全不使用关系数据库的自定义实现非常有用.
     * 将{@link#usingRelationalDatabase}设置为true将自动意味着使用模式.
     */
    protected boolean usingSchemaMgmt = true;

    /**
     *允许配置用于process engine所有运行时操作的数据库表前缀。例如,如果指定一个名为“PRE1”的前缀,Flowable将通过'PRE1.ACT_RU_EXECUTION_'表查询执行情况.
     *
     * 注意:自动数据库模式管理不考虑前缀。如果使用{@link AbstractEngineConfiguration#DB_SCHEMA_UPDATE_CREATE_DROP}或{@link AbstractEngineConfiguration#DB_SCHEMA_UPDATE_TRUE},Flowable将使用默认名称创建数据库表,而不考虑此处配置的前缀.
     */
    protected String databaseTablePrefix = "";

    /**
     * 用于进行通配符搜索的转义字符.
     *
     * 这将添加到包含LIKE子句查询的末尾。例如:SELECT * FROM table WHERE column LIKE '%\%%' 的转义符'\';
     */
    protected String databaseWildcardEscapeCharacter;

    /**
     * 要使用的数据库目录
     */
    protected String databaseCatalog = "";

    /**
     * 在某些情况下,如果数据库元数据没有正确返回,您需要设置用于表检查/生成的模式, 查看 https://jira.codehaus.org/browse/ACT-1220,
     * https://jira.codehaus.org/browse/ACT-1062
     */
    protected String databaseSchema;

    /**
     * 如果定义的databaseTablePrefix是模式名,而不是实际的表名前缀,则设置为true。这与检查是否存在Flowable表(databaseTablePrefix)有关。如果已经考虑了模式,就不会再使用-,为表检查添加前缀将导致错误的表名.
     */
    protected boolean tablePrefixIsSchema;
    
    /**
     * 如果最新版本的定义可被恢复,则设置为true,忽略可能的父级部署ID值
     */
    protected boolean alwaysLookupLatestDefinitionVersion;
    
    /**
     * 默认查找应退回到默认租户,则设置为true(默认情况下为空字符串或定义的租户值)
     */
    protected boolean fallbackToDefaultTenant;

    /**
     * 默认租户提供程序,在全局或本地回退到默认租户值为true的情况下,在查找定义时执行
     */
    protected DefaultTenantProvider defaultTenantProvider = (tenantId, scope, scopeKey) -> NO_TENANT_ID;

    /**
     * 启用记录sql语句执行时间的MyBatis插件.
     */
    protected boolean enableLogSqlExecutionTime;

    protected Properties databaseTypeMappings = getDefaultDatabaseTypeMappings();

    /**
     * 获取锁时检查之间的持续时间.
     */
    protected Duration lockPollRate = Duration.ofSeconds(10);

    /**
     * 在放弃之前等待DB模式锁定的持续时间.
     */
    protected Duration schemaLockWaitTime = Duration.ofMinutes(5);

    // 数据管理器 //

    protected PropertyDataManager propertyDataManager;
    protected ByteArrayDataManager byteArrayDataManager;
    protected TableDataManager tableDataManager;

    // 实体管理器 

    protected PropertyEntityManager propertyEntityManager;
    protected ByteArrayEntityManager byteArrayEntityManager;

    protected List<EngineDeployer> customPreDeployers;
    protected List<EngineDeployer> customPostDeployers;
    protected List<EngineDeployer> deployers;
    
    // 配置程序 

    protected boolean enableConfiguratorServiceLoader = true; // 默认情况下启用。在某些环境中,这应该设置为false(例如osgi)
    protected List<EngineConfigurator> configurators; // 注入式配置器
    protected List<EngineConfigurator> allConfigurators; // 包括自动发现的配置程序
    protected EngineConfigurator idmEngineConfigurator;
    protected EngineConfigurator eventRegistryConfigurator;

    public static final String PRODUCT_NAME_POSTGRES = "PostgreSQL";
    public static final String PRODUCT_NAME_CRDB = "CockroachDB";

    public static final String DATABASE_TYPE_H2 = "h2";
    public static final String DATABASE_TYPE_HSQL = "hsql";
    public static final String DATABASE_TYPE_MYSQL = "mysql";
    public static final String DATABASE_TYPE_ORACLE = "oracle";
    public static final String DATABASE_TYPE_POSTGRES = "postgres";
    public static final String DATABASE_TYPE_MSSQL = "mssql";
    public static final String DATABASE_TYPE_DB2 = "db2";
    public static final String DATABASE_TYPE_COCKROACHDB = "cockroachdb";

    public static Properties getDefaultDatabaseTypeMappings() {
   
        Properties databaseTypeMappings = new Properties();
        databaseTypeMappings.setProperty("H2", DATABASE_TYPE_H2);
        databaseTypeMappings.setProperty("HSQL Database Engine", DATABASE_TYPE_HSQL);
        databaseTypeMappings.setProperty("MySQL", DATABASE_TYPE_MYSQL);
        databaseTypeMappings.setProperty("MariaDB", DATABASE_TYPE_MYSQL);
        databaseTypeMappings.setProperty("Oracle", DATABASE_TYPE_ORACLE);
        databaseTypeMappings.setProperty(PRODUCT_NAME_POSTGRES, DATABASE_TYPE_POSTGRES);
        databaseTypeMappings.setProperty("Microsoft SQL Server", DATABASE_TYPE_MSSQL);
        databaseTypeMappings.setProperty(DATABASE_TYPE_DB2, DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/NT", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/NT64", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2 UDP", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/LINUX", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/LINUX390", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/LINUXX8664", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/LINUXZ64", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/LINUXPPC64", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/LINUXPPC64LE", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/400 SQL", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/6000", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2 UDB iSeries", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/AIX64", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/HPUX", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/HP64", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/SUN", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/SUN64", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/PTX", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2/2", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty("DB2 UDB AS400", DATABASE_TYPE_DB2);
        databaseTypeMappings.setProperty(PRODUCT_NAME_CRDB, DATABASE_TYPE_COCKROACHDB);
        return databaseTypeMappings;
    }

    protected Map<Object, Object> beans;

    protected IdGenerator idGenerator;
    protected boolean usePrefixId;

    protected Clock clock;
    protected ObjectMapper objectMapper;

    // 变量

    public static final int DEFAULT_GENERIC_MAX_LENGTH_STRING = 4000;
    public static final int DEFAULT_ORACLE_MAX_LENGTH_STRING = 2000;

    /**
     * 定义在数据库中存储字符串变量类型的最大长度。主要用于Oracle NVARCHAR2 2000个字符的限制
     */
    protected int maxLengthStringVariableType = -1;
    
    protected void initEngineConfigurations() {
   
        addEngineConfiguration(getEngineCfgKey(), getEngineScopeType(), this);
    }

    // 数据源
    // ///

    protected void initDataSource() {
   
        if (dataSource == null) {
   
            if (dataSourceJndiName != null) {
   
                try {
   
                    dataSource = (DataSource) new InitialContext().lookup(dataSourceJndiName);
                } catch (Exception e) {
   
                    throw new FlowableException("couldn't lookup datasource from " + dataSourceJndiName + ": " + e.getMessage(), e);
                }

            } else if (jdbcUrl != null) {
   
                if ((jdbcDriver == null) || (jdbcUsername == null)) {
   
                    throw new FlowableException("DataSource or JDBC properties have to be specified in a process engine configuration");
                }

                logger.debug("initializing datasource to db: {}", jdbcUrl);

                if (logger.isInfoEnabled()) {
   
                    logger.info("Configuring Datasource with following properties (omitted password for security)");
                    logger.info("datasource driver : {}", jdbcDriver);
                    logger.info("datasource url : {}", jdbcUrl);
                    logger.info("datasource user name : {}", jdbcUsername);
                }

                PooledDataSource pooledDataSource = new PooledDataSource(this.getClass().getClassLoader(), jdbcDriver, jdbcUrl, jdbcUsername, jdbcPassword);

                if (jdbcMaxActiveConnections > 0) {
   
                    pooledDataSource.setPoolMaximumActiveConnections(jdbcMaxActiveConnections);
                }
                if (jdbcMaxIdleConnections > 0) {
   
                    pooledDataSource.setPoolMaximumIdleConnections(jdbcMaxIdleConnections);
                }
                if (jdbcMaxCheckoutTime > 0) {
   
                    pooledDataSource.setPoolMaximumCheckoutTime(jdbcMaxCheckoutTime);
                }
                if (jdbcMaxWaitTime > 0) {
   
                    pooledDataSource.setPoolTimeToWait(jdbcMaxWaitTime);
                }
                if (jdbcPingEnabled) {
   
                    pooledDataSource.setPoolPingEnabled(true);
                    if (jdbcPingQuery != null) {
   
                        pooledDataSource.setPoolPingQuery(jdbcPingQuery);
                    }
                    pooledDataSource.setPoolPingConnectionsNotUsedFor(jdbcPingConnectionNotUsedFor);
                }
                if (jdbcDefaultTransactionIsolationLevel > 0) {
   
                    pooledDataSource.setDefaultTransactionIsolationLevel(jdbcDefaultTransactionIsolationLevel);
                }
                dataSource = pooledDataSource;
            }
        }

        if (databaseType == null) {
   
            initDatabaseType();
        }
    }

    public void initDatabaseType() {
   
        Connection connection = null;
        try {
   
            connection = dataSource.getConnection();
            DatabaseMetaData databaseMetaData = connection.getMetaData();
            String databaseProductName = databaseMetaData.getDatabaseProductName();
            logger.debug("database product name: '{}'", databaseProductName);

            // CRDB不会通过jdbc驱动程序公开这个版本,所以我们需要通过version()获取它.
            if (PRODUCT_NAME_POSTGRES.equalsIgnoreCase(databaseProductName)) {
   
                try (PreparedStatement preparedStatement = connection.prepareStatement("select version() as version;");
                        ResultSet resultSet = preparedStatement.executeQuery()) {
   
                    String version = null;
                    if (resultSet.next()) {
   
                        version = resultSet.getString("version");
                    }

                    if (StringUtils.isNotEmpty(version) && version.toLowerCase().startsWith(PRODUCT_NAME_CRDB.toLowerCase())) {
   
                        databaseProductName = PRODUCT_NAME_CRDB;
                        logger.info("CockroachDB version '{}' detected", version);
                    }
                }
            
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flowable是一个开的流程引擎,可以用于处理和管理各种类型的业务流程。Flowable码可以在其官方的GitHub仓库上找到,具体地址是https://github.com/flowable/flowable-engine/releases/tag/flowable-6.7.2。 Flowable的启动流程有两种方式,但最终都是执行了StartProcessInstanceCmd命令。在我以流程key方式启动来分析码中,启动流程的入口是通过runtimeService.startProcessInstance方法来实现的。 通过研究Flowable码,可以深入了解其内部的实现机制,从而更好地理解Flowable的工作原理和使用方法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [flowable 6.7.2 码压缩包](https://download.csdn.net/download/weixin_44393822/86790116)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [flowable部署和启动码解析](https://blog.csdn.net/u012483153/article/details/106736343)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Flowable流程启动码分析](https://blog.csdn.net/CH_PaulFrank/article/details/116800070)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值