Weld CDI环境中的并行web服务访问



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

我目前的方法是使用Producer,它返回web服务端口接口,该接口被注入到bean中。对于每个选定的键,bean在循环中调用该web服务。

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

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

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

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

由于我没有发现任何关于在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);        
}

}

您可以将您创建的worker封装在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;
}

最新更新