问题
I have a requirement to Inject the same instance of an ApplicationScoped
bean into several places of my application and have created the following factory class which uses the @PostConstruct
annotation to initialize the bean and the @Produces
annotation to return the same instance of the 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;
}
}
The problem I've got is when I deploy the application GlassFish returns the following error message:
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]]]
I can overcome this exception by adding the @Alternative
annotation to the BasicCommandBus class, however this doesn't seem to be the best way of solving the problem.
I don't want to add a qualifier everywhere that I inject CommandBus
into my application as using a different implementation of CommandBus
would require changing the code in multiple places. The intention is that a later version of the factory will read a configuration file and depending upon a value in the configuration file it may create a different type of CommandBus
.
I have read the answer to this question (https://stackoverflow.com/a/18782027/1274662) and understand why the Ambiguous dependencies exception is being thrown but what I don't know is the best way to deal with the fact that there are two possible beans that could be injected given that I want to decide which implementation is used and how it is initialised in a central location.
The questions I've got are:
Is using the
@Alternative
annotation on theBasicCommandBus
class the right approach?Is there a better approach that I should be using to Inject the same instance of an
ApplicationScoped
bean (i.e.CommandBus
) into several places of my application whilst controlling which implementation created (i.e.BasicCommandBus
orEnhancedCommandBus
) and how it is initialised in a central location?
回答1:
If you want your bean to be injectable only by the producer you can annotate BasicCommandBus
and EnhancedCommandBus
with @Vetoed
this way you'll not have the ambiguity between the bean it self and the producer method and at every injection point it's the producer that will inject the instance.
来源:https://stackoverflow.com/questions/29447182/using-a-cdi-producer-causes-ambiguous-dependencies-exception