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;