1

我们正在 Tomcat 上使用 JSF 2 和 Weld Cdi 开发 Web 前端。
现在我在并行执行多个 Web 服务以优化请求时间时遇到了问题。
用户可以从列表中选择多个项目。
对于每个选定的项目,该过程使用列表键作为参数从一个 Web 服务收集它的信息。

我目前的方法是使用生产者,它返回注入到 bean 中的 web 服务端口接口。bean 在循环中为每个选定的键调用此 webservie。

@Inject
private WSAnzeigeAssetsummen serviceAccess;
:

for ( Integer pfNr : sessionKeys.getPfnrList() ) {
   summaryTable = serviceAccess.execute(snr, pfnr, requestType, "", desiredRows, userName);
   processResult(summaryTable):
}

为了更快,我尝试使用 ExecutorService 和尽可能多的工人,它们正在返回期货。

这个构造的问题是,我无法将服务端口注入工作人员,因为工作人员没有得到管理。手动创建服务端口可以工作但不受欢迎,因为它忽略了生产者类。

此外,在测试时,不可能注入提供预定义结果集的虚拟服务端口。

由于我没有找到任何关于在 tomcat-weld 环境中并行执行的内容,因此我的方法一定有问题。

解决这种情况的正确方法是什么?

编辑:为了更清楚我尝​​试了什么......

public class DataCollector implements ISumRequest<Integer, Integer, String, FutureResult> {

ExecutorService pool = Executors.newCachedThreadPool();
@Inject
SessionBean sessionBean;

public Future<FutureResult> collectInformation(Integer snr, Integer pfnr, String requestType) {

    CollectWorker worker = new CollectWorker (snr,pfnr,requestType,sessionBean.getUserName());     
    return pool.submit(worker);        
}

}

这样做时,工人不受管理。

4

1 回答 1

2

您可以将创建的工作人员包装在 CDI 创建上下文中,如下所示:

@Inject
private BeanManager beanManager;

public <T extends Object> T performInjection(final T obj) {
    if (this.beanManager != null) { // only do injection if the bean manager is present.
        // Create a creational context from the BeanManager
        final CreationalContext creationalContext = this.beanManager.createCreationalContext(null);
        // Create an injection target with the Type of the instance we need to inject into
        final InjectionTarget injectionTarget = this.beanManager.createInjectionTarget(this.beanManager.createAnnotatedType(obj.getClass()));
        // Perform injection into the instance
        injectionTarget.inject(obj, creationalContext);
        // Call PostConstruct on instance
        injectionTarget.postConstruct(obj);
    }
    return obj;
}
于 2013-05-15T14:56:40.297 回答