J'ai deux classes Spring Bean qui implémentent la même interface.
@Service public class Demo { @Autowired private Abc abc; } }
Les deux classes sont
@Service public class SomeClass implements abc { @Override public class getNumber() { } } @Service public class SomeClass1 implements abc { @Override public class getNumber() { } }
Dans ma classe Service .
public interface Abc() { String getNumber(); }
J'ai eu une erreur "requis un seul bean, mais 2 ont été trouvés"
Pour cette erreur, je peux avoir la chance de mettre @Primary dans le haut de l'un des bean.
Mais je n'ai qu'un moyen de dire «configuration d'un bean» en fonction de la valeur que j'obtiendrai au moment de l'exécution (à partir de la base de données).
Pouvez-vous me suggérer un moyen.
3 Réponses :
Vous pouvez télécharger automatiquement une liste d'interfaces, puis choisir la bonne. Vous pouvez écrire:
@Autowired List<Abc> abcs;
cela se traduira par une liste d'implémentations de l'interface. Dans le corps de votre méthode, vous pouvez ensuite choisir la bonne.
Deux méthodes vous permettent de câbler automatiquement l'implémentation correcte.
Remplacez le nom de votre champ auto-câblé par le même nom que la classe d'implémentation (dans camelcase)
@Autowired @Qualifier("someClass") private Abc SomeClass;
essayez de trouver une implémentation de l'interface 'Abc' avec le nom de classe 'SomeClass'.
Une autre façon est d'ajouter un nom de bean à votre annotation de service
@Service("someClass") public class SomeClass implements abc
Cela peut ensuite être câblé automatiquement comme suit
@Autowired private Abc someClass;
Êtes-vous sûr que Sping autowires interfaces comme vous l'avez décrit dans la première option? Et si un avait SomeClass1 et SomeClass2?
Je pense que le problème qu'il pose est de savoir comment configurer deux implentations et comment utiliser dynamiquement le bon bean (basé sur les données de DB). Il semble que ce soit un exemple de modèle d'usine
Code Psuedo
Class SomeFactory{ @Autowired private Abc someClass; @Autowired private Abc someClass1;// keeping bean Name same as class name would solve bean finding issue public Abc getBeanFor(String type) { if("someClass".equals(type) return someClass; return someClass1; } } Class TestClass{ @Autowired private SomeFactory factory ; private void someProcess() { // Read type from DB for data factory.getBeanFor(typeReadFromData) .process(); } }
stackoverflow.com/questions/40830548/…
Je ne comprends pas entièrement la question, mais il existe une annotation
@Qualifier
pour gérer plusieurs implémentations de spring bean.La question n'est pas claire sur ce que vous voulez. Cependant, si vous cherchez à avoir des beans basés sur des propriétés externes, vous pouvez utiliser @ConditionalOnProperty. En savoir plus sur Spring Docs pour un cas d'utilisation.