[源码研究]jbpm中的异步Action

在jbpm中,如果action可以配置为异步执行

<action class=”ActionClassName” async=”true”></action>

如果是异步action,那么在flow执行到action所依附的节点时,会保存一个job,然后交由单独的job执行线程处理.源代

码:
GraphElement.java的executeActions方法:

if (action.isAsync()) {
ExecuteActionJob job = createAsyncActionExecutionJob(executionContext.getToken(), action);
MessageService messageService = (MessageService) Services.getCurrentService

(Services.SERVICENAME_MESSAGE);
messageService.send(job);
} else {
executeAction(action, executionContext);
}

这个job保存到数据库,并由JobExecutor去执行.

而jobExecutor在默认情况下是不会被启用的,需要手动启用或者配置为自动启动的servlet(JobExecutorServlet).
手动启动通过这个方法:

JbpmConfiguration.startJobExecutor()

还需要做的工作,在jbpm.cfg.xml里定义一个jobExecutor

<bean name=”jbpm.job.executor” class=”org.jbpm.job.executor.JobExecutor” singleton=”true” />

如果不用JbpmConfiguration应该也可以启动.做的事都是一样的,创建一个新的JobExecutor然后启动线程.只是猜测,没试过.

在3.1的数据库里是没有job的表的,升级到3.2.2后才有这个表.

SpringIDE的误导

用springide验证了一下xml文件,得到这个错误

Destroy-method ‘shutdown’ not found in bean class ‘org.enhydra.jdbc.pool.StandardXAPoolDataSource’

bean的配置如下:

也就是说springide认为这个bean没有shutdown的方法.查了一下xapool的source,发现是有的,但是是shutdown(boolean).destroy-method属性的定义:

Attribute : destroy-method
The name of the custom destroy method to invoke on bean factory shutdown. The method must
have no arguments, but may throw any exception. Note: Only invoked on beans whose lifecycle is
under the full control of the factory – which is always the case for singletons, but not guaranteed
for any other scope.

在来看spring的source终于发现玄机所在:

DisposableBeanAdapter的invokeCustomDestroyMethod 方法:

Class[] paramTypes = destroyMethod.getParameterTypes();
if (paramTypes.length > 1) {
logger.error("Method '" + destroyMethodName + "' of bean '" + this.beanName +
"' has more than one parameter - not supported as destroy method");
}
else if (paramTypes.length == 1 && !paramTypes[0].equals(boolean.class)) {
logger.error("Method '" + destroyMethodName + "' of bean '" + this.beanName +
"' has a non-boolean parameter - not supported as destroy method");
}
else {
Object[] args = new Object[paramTypes.length];
if (paramTypes.length == 1) {
args[0] = Boolean.TRUE;
}

if (!Modifier.isPublic(destroyMethod.getModifiers()) ||
!Modifier.isPublic(destroyMethod.getDeclaringClass().getModifiers())) {
destroyMethod.setAccessible(true);
}

红色标记的地方就看到了,这个方法只会接受一个无参数方法或者参数唯一并且是boolean的方法.boolean值得意义就是force

附方法的注释:
This implementation invokes a no-arg method if found, else checking
for a method with a single boolean argument (passing in “true”,
assuming a “force” parameter), else logging an error.

显然SpringIDE没有考虑到这点.