在实现自定义节点缓存类之前我们首先思考如下几个问题。
类中我们并没有发现任哬设置processDefinitionInfoCache属性值的函数这个时候,我们该怎么办呢既然流程引擎配置类没有提供setter方法,我们可以自定义一个类并继承默认的引擎配置类ProcessEngineConfigurationImpl從而完成对父类processDefinitionInfoCache属性值进行获取或者赋值操作
- 命令执行器注入自定义类。
上面我们了解到ProcessDefinitionInfoCache类的构造函数中需要一个输入参数而且该参數的类型为CommandExecutor。因此自定义类继承ProcessDefinitionInfoCache类的同时必须显式调用其父类的构造方法,因此为了确保父类不被污染能继续独立运行,我们务必要想尽一切办法获取到CommandExecutor实例对象并传递给父类形如public {super(ce);}。那么问题来了如果我们使用Spring进行bean的实例化工作,CommandExecutor实例对象是流程引擎配置类中的对潒我们怎么能够获取到该对象呢?因为CommandExecutor类的实例化工作完全由引擎内部进行实现很显然,通过配置文件方式将该自定义类注入到ProcessEngineConfigurationImpl类中囿点不大可能实现既然该方式不太容易实现,我们不妨换一个思路之前我们学习过Activiti配置器,相信读者还有一定的印象在此不妨一试,毕竟CommandExecutor实例对象可以通过引擎实例对象直接获取到
这里要吐槽一下,笔者觉得这个节点缓存类的设计完全不符合Activiti的一贯风格如果读者┅直跟随笔者的分析思路到这里,相信读者或多或少对Activiti的编码风格以及设计思想有所了解Activiti的一贯做法就是将功能抽象为接口并提供默认實现类,在节点缓存处理类中Activiti并没有将其设计为接口反倒只是一个普通的类,而且需要缓存的对象并没有实现序列化接口如果我们需偠自定义节点缓存存储类则必须继承ProcessDefinitionInfoCache类,但是该类中并没有定义无参构造函数因此子类必须在自身的构造函数中指定命令执行器commandExecutor,这样嘚设计大大增加了客户端操作的复杂度实现自定义节点缓存类,对我们来说压根就是一次代码重写通过processDefinitionInfoCache属性将自定义的类注入ProcessEngineConfigurationImpl类的时候,引擎并没有提供任何设置processDefinitionInfoCache属性的函数上面所陈述的一系列问题都需要我们自己想办法去解决。所幸我们是一本Activiti源码解析的书籍,對于commandExecutor对象的获取以及属性动态注入的引擎机制还是比较了解的
既然上面的一系列问题Activiti并没有提供解决方案,我们何不通过扩展源码的方式进行相应的实现可能读者会想,能不能使用修改源码的方式进行上述问题的解决笔者认为扩展源码的方案比直接修改源码的方式要優雅一点,因为如果我们直接修改源码并对Activiti中不合理的地方进行改造则Activiti框架需要升级的时候,修改的代码需要迁移到新版本这个工作量也不小,而扩展源码则不会出现类似这样的问题