2017-08-14 10 views
0

J'ai 2 haricots.WELD-001409: Dépendances ambiguës pour le type T avec qualificatifs @Default

Le premier est le modèle que j'utilise en production, Model.

@Named("model") 
@RequestScoped 
public class Model{ 

} 

Le second est l'extension de Model que j'utilise pour les tests.

@Named("modelTest") 
@RequestScoped 
public class ModelTest extends Model{ 

} 

Comment puis-je forcer CDI pour sélectionner Model par défaut?

+0

Un test ne devrait pas étendre la classe qu'il teste de toute façon. – Tom

+0

ce n'est pas un test de junit. C'est un test différent. test personnalisé pour les composants Web. mais ça ne devrait pas avoir d'importance. parce que ce problème se poserait si j'avais simplement 2 implémentations d'une interface. – user2914191

+1

Jetez un oeil à [https://dzone.com/articles/java-ee6-cdi-named-components] – Egl

Répondre

1

Puisque vous voulez changer le bean 'par défaut' pour un type donné et que vous ne voulez pas utiliser de qualificateurs, je suppose que le bean original ne doit pas être injecté n'importe où. Par conséquent, ce que vous êtes probablement après est soit une alternative ou une spécialisation.

Si nous parlons de alternatives, vous devez marquer le nouveau haricot avec @Alternative annotation et aussi « select » - ce qui peut être fait sur une base d'archives haricots en beans.xml ou tout simplement à l'échelle mondiale avec @Priority(int). Voici un extrait de code:

@Named("modelTest") 
@RequestScoped 
@Alternative 
@Priority(1) // "activates"/selects the alternative 
public class ModelTest extends Model{ 
} 

une alternative choisie, chaque fois que vous injectez le type précédent (Model), CDI au lieu d'injecter cette alternative (ModelTest), car il correspond au point d'injection ainsi.

L'option secondaire est la spécialisation. Il est très similaire aux alternatives mais plus strict de manière à ce que le bean d'origine soit 'mis au rebut', vous pouvez en lire plus à ce sujet dans CDI spec. La spécialisation vient également avec l'héritage de qualificateur et de nom de bean (pas cependant la portée!). Il n'y a pas non plus besoin de sélectionner le bean (par opposition aux alternatives). Voici le code:

@RequestScoped 
@Specializes 
public class ModelTest extends Model{ 
    // bean name with be inherited automatically as "model" 
} 

Notez qu'un bean ne peut avoir qu'un seul nom de bean à la fois, conformément aux spécifications. Par conséquent, si vous héritez d'un nom et en déclarez un autre, vous obtiendrez des erreurs - modifiez votre code en conséquence.