请解释CDI中的@Produces注解
Posted
技术标签:
【中文标题】请解释CDI中的@Produces注解【英文标题】:Please explain the @Produces annotation in CDI 【发布时间】:2013-05-08 05:38:41 【问题描述】:我读过 CDI 中的 @Produces 注解,但我不明白它的用法。
public class Resources
// Expose an entity manager using the resource producer pattern
@SuppressWarnings("unused")
@PersistenceContext
@Produces
private EntityManager em; //
@Produces
Logger getLogger(InjectionPoint ip) //
String category = ip.getMember()
.getDeclaringClass()
.getName();
return Logger.getLogger(category);
@Produces
FacesContext getFacesContext() //
return FacesContext.getCurrentInstance();
取自:http://www.jboss.org/jdf/quickstarts/jboss-as-quickstart/guide/GreeterQuickstart/#GreeterQuickstart-
容器如何知道调用生产者方法?如果我注入一个EntityManager,容器如何调用@produces EntityManager?以及如何调用 getLogger 生产者方法?
我也看不出经历所有麻烦的原因。
【问题讨论】:
【参考方案1】:这个例子对我不太适用。它的工作是一个小调整:
@Alternative
class SomeTPLClass
public SomeTPLClass(String id)
class SomeTPLClassProducer
@Produces
public SomeTPLClass getInstance()
return new SomeTPLClass("");
所以我不得不在我的班级中添加 @Alternative 以消除 @Default 有两个选项的错误。
【讨论】:
【参考方案2】:CDI specification 的第 3.3 节对@Produces
注释的使用进行了很好的高级概述:
生产者方法充当要注入的对象的来源,其中: • 要注入的对象不需要是bean 的实例,或者 • 要注入的对象的具体类型可能在运行时有所不同,或者 • 对象需要一些自定义初始化,这些初始化不是由 bean 构造函数执行的。
例如,假设您想在 Java EE 托管组件(如实体管理器)和其他 CDI 组件之间架起一座桥梁,您可以使用 @Produces
注释。另一个好处是您不必在整个数据域层中重复 @PersistenceContext
注释。
class A
@PersistenceContext // This is a JPA annotation
@Produces // This is a CDI 'hook'
private EntityManager em;
class B
@Inject // Now we can inject an entity manager
private EntityManager em;
另一个方便的用途是绕过没有 CDI 友好 bean 的库(例如,没有默认构造函数):
class SomeTPLClass
public SomeTPLClass(String id)
class SomeTPLClassProducer
@Produces
public SomeTPLClass getInstance()
return new SomeTPLClass("");
用于生成的 Javadoc 还显示了一个有趣的(但相当罕见的情况)生成命名集合,该集合随后可以注入到其他托管 bean(非常酷):
public class Shop
@Produces @ApplicationScoped
@Catalog @Named("catalog")
private List<Product> products = new LinkedList<Product>(8);
//...
public class OrderProcessor
@Inject
@Catalog
private List<Product> products;
容器负责处理所有标有@Produces 注解的方法和字段,通常会在部署应用程序时执行此操作。然后,处理后的方法和字段将根据需要用作托管 bean 的注入点解析的一部分。
【讨论】:
不错的答案。谢谢。但我对你的第一个例子有疑问。可以说Class C
也@Produces
和EntityManager
。 Class B
从哪里知道从这些注入哪个?
@Produces 只能被 Class 使用一次
@Perception - 我非常感谢您在这里所做的努力,我认为您添加了很棒的内容。但是,对于 JavaEE 新手,我仍然看不到注释的作用?在使用 EntityManager 的第一个示例中,为什么添加此注释使其可以使用 @Inject?另外,“生产者方法充当要注入的对象的来源”到底是什么意思?成为对象的来源是什么意思?
@Inject 表示您可以使用该对象而无需手动创建它。 @Produres 是您创建它的地方。而对于 EntityManager,我认为 jboss 使用 @PersistenceContext 为您创建它以上是关于请解释CDI中的@Produces注解的主要内容,如果未能解决你的问题,请参考以下文章
哪个是 CDI @Produces 注释的 Spring 等效项?