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

Using a CDI producer causes ambiguous dependencies exception

我需要将 ApplicationScoped bean 的相同实例注入到我的应用程序的多个位置,并创建了以下使用 @PostConstruct 注释进行初始化的工厂 class bean 和 @Produces 注释 return 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 时 return 出现以下错误消息:

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 class 来克服这个异常,但这似乎不是解决问题的最佳方法。

我不想在我将 CommandBus 注入我的应用程序的任何地方添加限定符,因为使用 CommandBus 的不同实现需要在多个地方更改代码。目的是工厂的更高版本将读取配置文件,并根据配置文件中的值创建不同类型的 CommandBus.

我已经阅读了这个问题的答案 () 并理解为什么会抛出 Ambiguous dependencies 异常,但我不知道的是处理以下事实的最佳方法有两个考虑到我想决定使用哪个实现以及如何在中央位置初始化它,可以注入的可能 bean。

我的问题是:

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

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

如果你希望你的 bean 只能由生产者注入,你可以用 @Vetoed 注释 BasicCommandBusEnhancedCommandBus 这样你就不会在 bean 之间产生歧义了self 和生产者方法,在每个注入点,生产者将注入实例。