前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2023最新版本Activiti7系列-源码篇-初始化过程

2023最新版本Activiti7系列-源码篇-初始化过程

作者头像
用户4919348
发布2023-08-16 08:55:55
3870
发布2023-08-16 08:55:55
举报
文章被收录于专栏:波波烤鸭波波烤鸭

源码分析

1.设计模式

1.1 命令模式

https://cloud.tencent.com/developer/article/1415244

1.2 责任链模式

https://cloud.tencent.com/developer/article/1414901

2.初始化过程

2.1 入口代码

  我们在SpringBoot项目中来看Activiti7的源码。首先要找到的是自动装配的入口。在activiti-spring-boot-starterspring.factories中找到自动配置类ProcessEngineAutoConfiguration这个配置类

  进入到ProcessEngineAutoConfiguration中可以看到完成了SpringProcessEngineConfiguration的注入。我们再进入父类AbstractProcessEngineAutoConfiguration中。

代码语言:javascript
复制
    @Bean
    public ProcessEngineFactoryBean processEngine(SpringProcessEngineConfiguration configuration) {
        return super.springProcessEngineBean(configuration);
    }

看到了ProcessEngineFactoryBean这让我们联想到了是getObject()方法。然后进入到springProcessEngineBean方法中。

代码语言:javascript
复制
    public ProcessEngineFactoryBean springProcessEngineBean(SpringProcessEngineConfiguration configuration) {
        ProcessEngineFactoryBean processEngineFactoryBean = new ProcessEngineFactoryBean();
        processEngineFactoryBean.setProcessEngineConfiguration(configuration);
        return processEngineFactoryBean;
    }

再进入到ProcessEngineFactoryBeangetObject方法

代码语言:javascript
复制
    public ProcessEngine getObject() throws Exception {
        this.configureExpressionManager();
        this.configureExternallyManagedTransactions();
        if (this.processEngineConfiguration.getBeans() == null) {
            this.processEngineConfiguration.setBeans(new SpringBeanFactoryProxyMap(this.applicationContext));
        }

        this.processEngine = this.processEngineConfiguration.buildProcessEngine();
        return this.processEngine;
    }

关键是processEngineConfiguration.buildProcessEngine();这行代码。进入buildProcessEngine方法中查看。即进入到了ProcessEngineConfigurationImpl类中,并且调用了下面的方法。

代码语言:javascript
复制
  @Override
  public ProcessEngine buildProcessEngine() {
    init();
    ProcessEngineImpl processEngine = new ProcessEngineImpl(this);
    postProcessEngineInitialisation();

    return processEngine;
  }

ProcessEngineConfigurationImpl的作用:配置和初始化Activiti的流程引擎。通过该类,可以对流程引擎的各种参数进行配置,包括数据库连接信息事务管理器缓存管理器作业执行器等。同时,该类还提供了创建和获取ProcessEngine实例的方法,用于启动和管理流程引擎的运行。

2.2 init方法

  init()方法的作用是初始化Activiti引擎的配置,为引擎的正常运行做准备。

代码语言:javascript
复制
public void init() {
  initConfigurators();
  configuratorsBeforeInit();
  initHistoryLevel();
  initExpressionManager();

  if (usingRelationalDatabase) {
    initDataSource();
  }

  initAgendaFactory();
  initHelpers();
  initVariableTypes();
  initBeans();
  initScriptingEngines();
  initClock();
  initBusinessCalendarManager();
  initCommandContextFactory();
  initTransactionContextFactory();
  initCommandExecutors();
  initServices();
  initIdGenerator();
  initBehaviorFactory();
  initListenerFactory();
  initBpmnParser();
  initProcessDefinitionCache();
  initProcessDefinitionInfoCache();
  initKnowledgeBaseCache();
  initJobHandlers();
  initJobManager();
  initAsyncExecutor();

  initTransactionFactory();

  if (usingRelationalDatabase) {
    initSqlSessionFactory();
  }

  initSessionFactories();
  initDataManagers();
  initEntityManagers();
  initHistoryManager();
  initJpa();
  initDeployers();
  initDelegateInterceptor();
  initEventHandlers();
  initFailedJobCommandFactory();
  initEventDispatcher();
  initProcessValidator();
  initDatabaseEventLogging();
  configuratorsAfterInit();
}

