所以我想我通过使用javax.enterprise.inject.Instance 想出了我想要做什么。首先定义一个简单的bean:
@Alternative
public class Foo {
private int value;
public void setValue(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
它被定义为@Alternative,因此CDI 不会混淆它和生产者方法(如下所示)。更好的解决方案是将Foo 定义为接口,然后FooImpl 将使用@Typed 进行注释,因此CDI 认为它只是FooImpl bean 类型。不管怎样,接下来是生产者类。
@ApplicationScoped
public class FooProducer {
private int value;
public FooProducer() {
value = -1;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
@Produces
public Foo getFoo() {
Foo p = new Foo();
p.setValue(getValue());
return p;
}
}
getFoo() 方法生成具有不同值的新 Foo 对象。该值可以通过setValue(int) 方法更改。接下来我使用javax.enterprise.inject.Instance 注入Foo。
@Inject
Instance<Foo> fooInstance;
@Inject
FooProducer fooProducer;
....
fooProducer.setValue(10);
Foo foo = fooInstance.get();
System.out.printf("foo = %s, %d\n", foo.getValue());
fooProducer.setValue(10000);
foo = fooInstance.get();
System.out.printf("foo = %s, %d\n", foo.getValue());
这里我使用注入的fooProducer.setValue() 方法来改变生产者将如何产生Foo。当fooInstance.get() 第一次被调用时,Foo 将包含值 10,第二次将包含值 10000。
鉴于这个简单的示例,很容易应用在运行时将EntityManager 实例获取到不同的数据库。生成 EntityManager 的代码还有更多内容,但不会太多。