jBPM(十七): popJbpmConfiguration的异常理解及纠正
有几天没写jBPM方面的博客了, 这方面有些生疏了.
今天再回过头看时,发现这么个问题.JbpmContextFilter类里jbpmContext.close()方法执行时,
会调用JbpmConfiguration类里popJbpmConfiguration和popJbpmContext(jbpmContext)两个
方法. popJbpmContext后, jbpmContext会因再没有对其的引用而被垃圾回收掉,
popJbpmConfiguration也会被"回收掉". 于是这样就有了一个不和谐的现象:
每一次请求来时都要新创建JbpmConfiguration实例和jbpmContext实例.想到Hibernate中创建一个
configuration实例是很耗资源的,这里也可类比地得出同样的结论(从执行代码上也能看出来,新建一个JbpmConfiguration实例
要做I/O操作并解析xml文件).这样每一个请求来都要新建JbpmConfiguration对象岂不荒唐!
肯定是自己理解上出了偏差. 偏差出在了哪? 一番细想研究后, 找到了答案.
首先来看创建一个JbpmConfiguration时做了什么.
JbpmConfiguration的最初创建是在JbpmContextFilter中通
过"JbpmConfiguration.getInstance(jbpmConfigurationResource)"来完成的.
在getInstance里,
经过一番"努力"后生成一个JbpmConfiguration对象,随后把它放到了JbpmConfiguration类静态变量instances中
保存了下来.这样只人JVM不死, 新建的JbpmConfiguration实例就一直由于instances对其的引用而不会被回收.
上面的分析确保了JbpmConfiguration实例不会被回收,那是什么导致了我上面的错误分析? 我们再看JbpmConfiguration类createJbpmContext方法做了什么. 在jBPM(十六): 记录JbpmContext实例的诞生
中
我们见证了以反射方式生成的jbpmContext实例,那么jbpmContext实例创建后createJbpmContext做什么?
我们看到调用了一句jbpmContextCreated(jbpmContext),把当前的JbpmConfiguration实例push到静态属
性jbpmConfigurationsStacks(是ThreadLocal类型的)里里stack中,
再把新生成的jbpmContext实例push到jbpmContextStacks(也是ThreadLocal类型)里.
有了上面的push,再看在jbpmContext.close()时的pop操作.
对popJbpmContext(jbpmContext)的理解没错,popJbpmConfiguration的理解上出了问题,
是调用getJbpmConfigurationStack().remove了,
但这里的remove只是从jbpmConfigurationsStacks里的stack里给remove了, JVM里还是有的.
这里的remove是造成上面我理解出错的"元凶".
----------
分析得知,
JbpmConfiguration在jbpmContext.close()时没有给回收掉,
这样就不难理解JbpmContext.getCurrentJbpmContext()时调用
JbpmConfiguration.getCurrentJbpmConfiguration()就可以直接以stack.peek方式从
jbpmConfigurationsStacks里取出一个实例,也可以理解JbpmConfiguration.getInstance时不用再新建
一个JbpmConfiguration实例了.