Использование производителя CDI вызывает исключение неоднозначных зависимостей
У меня есть требование, чтобы ввести тот же экземпляр ApplicationScoped
боб в нескольких местах моего приложения и создали следующий класс фабрики, который использует @PostConstruct
аннотация для инициализации бина и тому @Produces
аннотация для возврата того же экземпляра компонента.
@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
в мое приложение, как с использованием другой реализации CommandBus
потребует изменения кода в нескольких местах. Предполагается, что более поздняя версия фабрики будет считывать файл конфигурации и в зависимости от значения в файле конфигурации может создавать другой тип CommandBus
,
Я прочитал ответ на этот вопрос ( /questions/41513234/cdi-prodyuser-i-inektsiya/41513239#41513239) и понимаю, почему выбрасывается исключение "Неоднозначные зависимости", но то, чего я не знаю, - лучший способ справиться с тем, что Есть два возможных bean-компонента, которые могут быть введены, учитывая, что я хочу решить, какая реализация используется и как она инициализируется в центральном местоположении.
У меня есть следующие вопросы:
Использует
@Alternative
аннотация наBasicCommandBus
класс правильный подход?Есть ли лучший подход, который я должен использовать, чтобы ввести тот же экземпляр
ApplicationScoped
боб (то естьCommandBus
) в нескольких местах моего приложения, контролируя, какая реализация создала (т.е.BasicCommandBus
или жеEnhancedCommandBus
) и как это инициализируется в центральном месте?
1 ответ
Если вы хотите, чтобы ваш бин вводился только производителем, вы можете аннотировать BasicCommandBus
а также EnhancedCommandBus
с @Vetoed
таким образом, у вас не будет неоднозначности между компонентом, который он сам, и методом продюсера, и в каждой точке внедрения это будет продюсер, который будет внедрять экземпляр.