CDI Dépendance ambiguë avec @Produces - pourquoi?
Je suis aide d'un code comme ci-dessous:
public Configuration {
private boolean isBatmanCar = someMethod(...);
@Produces
public Car getCar(@New Car car) {
if(isBatmanCar) {
car.setName("BatmanCar");
}
return car;
}
}
public Car {
private String name = "NormalCar";
public void setName(String name) {
this.name = name;
}
}
public Demo {
@Inject
Car car;
//rest of code
}
Quand j'déployer une application de glassfish (Java EE 6 btw), j'ai
AmbiguousResolutionException: WELD-001318 Cannot resolve an ambiguous dependency between (...) Car with qualifiers [@Any @Default] (...) Producer Method [Car] with qualifiers [@Any @Default]
Je sais que quand j'ajoute @Alternative
de classe car cela va fonctionner, mais je me demande si c'est la bonne façon de le faire, et pourquoi dois-je faire?
Pouvez-vous me dire quelle est la bonne utilisation de @Produit dans de tels cas?
Je suis à l'aide de Java EE 6, CDI 1.0, EJB 3.1, Glassfish 3.2
source d'informationauteur dmydlarz
Vous devez vous connecter pour publier un commentaire.
L'erreur vient du fait que vous avez 2 haricots de type
Car
l'un étant la classe, l'autre étant le producteur. Vous avez 2 solutions évidentes à résoudre l'ambiguïté:Tout d'abord, vous mettez la logique derrière
isBatmanCar
champ dans la classe d'origine (dans un constructeur ou un@PostConstruct
méthode par exemple) et supprimer votre producteur. Qui aurait laissé qu'uneCar
bean.Ou si vous voulez vraiment avoir 2 haricot ou ne peut pas éviter cela, vous devez créer un qualificatif pour votre produit bean:
et l'utiliser sur le producteur,
pour être en mesure d'injecter le type de voiture
Qualificatif est l'option naturelle pour résoudre ambigu injection. À l'aide de
@Alternative
fonctionne aussi mais c'est plus un truc ici que d'une bonne pratique.Dernière remarque:
@New
n'est pas nécessaire ici, depuis votreCar
bean a pas de portée (donc@Dependent
étendue). @Nouvelle n'est utile que lorsqu'un producteur injecter un haricot avec une portée qui n'est pas@Dependent
. Cela dit, ce code n'est pas très utile si votreCar
classe est portée@Dependent
.À l'aide de @Alternative fonctionne, mais doit uniquement être utilisé si vous voulez être en mesure de l'activer par le biais de beans.xml.
Supprimant le constructeur par défaut de votre bean fonctionne aussi mais vous ne serez pas en mesure d'utiliser votre bean dans un autre champ que @RequestScoped.
À l'aide de votre propre qualificatif fonctionne mais n'est pas très utile si vous n'avez qu'une mise en œuvre et veulent juste être en mesure d'instancier votre bean avec un producteur plutôt qu'avec son constructeur.
La façon la plus simple est d'annoter vos haricots @Tous :
Choses que vous devez garder à l'esprit :
Concernant tout cela, le même code que ci-dessus explicitement qualifiés ressemble à ceci :
Il devient de plus en plus évident que la fève du constructeur par défaut n'est pas valide possibilité pour le point d'injection et le producteur est valide possibilité.
Une autre possibilité serait de créer le constructeur par défaut de la classe de Voiture comme ceci:
par la suppression de constructeur par défaut, la Voiture de classe ne peut plus être utilisé pour créer des instances utilisées par injection.
Et de changer votre producteur méthode pour
alors producteur de la méthode serait la seule façon de créer vos Voitures.
Ce moyen peut être utilisé, quand on sait qu'on aura toujours besoin de personnalisé instance et vous n'avez pas besoin de constructeur par défaut. Mais généralement, Antoine solution est plus utile.