java - 使用 CDI 生产者会导致不明确的依赖项异常

标签 java jakarta-ee dependency-injection cdi

我需要将 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 的最佳方法考虑到我想决定使用哪个实现以及如何在中央位置对其进行初始化。

我的问题是:

  1. BasicCommandBus 类上使用 @Alternative 注释是正确的方法吗?

  2. 我应该使用更好的方法将 ApplicationScoped bean(即 CommandBus)的相同实例注入(inject)到我的应用程序的多个位置,同时控制创建哪个实现(即 BasicCommandBusEnhancedCommandBus)以及如何在中央位置对其进行初始化?

最佳答案

如果您希望您的 bean 只能由生产者注入(inject),您可以使用 @Vetoed 注释 BasicCommandBusEnhancedCommandBus 这样您就可以在 bean 本身和生产者方法之间没有歧义,并且在每个注入(inject)点,生产者将注入(inject)实例。

关于java - 使用 CDI 生产者会导致不明确的依赖项异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29447182/

相关文章:

java - 更新自定义 ScrollBar UI 的颜色

java.rmi.MarshalException : Failed to communicate

javascript - 使用 ES5 实现 Angular 2 ViewChild

jakarta-ee - javax.命名.NameNotFoundException : While trying to lookup 'abc' didn't find subcontext 'abc'

android - Koin 如何在 Android Activity/appcompatactivity 之外注入(inject)

c# - 为什么在此代码中使用 Func<T>?

java - 为什么 “dist/”目录下没有manifest.mf,为什么jar文件不工作?

java - 在 getResources().getIdentifier() 中显示相同的图片

java - 为什么反序列化时不使用用户定义的serialVersionUID?

java - 服务到 worker 模式 - 将数据从 Controller 传输到 View 的最佳实践