流程引擎自动配置原理及源码分析
前言废话
其实很早就把文档写完了,五一出去玩前段时间又犯懒,直到今天才来了兴致,这篇主要记录分享自动配置和一些基础的参数配置过程,过段时间的下一篇还会分享任务流转相关的源码记录,希望能抛砖引玉对各位有用,趁热打铁吧!
1.为什么camunda会随程序启动自动配置
在springboot项目中引入camunda依赖非常方便,提前准备好数据库引入几个依赖就能完成自动配置和随项目自启动,和springboot的自动配置一样,camunda的配置工作也是通过几个注解的相互作用和特定的配置类完成的。我们跟踪源码看看具体的步骤是怎样的。首先找到下图的springboot-starter依赖包,这是自动配置的起点。
我们发现目录结构META-INF下有spring.factories文件,打开后发现里面有自动配置类CamundaBpmAutoConfiguration,而springboot的SPI机制在启动时会扫描META-INF/services/目录下所有接口或META-INF目录下spring.factories文件,进行自动配置的拓展。要注意的是这种写法需要写类的全限定名也就是 包路径+类名。
具体步骤如下:
1.根据启动类上的@SpringBootApplication注解找到@EnableAutoConfiguration注解,再找到@import的AutoConfigurationImportSelector类,这个类实现了DeferredImportSelector接口,这个接口又继承了ImportSelector接口,因此在AutoConfigurationImportSelector类重写了selectImports()方法。
2.selectImports()方法,该方法刚开始会先判断是否进行自动装配,随后会从META-INF/spring-autoconfigure-metadata.properties读取元数据与元数据的相关属性,紧接着会调用getAutoConfigurationEntry()获取自动装配类的封装类,之后会调用getCandidateConfigurations()方法。
3.这个方法会调用SpringFactoriesLoader.loadFactoryNames()方法, 它会遍历读取META-INF/spring.factories文件里的EnableAutoConfiguration的配置,紧接着在进行排除与过滤,进而得到需要装配的类。
这样就实现了随springboot项目启动而加载CamundaBpmAutoConfiguration类。
2.camunda自动配置做了哪些工作
自动配置类CamundaBpmAutoConfiguration里有许多声明了@Bean注解的方法,其中的ProcessEngineFactoryBean()方法创建返回了ProcessEngineFactoryBean类,而这个类使用工厂模式返回getObject()方法返回的ProcessEngineImpl类。
在用这个configuration配置类创建processEngine的过程中会进行初始化、校验启动配置是否正确、以及注入各种常用的service和常量,因为操作实在太多,下面挑几个简要概况一下所做的重要操作有哪些。
-
init()初始化
a.初始化上下文工厂并赋值绑定配置类,为后续new CommandContext()做准备
b.初始化命令拦截器和拦截器的顺序,初始化命令执行器。可以看到在方法里创建了各个拦截器并手动指定链式连接的顺序,并保留了一个全局变量commandExecutorTxRequired,为了让后续Service和其他命令执行器都会先进入链式拦截器。
c.初始化常用的Service,做的工作就是给所有service都绑定拦截器链条的头部执行器LogInteceptor,如果是repositoryService则额外设置部署语言默认配置UTF-8。
d.初始化缓存工厂、初始化seesion工厂、初始化变量序列化器、校验历史数据清理线程数大小 - 将刚才init方法创建的service、Factory、Executor等绑定给流程引擎实例
- 执行3个命令执行器。
a.第一个命令校验数据库连接,连接本地还是h2数据库,并且判断数据库更新属性需不需要启动前清空表,然后执行预先准备好的sql删除、更新或创建表.
b.第二个命令建立数据库连接,判断配置文件的历史等级和数据库历史等级是否相同,不同则抛异常。
c.第三个命令读取ACT_RU_JOB表,执行配置的定时任务,并根据historyCleanUp的配置判断是否执行清理历史数据的操作。
每个命令执行前都会按照拦截器顺序遍历拦截器,分别是LogInterceptor打印日志、ProcessApplicationContextInterceptor目的不清楚、SpringTransactionInterceptor开启spring事务、CommandContextInterceptor给命令执行器开启新的上下文以获取流程引擎参数,开启数据库连接,拿锁。
- 注册(其实就是put进一个map里)刚创建的流程引擎实例到processEngines
- 创建DbMetricsReporter数据库度量报告器并启动,不清楚作用
- 执行postProcessEngineBuild,设置filter和admin、group等属性
- 用repositoryService创建postProcessEngineBuild,扫描项目中带特定后缀的文件用input流的形式进行部署,这里是为什么启动会自动部署xml文件。
- 加载剩余的@Bean,自动配置类结束,项目启动。