我需要将 ApplicationScoped
bean 的相同实例注入(inject)到我的应用程序的多个位置,并创建了以下使用 @PostConstruct
注释的工厂类初始化 bean 和 @Produces
注释以返回 bean 的相同实例。
@ApplicationScoped
public class CommandBusFactory implements Serializable {
private static final long serialVersionUID = 1L;
private CommandBus commandBus;
@PostConstruct
public void init() {
commandBus = new BasicCommandBus();
// Do some stuff to configure the command bus
}
@Produces
public CommandBus produceCommandBus() {
return commandBus;
}
}
我遇到的问题是当我部署应用程序 GlassFish 时返回以下错误消息:
Exception while loading the app : CDI deployment failure:WELD-001409 Ambiguous dependencies for type [CommandBus] with qualifiers [@Default] at injection point [[BackedAnnotatedField] @Inject private myapp.web.ToDoItemCommandController.commandBus]. Possible dependencies [[Producer Method [CommandBus] with qualifiers [@Any @Default] declared as [[BackedAnnotatedMethod] @Produces public myapp.core.cdi.CommandBusFactory.produceCommandBus()], Managed Bean [class myapp.core.commandhandling.BasicCommandBus] with qualifiers [@Any @Default]]]
我可以通过将 @Alternative
注释添加到 BasicCommandBus 类来解决这个异常,但这似乎不是解决问题的最佳方法。
我不想在将 CommandBus
注入(inject)我的应用程序的所有地方都添加限定符,因为使用不同的 CommandBus
实现需要在多个地方更改代码。目的是工厂的更高版本将读取配置文件,并根据配置文件中的值创建不同类型的 CommandBus
。
我已经阅读了这个问题的答案 ( https://stackoverflow.com/a/18782027/1274662 ) 并理解为什么会抛出 Ambiguous dependencies 异常,但我不知道的是处理有两个可能的 bean 的最佳方法考虑到我想决定使用哪个实现以及如何在中央位置对其进行初始化。
我的问题是:
在
BasicCommandBus
类上使用@Alternative
注释是正确的方法吗?我应该使用更好的方法将
ApplicationScoped
bean(即CommandBus
)的相同实例注入(inject)到我的应用程序的多个位置,同时控制创建哪个实现(即BasicCommandBus
或EnhancedCommandBus
)以及如何在中央位置对其进行初始化?
最佳答案
如果您希望您的 bean 只能由生产者注入(inject),您可以使用 @Vetoed
注释 BasicCommandBus
和 EnhancedCommandBus
这样您就可以在 bean 本身和生产者方法之间没有歧义,并且在每个注入(inject)点,生产者将注入(inject)实例。
关于java - 使用 CDI 生产者会导致不明确的依赖项异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29447182/