JCA 1.5 规范定义了WorkManager API,能方便的进行任务的(多线程)并行处理。按照JCA规范的原意,WorkManager是仅提供给Resource Adapter使用的,容器会提供WorkManager实例并通过BootstrapContext注入到adapter中。可是,有时在其他场合,例如EJB、Servlet中,也希望能将请求拆分,使用WorkManager并行处理,但JEE规范中并没有提供这样的机制。
WebLogic提供了CommonJ WorkManager API,可用于任意应用中,但这个API不在JEE规范之中,因此GlassFish是不支持的。而且,使用WebLogic CommonJ WorkManager时需要在ejb-jar.xml中加入一个类型为commonj.work.WorkManager的resource reference,这样同一个ejb包就不能在不同application server间通用了,因此我还是希望能找到一种通用的方法。
SpringFramework的org.springframework.jca.work包为GlassFish和JBoss提供了在Resource Adapter外部使用JCA 1.5 WorkManager的简便方法。看了for GlassFish的源代码,发现它其实是调用了GlassFish内部的factory去直接创建WorkManager,那么对GlassFish是否也可以这样做呢?
反编译WebLogic的jar包,发现commonj WorkManager和connector WorkManager实际上都是delegate到一个weblogic.work.WorkManager实现的,也就是说在WebLogic里,CommonJ和JCA的WorkManager的底层实现其实都是同样的。接下来找到了weblogic.work.WorkManagerFactory,它有find和findOrCreate方法可返回weblogic.work.WorkManager实例,也许就是可以拿到weblogic-ejb-jar.xml里面定义的weblogic WorkManager。拿到了内部的weblogic.work.WorkManager实例后,再调用weblogic.connector.work.WorkManager的create方法,将这个内部WorkManger包裹到JCA WorkManager中,那么我们的应用就可以使用这个JCA WorkManager了,通过Spring的WorkManagerTaskExecutor来很方便的调度任务,上层的逻辑就可以做到与应用服务器无关。看起来很美。