在在Spring中使用flowable这篇文章中可以看到配置flowable的方式是非常方便的,关键是要在配置文件中注入一个ProcessEngineFactoryBean, 今天我们在上篇文章责任链模式及其在flowable源码中的应用的基础上来分析一下flowable在Spring中的启动过程。
首先看看最关键的ProcessEngineFactoryBean类的继承关系:
image-20181208134746075对Spring比较熟悉的同学肯定秀快就能发现该类实现的三个接口都是Spring中的原生接口,接下来分别看下为什么要实现这三个接口。
- ApplicationContextAware
Implementing this interface makes sense for example when an object requires access to a set of collaborating beans. Note that configuration via bean references is preferable to implementing this interface just for bean lookup purposes
上面一段摘抄自Spring源码中的注释,也就是说实现了该类就能拿到所有的bean,其定义的方法会在Invoked after population of normal bean properties,也就是常规bean初始化完成后被调用。
看看ProcessEngineFactoryBean是怎么实现该方法的:
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
一行代码,也就是将应用上下文赋给自己的一个成员变量,以方便后期使用。
- FactoryBean
If a bean implements this interface, it is used as a factory for an object to expose, not directly as a bean instance that will be exposed itself.
实现了该接口,就可以不直接暴露bean实例而是以工厂的方式展示,也就是说,实现了该接口的bean可以返回不同的类型。那么具体返回了什么类型,就要看看它所定义的getObject方法了,注释文档中写到:
Return an instance (possibly shared or independent) of the object managed by this factory
getObject返回的具体对象就是工厂所表示的实例,并且:
{@link #getObjectType()} {@link #getObject()} invocations may arrive early in the bootstrap process, even ahead of any post-processor setup
该方法在启动阶段很早会被调用。
该接口的getObjectType用来返回工厂实例的类型,isSingleton表示该工厂返回的实现是否是单例,这里就不作多的解释了,直接看看ProcessEngineFactoryBean的具体实现:
public ProcessEngine getObject() throws Exception {
configureExpressionManager();
configureExternallyManagedTransactions();
if (processEngineConfiguration.getBeans() == null) {
processEngineConfiguration.setBeans(new SpringBeanFactoryProxyMap(applicationContext));
}
this.processEngine = processEngineConfiguration.buildProcessEngine();
return this.processEngine;
}
this.processEngine = processEngineConfiguration.buildProcessEngine();
return this.processEngine;
}
public Class<ProcessEngine> getObjectType() {
return ProcessEngine.class;
}
public boolean isSingleton() {
return true;
}
可以知道,ProcessEngineFactoryBean表示的是一个类型为ProcessEngine的单实例对象,在getObject中的processEngineConfiguration.buildProcessEngine()
这一行是需要重点关注的,直接进入具体的源码:
@Override
public ProcessEngine buildProcessEngine() {
init();
ProcessEngineImpl processEngine = new ProcessEngineImpl(this);
// trigger build of Flowable 5 Engine
if (flowable5CompatibilityEnabled && flowable5CompatibilityHandler != null) {
Context.setProcessEngineConfiguration(processEngine.getProcessEngineConfiguration());
flowable5CompatibilityHandler.getRawProcessEngine();
}
postProcessEngineInitialisation();
return processEngine;
}
// init
// /////////////////////////////////////////////////////////////////////
public void init() {
initConfigurators();
configuratorsBeforeInit();
initProcessDiagramGenerator();
initHistoryLevel();
initExpressionManager();
initAgendaFactory();
if (usingRelationalDatabase) {
initDataSource();
}
initHelpers();
initVariableTypes();
initBeans();
initFormEngines();
initFormTypes();
initScriptingEngines();
initClock();
initBusinessCalendarManager();
initCommandContextFactory();
initTransactionContextFactory();
initCommandExecutors();
initServices();
initIdGenerator();
initBehaviorFactory();
initListenerFactory();
initBpmnParser();
initProcessDefinitionCache();
initProcessDefinitionInfoCache();
initAppResourceCache();
initKnowledgeBaseCache();
initJobHandlers();
initJobManager();
initAsyncExecutor();
initTransactionFactory();
if (usingRelationalDatabase) {
initSqlSessionFactory();
}
initSessionFactories();
initDataManagers();
initEntityManagers();
initCandidateManager();
initHistoryManager();
initJpa();
initDeployers();
initDelegateInterceptor();
initEventHandlers();
initFailedJobCommandFactory();
initEventDispatcher();
initProcessValidator();
initFunctionDelegates();
initDatabaseEventLogging();
initFlowable5CompatibilityHandler();
configuratorsAfterInit();
}
看着让人头晕的一大串的初始化方法,但这也说明我们找到了正确的位置,没办法,先看看需要关注的点:
public void initCommandExecutors() {
initDefaultCommandConfig();
initSchemaCommandConfig();
initCommandInvoker();
initCommandInterceptors();
initCommandExecutor();
}
这个初始化的内容就是在用来初始化调用责任链的,在上一篇中有详细讲解,在这里我们只需要知道调用责任链已经形成。接着看initServices()方法:
public void initServices() {
initService(repositoryService);
initService(runtimeService);
initService(historyService);
initService(identityService);
initService(taskService);
initService(formService);
initService(managementService);
initService(dynamicBpmnService);
}
public void initService(Object service) {
if (service instanceof ServiceImpl) {
((ServiceImpl) service).setCommandExecutor(commandExecutor);
}
}
原来就是用来初始化flowable中的几大核心Service的,将commandExecutor赋给它的成员变量,而commandExecutor又包含调用责任链的内容,所以在核心Service中的实现中都是这样的代码:
image-20181208143515841又回到了责任链的执行问题了,看不懂? 没关系,回去看看上一篇就好了,或许我应该把责任链放在这篇的后面。。。
这个接口的实现是关键,总结一下,就是用来执行所有的初始化,包括数据库及DataManager的实例化,上下文,核心Servcie,一下子消化不完,后面或许还会回过头来看看。
- DisposableBean
Interface to be implemented by beans that want to release resources on destruction
用来最后释放资源的,直接看实现:
public void destroy() throws Exception {
if (processEngine != null) {
processEngine.close();
}
}
当工厂bean销毁时关闭流程引擎,释放内存等各种资源, 如下:
public void close() {
ProcessEngines.unregister(this);
if (asyncExecutor != null && asyncExecutor.isActive()) {
asyncExecutor.shutdown();
}
Runnable closeRunnable = processEngineConfiguration.getProcessEngineCloseRunnable();
if (closeRunnable != null) {
closeRunnable.run();
}
if (processEngineConfiguration.getProcessEngineLifecycleListener() != null) {
processEngineConfiguration.getProcessEngineLifecycleListener().onProcessEngineClosed(this);
}
processEngineConfiguration.getEventDispatcher().dispatchEvent(FlowableEventBuilder.createGlobalEvent(FlowableEngineEventType.ENGINE_CLOSED));
}
本文基于ProcessEngineFactoryBean实现的三个接口简单说明了一个flowable的启动也就是初始化方式,结合责任链那一篇我们基本上对flowable核心Servcie方法的调用也能形成一个闭环,先到这里,下篇再见。
网友评论