上面初始化的内容有很多。我们先来看几个关键的:

  • initCommandContextFactory();
  • initTransactionContextFactory();
  • initCommandExecutors();
  • initServices();
2.2.1 initCommandContextFactory

  initCommandContextFactory方法的作用很简单,完成ProcessEngineConfigurationImpl中的commandContextFactory属性的初始化操作。

代码语言:javascript
复制
public void initCommandContextFactory() {
  if (commandContextFactory == null) {
    commandContextFactory = new CommandContextFactory();
  }
  commandContextFactory.setProcessEngineConfiguration(this);
}
2.2.2 initTransactionContextFactory

  initTransactionContextFactory方法的作用也很简单,完成ProcessEngineConfigurationImpl中的transactionContextFactory属性的初始化操作。

代码语言:javascript
复制
public void initTransactionContextFactory() {
  if (transactionContextFactory == null) {
    transactionContextFactory = new StandaloneMybatisTransactionContextFactory();
  }
}

2.2.3 initCommandExecutors

  initCommandExecutors这是一个非常重要的方法。会完成责任链中相关拦截器的组织和加载。里面的方法有

  • initDefaultCommandConfig() :初始化defaultCommandConfig属性【可重用Context上下文,支持事务传播属性】
  • initSchemaCommandConfig() :初始化schemaCommandConfig属性【不可重用Context上下文,不支持事务传播属性】
  • initCommandInvoker() :初始化commandInvoker属性。这个是责任链路中的最后一个节点
  • initCommandInterceptors() :初始化commandInterceptors属性,组装所有的拦截器到集合中
  • initCommandExecutor():初始化commandExecutor属性,完成责任链的关联并绑定链路的第一个节点【first】

核心代码:

代码语言:javascript
复制
public void initCommandExecutor() {
  if (commandExecutor == null) {
      // 获取责任链中的第一个拦截器    初始化责任链
    CommandInterceptor first = initInterceptorChain(commandInterceptors);
    commandExecutor = new CommandExecutorImpl(getDefaultCommandConfig(), first);
  }
}

public CommandInterceptor initInterceptorChain(List<CommandInterceptor> chain) {
  if (chain == null || chain.isEmpty()) {
    throw new ActivitiException("invalid command interceptor chain configuration: " + chain);
  }
    // 设置责任链
  for (int i = 0; i < chain.size() - 1; i++) {
    chain.get(i).setNext(chain.get(i + 1));
  }
  return chain.get(0); // 返回第一个节点
}

对应的图解:

2.2.4 initServices

  在Activiti7中我们完成各种流程的操作,比如部署查询流程定义流程审批等各种操作都是通过xxxService来完成的。这些service在ProcessEngineConfigurationImpl中的成员变量中就会完成对象的实例化。

代码语言:javascript
复制
  protected RepositoryService repositoryService = new RepositoryServiceImpl();
  protected RuntimeService runtimeService = new RuntimeServiceImpl();
  protected HistoryService historyService = new HistoryServiceImpl(this);
  protected TaskService taskService = new TaskServiceImpl(this);
  protected ManagementService managementService = new ManagementServiceImpl();
  protected DynamicBpmnService dynamicBpmnService = new DynamicBpmnServiceImpl(this);

  在init方法的initServices完成的操作是和上面实例化的commandExecutor完成绑定。也就是xxxService中的各种执行操作最终都是由commandExecutor来完成的。

代码语言:javascript
复制
  public void initServices() {
    initService(repositoryService);
    initService(runtimeService);
    initService(historyService);
    initService(taskService);
    initService(managementService);
    initService(dynamicBpmnService);
  }

绑定commandExecutor

代码语言:javascript
复制
  public void initService(Object service) {
    if (service instanceof ServiceImpl) {
      ((ServiceImpl) service).setCommandExecutor(commandExecutor);
    }
  }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-08-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 源码分析
    • 1.设计模式
      • 1.1 命令模式
      • 1.2 责任链模式
    • 2.初始化过程
      • 2.1 入口代码
      • 2.2 init方法
      • 2.2.3 initCommandExecutors
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档