Préface
Cet article présente principalement le contenu pertinent sur la recherche (injection de méthode) au printemps. Il est partagé pour votre référence et votre apprentissage. Je ne dirai pas beaucoup en dessous. Jetons un coup d'œil à l'introduction détaillée ensemble:
Cela peut se produire lors de l'utilisation du printemps: un haricot singleton dépend d'un autre haricot non-Singleton. Si vous utilisez simplement l'assemblage automatique pour injecter des dépendances, certains problèmes peuvent survenir, comme indiqué ci-dessous:
Classe A pour singleton
@Componentpublic classa classa {@autowired private classbbBB; public void printclass () {System.out.println ("Ceci est la classe A:" + ceci); classb.printClass (); }}Classe B pour non-single
@ Composant @ scope (value = scope_prototype) classe publique classb {public void printclass () {System.out.println ("Ceci est la classe B:" + ceci); }} Ici, la classe A adopte la portée de Singleton par défaut et s'appuie sur la classe B. La portée de la classe B est le prototype, donc ce n'est pas un singleton. Pour le moment, vous pouvez voir le problème de l'écriture comme celle-ci après avoir exécuté un test:
@Runwith (springrunner.class) @contextconfiguration (classes = {classa.class, classb.class}) public class myTest {@autowired private classa classa; @Test public void simplest () {for (int i = 0; i <3; i ++) {classa.printClass (); }}}Le résultat de la sortie est:
C'est la classe A: classa @ 282003e1
Ceci est la classe B: classb @ 7fad8c79
C'est la classe A: classa @ 282003e1
Ceci est la classe B: classb @ 7fad8c79
C'est la classe A: classa @ 282003e1
Ceci est la classe B: classb @ 7fad8c79
Comme vous pouvez le voir, le code de hachage des deux classes est le même dans les trois sorties. Il est compréhensible que la valeur de la classe A reste inchangée car c'est un singleton, mais la portée de la classe B est un prototype mais maintient également le code de hachage inchangé, qui semble être devenu un singleton?
La raison de cette situation est que la portée de la classe A est le singleton par défaut, donc le contexte ne créera qu'une seule fois de la classe A, il n'y a donc qu'une seule chance d'injecter des dépendances, et le conteneur ne peut pas fournir la classe A avec une nouvelle classe B à chaque fois.
Pas si bonne solution
Pour résoudre le problème ci-dessus, vous pouvez apporter des modifications à la classe A pour implémenter ApplicationContextAware.
@ComponentPublic Class Classa implémente ApplicationContextAware {private applicationContext ApplicationContext; public void printclass () {System.out.println ("Ceci est la classe A:" + ceci); getClassB (). printClass (); } public classb getClassB () {return applicationContext.getBean (classb.class); } public void setApplicationContext (ApplicationContext ApplicationContext) lève BeanSException {this.ApplicationContext = applicationContext; }}De cette façon, vous pouvez trouver manuellement un nouveau bean dans le contexte chaque fois que vous devez aller en classe B. Après avoir exécuté un autre test, j'ai obtenu la sortie suivante:
Ceci est la classe A: com.devhao.classa@4df828d7
Ceci est la classe B: com.devhao.classb@31206beb
Ceci est la classe A: com.devhao.classa@4df828d7
Ceci est la classe B: com.devhao.classb@3e77a1ed
Ceci est la classe A: com.devhao.classa@4df828d7
Ceci est la classe B: com.devhao.classb@3ffcd140
Vous pouvez voir que le code de hachage de la classe A reste inchangé dans les trois sorties, tandis que la classe B est différente à chaque fois, ce qui montre que le problème a été résolu et que la nouvelle instance est utilisée à chaque fois qu'elle est appelée.
Cependant, cette méthode d'écriture est fortement associée au printemps, et le printemps fournit un autre moyen de réduire l'invasivité.
@Chercher
Spring fournit une annotation appelée @lookup, qui est une annotation qui fonctionne sur la méthode. La méthode marquée par elle sera remplacée. Ensuite, selon le type de sa valeur de retour, le conteneur appelle la méthode getBean () du beanfactory pour retourner un haricot.
@Componentpublic classa classa {public void printclass () {System.out.println ("Ceci est la classe A:" + ceci); getClassB (). printClass (); } @Lookup public classb GetClassB () {return null; }} On peut constater qu'il est beaucoup plus simple et plus fortement couplé au printemps. L'exécution du test peut toujours obtenir la sortie correcte.
La valeur de retour de la méthode annotée n'est plus importante, car le conteneur générera dynamiquement une sous-classe, puis réécrit / implémenter la méthode annotée, et la méthode de sous-classe est finalement appelée.
La méthode @lookup utilisée doit se conformer à la signature suivante:
<public | protégé> [Résumé] <Tour-Type> THETHODNAME (sans arguments);
Résumer
Ce qui précède est l'intégralité du contenu de cet article. J'espère que le contenu de cet article a une certaine valeur de référence pour l'étude ou le travail de chacun. Si vous avez des questions, vous pouvez laisser un message pour communiquer. Merci pour votre soutien à wulin.com.