【发布时间】:2014-02-27 14:34:31
【问题描述】:
是否可以手动将 bean 注入 CDI 上下文?使用 JBoss Seam 框架,我总是可以做类似Contexts.getConversationContext().set("foo", bar); 的事情,而 Bean 将成为该上下文的一部分。是否有可能在 Java EE 6 CDI 中做这样的事情?
【问题讨论】:
标签: java jakarta-ee seam cdi
是否可以手动将 bean 注入 CDI 上下文?使用 JBoss Seam 框架,我总是可以做类似Contexts.getConversationContext().set("foo", bar); 的事情,而 Bean 将成为该上下文的一部分。是否有可能在 Java EE 6 CDI 中做这样的事情?
【问题讨论】:
标签: java jakarta-ee seam cdi
使用 CDI,您必须稍微改变您对作用域 bean 的看法。在 Seam2 中,上下文只是特定范围内的映射,您可以访问这些映射。在 CDI 中,容器可以控制上下文,并且只允许您在具体范围内声明 bean,并且所有内容都在后台进行管理,而无需访问范围映射。这样做是因为 CDI 的理念是保持事物的类型安全,并且仅在映射中以字符串为值设置事物并通过其字符串键注入它们根本不是类型安全的。
为了实现您想要在具体范围内创建一个“持有者”bean 并在那里保存您的值的目标。
@Named
@ConversationScoped
public class UserManager {
private User currentUser;
//getters and setters for currentUser
}
在这个示例中,通过在对话范围 bean 中设置一个用户实例,它被保存在对话范围内。这是完全类型安全的,因为您可以通过使用 @Inject(实际上是使用 bean 类型)将 UserManager 注入任何您想要的位置,避免在重构时不安全的字符串键(如 Seam2 中)。
【讨论】:
没有办法以与实现无关的方式做到这一点。您必须深入研究实现,找到范围对象,通过 BeanManager 将它们拉出并弄清楚如何添加它们。并非所有(很可能没有)都像地图一样容易设置。
【讨论】:
难道不能使用 Producer 方法吗?
http://docs.jboss.org/weld/reference/1.0.0/en-US/html/producermethods.html
我这样做是为了创建注入到我的 bean 中的对象。
虽然我没用过这个,但是还有BeanManager接口
http://docs.jboss.org/weld/reference/1.0.0/en-US/html/extend.html
或者您是否在关注对话范围内的特定内容?
【讨论】:
Dependent,并继承被注入的bean的范围。
@Dependent 表示容器将为每个注入点(@Inject)创建一个新实例(CDI 1.1 实际上使@Dependent 替换@New)。没有两个注入点将共享同一个实例。创建后,容器就忘记了 bean;从而使其依赖于封闭对象实例的生命周期。