美文网首页
flowable流程引擎在Spring环境中的启动源码分析

flowable流程引擎在Spring环境中的启动源码分析

作者: Acamy丶 | 来源:发表于2018-12-08 14:50 被阅读0次

    在Spring中使用flowable这篇文章中可以看到配置flowable的方式是非常方便的,关键是要在配置文件中注入一个ProcessEngineFactoryBean, 今天我们在上篇文章责任链模式及其在flowable源码中的应用的基础上来分析一下flowable在Spring中的启动过程。

    首先看看最关键的ProcessEngineFactoryBean类的继承关系:

    image-20181208134746075

    对Spring比较熟悉的同学肯定秀快就能发现该类实现的三个接口都是Spring中的原生接口,接下来分别看下为什么要实现这三个接口。

      1. 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;
        }
    

    一行代码,也就是将应用上下文赋给自己的一个成员变量,以方便后期使用。

      1. 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,一下子消化不完,后面或许还会回过头来看看。

      1. 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方法的调用也能形成一个闭环,先到这里,下篇再见。

    相关文章

      网友评论

          本文标题:flowable流程引擎在Spring环境中的启动源码分析

          本文链接:https://www.haomeiwen.com/subject/gveqhqtx.html