CDI specification的3.3节给出了对
@Produces注释的使用的很好的高级概述:
A producer method acts as a source of objects to be injected, where:
• the objects to be injected are not required to be instances of beans, or
• the concrete type of the objects to be injected may vary at runtime, or
• the objects require some custom initialization that is not performed by the bean constructor.
比方说,例如,您想要在一个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 for produce也显示了一个有趣的(但很罕见的情况)生成一个命名集合,稍后可以注入其他托管bean(非常酷):
public class Shop {
@Produces @ApplicationScoped
@Catalog @Named("catalog")
private List products = new LinkedList(8);
//...
}
public class OrderProcessor {
@Inject
@Catalog
private List products;
}
容器负责处理标记有@Produces注释的所有方法和字段,并且通常在部署应用程序时执行此操作。然后,根据需要,处理的方法和字段将用作托管bean的注入点解析的一部分。