【问题标题】:Weld: Inject dependency inside Thread J2EEWeld:在线程 J2EE 中注入依赖项
【发布时间】:2016-12-14 22:11:03
【问题描述】:

我目前遇到了一个大问题,我们将不胜感激。

首先,以下情况发生在 J2EE 环境中,我知道我不应该自己管理线程,但不幸的是,我无法更改它,也无法使用 EJB。该环境基于 Tomcat Web Container 和 Weld CDI 管理器。

我的结构包含大量 RESTful 服务、服务层和 DAO 层实现,所有这些都通过使用相互注入 @Inject,它工作正常。当我需要将我的服务层注入到我的 Run 方法中时,问题就出现了,我得到了

WELD-001303 No active contexts for scope type javax.enterprise.context.RequestScoped.

我已经有一个方法可以返回所需的 bean 及其上下文,如下代码所述:

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 中?

谢谢。

【问题讨论】:

    标签: java multithreading dependency-injection weld


    【解决方案1】:

    抱歉,不行 - 这行不通。

    CDI 不支持跨线程的上下文传播。它只绑定到一个线程。否则会由于同步而产生严重的开销。

    作为我上面的线程绑定声明的证明,请查看Weld source code,其中ThreadLocal&lt;BeanStore&gt; 在给定上下文中用作bean 的存储。我在链接中提到的类是上下文实现类的前身。另请注意,这不是仅焊接的“问题”,任何 CDI impl 都在相同的基础上工作。

    您可以在不同的线程中激活给定的上下文/作用域,但这意味着一切都将被重新创建,并且您保存在(例如)@ApplicationScoped bean 中的任何状态都不会传播。此外,通过一些绝对不好的黑客攻击,您也许能够访问 bean 存储并复制到另一个线程。这将为您提供只读访问权限,但我不确定如何执行此操作以及是否值得付出努力。

    最后但同样重要的是,CDI 允许您实现自己的上下文,甚至可以补充您的内置上下文版本。这样你就可以提供一个完整版本的跨线程工作的上下文,但是有很多挑战,我不确定它是否可行/合理。

    【讨论】:

    • 感谢您的回答。我必须同意,我也不认为像你所说的那样值得努力。我可能必须找到解决我的情况的方法并删除线程使用。
    猜你喜欢
    • 2018-06-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    • 2018-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    相关资源
    最近更新 更多