Aperçu
Dans l'article précédent, il est présenté que si vous vous injectez dans un haricot, si vous avez @async et @transaction, si vous vous injectez avec @Autowire, vous signalerez une dépendance circulaire. Si vous vous injectez avec BeanfactoryAware, @Transaction sera invalide. Par exemple:
@ServicePublic class MyService implémente beanfactoryAware {private myService self; // L'annotation des transactions est invalide @Transactional public void notwork () {...} @async public future async () {...} @Override public void SetBeanFactory (beanfactory beanfactory) lance Beansexception {self = beanfactory.getBean (mysvice.class); }}Je viens de le mentionner brièvement à ce moment-là, et cet article est de découvrir pourquoi il a échoué.
Général
Les conditions suivantes doivent être remplies dans la situation ci-dessus:
Le résultat est: à l'exception de @async, l'annotation prend effet, et aucun autre ne prend effet, comme le montre la figure ci-dessous
Le proxy normal doit être la figure suivante:
raison
La première chose qui me vient à l'esprit est que la méthode de traitement de l'annotation @async peut être différente des autres. Dans la mise en œuvre d'AsyncannotationBeanPostProcessor (le code spécifique est dans sa classe parent AbstractAdviseBeanPostProcessor), un problème a été trouvé,
Dans des circonstances normales, le haricot qui arrive est déjà une classe de procuration dynamique qui est procassée, et lorsqu'elle échoue, la classe réelle qui arrive est en effet, comme le montre la figure ci-dessous:
Ensuite, après avoir analysé le code, s'il s'agit d'une classe réelle, lorsqu'elle atteint la ligne 69, elle renvoie vrai et ajoute le conseiller d'Aysnc au principe dynamique. S'il s'agit d'une classe réelle, lorsqu'elle atteint la ligne 83, elle créera une classe de proxy et ajoutera uniquement le conseiller d'Aysnc au proxy dynamique, donc @transaction sera invalide.
Pourquoi les agents ne sont-ils pas venus?
En fait, la seule différence est de savoir si vous vous êtes obtenu via BeanfactoryAware. Alors pourquoi utilisez-vous BeanFactory pour vous procurer, et alors vous n'êtes pas un proxy dans lepostprocessor ultérieur? Si vous connaissez le mécanisme de chargement de Spring @Transaction, vous saurez que la création de proxy dynamique telle que @Transaction et @Retryable Annotations est créée dans AnnotationAwaReaspectJautoproxyCreator. Grâce à Debug, nous avons constaté qu'après avoir traversé AnnotationawaReaspectJautoproxycreator, notre proxy dynamique n'a pas été ajouté.
Jetons un coup d'œil à la mise en œuvre dans AnnotationAwaReaspectJautoproxyCreator, mais après cela, aucune classe de procuration n'a été générée. La raison en est qu'il y a "MyService" dans la carte exposée à l'avance.
Quand a-t-il été exposé? En fait c'est
@OverridePublic void SetBeanFactory (beanfactory beanfactory) lève BeanSexception {self = beanfactory.getBean (MyService.class);}Ensuite, tout est apparu. Dans le cas MyService, BeanfactoryAware a été déclenché et une classe de proxy a été créée via beanfactory.getBean (MyService.class); (Conseils: la classe de proxy actuelle ne contient pas Adivisor d'Async), car le printemps crée en fait le bean MyService et n'a pas encore été mis dans le beanfactory. Ensuite, nous avons déclenché Beanfactory.getBean (MyService.class); Dans ce processus, nous avons créé le proxy et retourné, et l'avons rejoint à la carte exposée à l'avance. Cela conduit à une série de problèmes qui ont suivi. C'est un peu emmêlé. Parlez à l'image:
Normalement, le processus suivant devrait être:
C'est le cas avec une situation anormale
résumé
Dans des circonstances normales, utilisez @Autowire pour injecter (si Autowire est utilisé, la situation ci-dessus lancera directement la dépendance circulaire). Bien sûr, s'il y a un problème, vous ne pouvez pas le laisser partir. Vous devez connaître la raison et la raison!
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.