源码分析
1.设计模式
1.1 命令模式
https://dpb-bobokaoya-sm.blog.csdn.net/article/details/89115420
1.2 责任链模式
https://dpb-bobokaoya-sm.blog.csdn.net/article/details/89077040
2.初始化过程
2.1 入口代码
我们在SpringBoot项目中来看Activiti7的源码。首先要找到的是自动装配的入口。在activiti-spring-boot-starter
的spring.factories
中找到自动配置类ProcessEngineAutoConfiguration
这个配置类
进入到ProcessEngineAutoConfiguration
中可以看到完成了SpringProcessEngineConfiguration
的注入。我们再进入父类AbstractProcessEngineAutoConfiguration
中。
@Bean
public ProcessEngineFactoryBean processEngine(SpringProcessEngineConfiguration configuration) {
return super.springProcessEngineBean(configuration);
}
看到了ProcessEngineFactoryBean
这让我们联想到了是getObject()
方法。然后进入到springProcessEngineBean
方法中。
public ProcessEngineFactoryBean springProcessEngineBean(SpringProcessEngineConfiguration configuration) {
ProcessEngineFactoryBean processEngineFactoryBean = new ProcessEngineFactoryBean();
processEngineFactoryBean.setProcessEngineConfiguration(configuration);
return processEngineFactoryBean;
}
再进入到ProcessEngineFactoryBean
的getObject
方法
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
类中,并且调用了下面的方法。
@Override
public ProcessEngine buildProcessEngine() {
init();
ProcessEngineImpl processEngine = new ProcessEngineImpl(this);
postProcessEngineInitialisation();
return processEngine;
}
ProcessEngineConfigurationImpl
的作用:配置和初始化Activiti的流程引擎。通过该类,可以对流程引擎的各种参数进行配置,包括数据库连接信息
、事务管理器
、缓存管理器
、作业执行器
等。同时,该类还提供了创建和获取ProcessEngine实例的方法,用于启动和管理流程引擎的运行。
2.2 init方法
init()方法的作用是初始化Activiti引擎的配置,为引擎的正常运行做准备。
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
属性的初始化操作。
public void initCommandContextFactory() {
if (commandContextFactory == null) {
commandContextFactory = new CommandContextFactory();
}
commandContextFactory.setProcessEngineConfiguration(this);
}
2.2.2 initTransactionContextFactory
initTransactionContextFactory方法的作用也很简单,完成ProcessEngineConfigurationImpl
中的transactionContextFactory
属性的初始化操作。
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】
核心代码:
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
中的成员变量中就会完成对象的实例化。
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
来完成的。
public void initServices() {
initService(repositoryService);
initService(runtimeService);
initService(historyService);
initService(taskService);
initService(managementService);
initService(dynamicBpmnService);
}
绑定commandExecutor
public void initService(Object service) {
if (service instanceof ServiceImpl) {
((ServiceImpl) service).setCommandExecutor(commandExecutor);
}
}