CDI @Produces 注释在字段上的目的是什么?
What is the purpose of CDI @Produces annotation on a field?
我想我理解了 CDI @Produces 结合工厂方法的目的:
@Produces
public TimeLogger getTimeLogger() {
return new TimeLogger(new SimpleDateFormat("HH:mm"), Calendar.getInstance());
}
但是我真的不明白下面的等价物是如何有用的:
@Produces
TimeLogger timeLogger;
由于 timeLogger
在第二种情况下将为 null,那么它有何作用?如何指向某个可以提供 TimeLogger 实例的工厂?我需要添加限定符吗?
目的是将 CDI 的依赖注入与某些其他依赖注入机制(例如 Java EE 的 @Resource
注入连接起来。
一般来说,将@Produces
放在字段上意味着当其他人调用该字段类型的对象时,该对象将被该字段的内容"produced",无论他们碰巧是,不管他们是怎么变成那样的。
好的,我们再试一次。
假设我在托管 bean 中有一个字段。它的类型是 Foo
:
private Foo foo;
假设我在某处使用普通 Java 东西的方法中设置该字段:
// Let's pretend this is called from our constructor.
private void initialize() {
this.foo = goGetAFooFromLDAPOrSomething();
// yay, now foo is set to something that I went and got from somewhere;
// I just went out and got it; I didn't do anything fancy involving
// CDI
}
现在假设我想在我的应用程序的其他地方使用 Foo
但我真的不想再次经历这种令人头疼的事情,而只是想表明 Foo
是我的要求之一,所以,作为一名优秀的 CDI 公民,我只想 @Inject
a Foo
:
// In some other class somewhere.
// Hey, CDI, get me a Foo that was produced elsewhere,
// however you do it.
@Inject
private Foo injectedFoo;
如果就此打住,这个注入点将得不到满足。目前没有人 "makes" Foo
以 CDI 永远不会知道的方式。
我可以通过简单地将 @Produces
添加到托管 bean 的 foo
字段来满足注入点:
@Produces
private Foo foo;
毕竟,我们自己手动填充了这个字段,然后向 CDI 表明它可以 "make" 一个 Foo
通过在有人调用 Foo
时简单地返回这个字段的值在某处注射。
这有意义吗?
限定符在这种情况下与在任何其他情况下没有什么不同:它们是另一种指示制造或注入哪种 Foo
的方式。如果我想注入一个 @Yellow
Foo
,那么我会这样表示我的愿望:
@Inject
@Yellow
private Foo injectedFoo;
...然后我必须确保某个地方的某些东西会产生 @Yellow
Foo
。在这个愚蠢的例子中,它可以这样设置:
@Produces
@Yellow
private Foo foo;
我想我理解了 CDI @Produces 结合工厂方法的目的:
@Produces
public TimeLogger getTimeLogger() {
return new TimeLogger(new SimpleDateFormat("HH:mm"), Calendar.getInstance());
}
但是我真的不明白下面的等价物是如何有用的:
@Produces
TimeLogger timeLogger;
由于 timeLogger
在第二种情况下将为 null,那么它有何作用?如何指向某个可以提供 TimeLogger 实例的工厂?我需要添加限定符吗?
目的是将 CDI 的依赖注入与某些其他依赖注入机制(例如 Java EE 的 @Resource
注入连接起来。
一般来说,将@Produces
放在字段上意味着当其他人调用该字段类型的对象时,该对象将被该字段的内容"produced",无论他们碰巧是,不管他们是怎么变成那样的。
好的,我们再试一次。
假设我在托管 bean 中有一个字段。它的类型是 Foo
:
private Foo foo;
假设我在某处使用普通 Java 东西的方法中设置该字段:
// Let's pretend this is called from our constructor.
private void initialize() {
this.foo = goGetAFooFromLDAPOrSomething();
// yay, now foo is set to something that I went and got from somewhere;
// I just went out and got it; I didn't do anything fancy involving
// CDI
}
现在假设我想在我的应用程序的其他地方使用 Foo
但我真的不想再次经历这种令人头疼的事情,而只是想表明 Foo
是我的要求之一,所以,作为一名优秀的 CDI 公民,我只想 @Inject
a Foo
:
// In some other class somewhere.
// Hey, CDI, get me a Foo that was produced elsewhere,
// however you do it.
@Inject
private Foo injectedFoo;
如果就此打住,这个注入点将得不到满足。目前没有人 "makes" Foo
以 CDI 永远不会知道的方式。
我可以通过简单地将 @Produces
添加到托管 bean 的 foo
字段来满足注入点:
@Produces
private Foo foo;
毕竟,我们自己手动填充了这个字段,然后向 CDI 表明它可以 "make" 一个 Foo
通过在有人调用 Foo
时简单地返回这个字段的值在某处注射。
这有意义吗?
限定符在这种情况下与在任何其他情况下没有什么不同:它们是另一种指示制造或注入哪种 Foo
的方式。如果我想注入一个 @Yellow
Foo
,那么我会这样表示我的愿望:
@Inject
@Yellow
private Foo injectedFoo;
...然后我必须确保某个地方的某些东西会产生 @Yellow
Foo
。在这个愚蠢的例子中,它可以这样设置:
@Produces
@Yellow
private Foo foo;