我目前正面临一个巨大的问题,任何帮助都会受到高度赞赏。
首先,以下内容出现在J2EE环境中,我知道我不应该自己管理一个Thread,但不幸的是我不能改变它,也不能使用EJB。该环境基于Tomcat Web容器和Weld CDI管理器。
我的结构包含许多RESTful服务,服务层和DAO层实现,所有这些都是通过使用注入彼此 @Inject,它工作正常。当我需要将我的服务层注入到我的Run方法中并且我得到
时,就会出现问题WELD-001303 No active contexts for scope type javax.enterprise.context.RequestScoped.
我已经有了一个方法来返回所需的bean及其contextual,如下面的代码描述:
BeanManager manager = (BeanManager) jndiContext.lookup("java:/comp/BeanManager");
Bean<T> bean = (Bean<T>) manager.getBeans(beanClass).iterator().next();
CreationalContext<?> ctx = manager.createCreationalContext(bean);
return (T) manager.getReference(bean, beanClass, ctx);
但即使我使用这种方法我也会收到错误。那么,有没有什么方法可以将我的bean注入我创建和管理的Thread中?
谢谢。
答案 0 :(得分:0)
很抱歉,但是没有 - 这只是没有成功。
事实上,CDI不支持跨线程的上下文传播。它仅限于一个线程。否则会由于同步而产生严重的开销。作为上述线程绑定声明的证明,请查看Weld source code,其中ThreadLocal<BeanStore>
在给定上下文中用作bean的存储。我在链接中引用的类是实现类的上下文的前身。另请注意,这不仅仅是Weld&#34;问题&#34;,任何CDI都会在同一基础上发挥作用。
您可以在不同的线程中激活给定的上下文/范围,但这意味着将重新创建所有内容,并且您在(例如)@ApplicationScoped
bean中保存的任何状态都不会传播。此外,有些肯定不是很好的黑客,你可能访问bean商店并复制到另一个线程。这会给你一个只读权限,但我不知道该怎么做,如果这甚至值得努力。
最后但并非最不重要的是,CDI允许您实现自己的上下文,甚至可以补充您的内置上下文版本。通过这种方式,您可以提供跨线程的完整版本的上下文,但是有很多挑战,我不确定它是否可行/合理。