Personnalisé Autowire candidat haricots au Printemps 3
Dire que j'ai la structure suivante avec une interface de service ServiceInterface
et un couple de composants de mise en œuvre: ProductAService
et ProductBService
j'ai aussi un RequestContext
bean qui a une qualification de la propriété qui dit que nous sommes-dire en cours de traitement ProductA ou Produitb. Comment puis injecter automatiquement avec permettra à l'autowiring ou d'autres annotation de la mise en œuvre correcte (ProductAService ou ProductBService) dans certains services qui en ont besoin (ServiceThatNeedsServiceInterface
ci-dessous).
public interface ServiceInterface {
void someMethod();
}
@Component(name="ProductAService")
public class ProductAService implements ServiceInterface {
@Override public void someMethod() {
System.out.println("Hello, A Service");
}
}
@Component(name="ProductBService")
public class ProductBService implements ServiceInterface {
@Override public void someMethod() {
System.out.println("Hello, B Service");
}
}
@Component
public class ServiceThatNeedsServiceInterface {
//What to do here???
@Autowired
ServiceInterface service;
public void useService() {
service.someMethod();
}
}
@Component
@Scope( value = WebApplicationContext.SCOPE_REQUEST )
public class RequestContext {
String getSomeQualifierProperty();
}
Vous devez vous connecter pour publier un commentaire.
Source se référant à votre question lorsqu'ils ont créé le ServiceLocatorFactoryBean de retour en version 1.1.4. Pour l'utiliser, vous devez ajouter une interface similaire à celui ci-dessous:
Vous devez ajouter le code suivant à votre applicationContext.xml
Maintenant votre ServiceThatNeedsServiceInterface sera semblable à celui ci-dessous:
ServiceLocatorFactoryBean sera de retour le service basé sur le RequestContext qualificatif.
En dehors de printemps annotations votre code n'est pas en dépendait du Printemps.
J'ai exécuté la suite de test unitaire pour les ci-dessus
La console d'affichage
Bonjour, Un Service
Bonjour, B Service De
Un mot d'avertissement. La documentation de l'API états qui
“Ce service locators ... sera généralement utilisé pour le prototype de haricots, c'est à dire pour l'usine de méthodes qui sont censés renvoyer une nouvelle instance pour chaque appel... Pour singleton haricots, direct setter ou le constructeur de l'injection de la cible, la fève est préférable.”
Je ne comprends pas pourquoi cela peut causer un problème. Dans mon code il renvoie le même service sur deux séquences d'appels à serviceThatNeedsServiceInterface.useService();
Vous pouvez trouver le code source de mon exemple dans GitHub
La seule façon que je peux penser à faire quelque chose comme ce que vous cherchez est de créer quelque chose comme une interface factorybean qui retourne la mise en œuvre appropriée basée sur le RequestContext de la propriété. Voici quelque chose que j'ai giflé ensemble qui a le comportement que vous souhaitez:
J'ai mis un exemple de travail à l'aide de ce code sur Github. Vous pouvez cloner et de l'exécuter avec:
Puis visite
http://localhost:8080/dynamicallyInjected
de voir le résultat d'une dépendance, ethttp://localhost:8080/dynamicallyInjected?which=bob
pour voir les autres.Je suppose, que vous avez manqué l'annotation, qui dit printemps, que vous avez un service personnalisé.
Si votre solution est d'ajouter cette annotation avant le nom de la classe:
Et puis vous pouvez auto fil, mais pour utiliser le service, vous devez ajouter l'annotation Qualificatif() comme ceci:
Ou peut-être que vous avez à ajouter une annotation Qualificatif("nom de votre bean") 🙂
Cela peut vous aider:
Utilisation
OU
AutowireCapeableBeanFactory.autowireBean(Objet existingBean)
AutowireCapeableBeanFactory.autowireBeanProperties(Objet existingBean, int autowireMode, boolean dependencyCheck)
Je ne pense pas que vous pouvez le faire avec l'annotation, la raison en est, vous avez besoin d'un haricot qui est dynamique sur runtime(peut-être Un service ou B), donc @Autowire sera viré avant le bean est utilisé en tout lieu. Une solution est d'obtenir haricot de contexte lorsque vous en avez besoin.
Vous pouvez mettre d'autre logique quelque part dans la classe comme une autre fonction:
C'est dynamique, et ce pourrait être ce que vous voulez.
Vous pouvez utiliser le @Qualifier d'annotation en combinaison avec des alias. Voir un exemple de comment il est utilisé pour charger un haricot basée sur une propriété ici. Vous pouvez modifier cette approche et modifier la propriété/alias dans le requestcontext...