La bibliothèque de programmation orientée aspect (AOP) AspectJ est utile pour intercepter les appels de méthode et insérer des traitements arbitraires dans un environnement JVM et des cadres. Il est souvent utilisé comme une mise en œuvre de travail.
Par exemple, il y a pas mal de cas où AspectJ (proxy CGLIB [^ cglib]) est utilisé pour réaliser des transactions avec l'annotation @ Transactional
même dans le domaine où Spring Framework est utilisé [^ aop-impl].
[^ cglib]: Bien qu'il soit appelé "proxy CGLIB" dans la documentation officielle de Spring, il fait référence à AspectJ (GCLIB est le nom de la bibliothèque de génération de code utilisée en interne par AspectJ).
[^ aop-impl]: Spring utilise par défaut [java.lang.reflect.Proxy](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/ lang / reflect / Proxy.html) ne peut être AOP que pour l'interface, et il existe de nombreux cas où AspectJ est utilisé en raison de ses restrictions.
Le AspectJ largement utilisé est en fait utile, mais dans les projets où il fonctionne ** "My @ Transactional
est ignoré après des heures d'essais et d'erreurs ... pourquoi ...!" J'ai entendu le triste cri de ** à plusieurs reprises sur divers sites.
Au printemps, si vous lisez les chapitres du document officiel Chapitre 6. Programmation orientée aspect avec Spring, l'arrière-plan sera également Je connais tous les principes de fonctionnement et les options possibles, mais si vous rencontrez des problèmes avec ** "Je veux déplacer mon AOP maintenant !!" **, voir ci-dessous:
Le symptôme est que l'AOP ne fonctionne pas si les conditions suivantes sont remplies:
statique
Rendons possible le dépassement.
Modèles communs:
this. Method ()
--Un appel de méthode est effectué vers le return this;
--nouvelle ta classe ()
AspectJ atteint l'AOP en suivant les étapes suivantes:
[^ override]: c'est pourquoi la méthode cible doit pouvoir remplacer
Le point important est que ** AspectJ crée une autre classe et son instance (wrapper) qui hérite de la classe que vous avez écrite **.
Donc, si vous appelez une méthode sur une instance du wrapper, AOP fonctionnera, mais si vous appelez une méthode sur une instance de la classe d'origine, AOP ne fonctionnera pas du tout.
La solution de contournement consiste à obtenir l'instance à partir de laquelle la méthode est appelée à partir du framework (qui prend en charge AspectJ).
Par exemple, la solution de contournement spécifique pour le modèle «2)» mentionné ci-dessus est la suivante:
this. Method ()
--this
dans la méthode de votre classe n'est pas un wrapper, mais une instance originalethis
(= vous obtiendrez un wrapper pour AspectJ)
--Un appel de méthode est effectué vers le return this;
this
--nouvelle ta classe ()
--Laissez le framework créer l'instance (définie comme Bean / Component dans Spring)Comme ceux qui ont lu toutes les explications jusqu'à présent le savent déjà, cela revient au principe simple que ** AspectJ appelle la méthode sans passer par le wrapper généré par héritage / remplacement **.
Dans les articles dans le monde, il y a des moments où il y a une explication et une énumération que "AspectJ ne fonctionne pas bien dans ce cas, dans un tel cas, dans un tel cas", et quand j'ai vu cela, "Quelle bibliothèque mystérieuse compliquée. J'ai vu des gens désespérés à plusieurs reprises, mais en substance, c'est juste ce problème (je vais probablement l'expliquer à l'avenir, donc le texte Je l'ai résumé en).
Même si les exemples spécifiques évoqués jusqu'à présent ne s'appliquent pas directement, vous pouvez probablement en trouver la cause en pensant au principe de fonctionnement d'AspectJ évoqué dans cet article.
@ Transactional
By default, a transaction will be rolling back on RuntimeException and Error but not on checked exceptions (business exceptions). See DefaultTransactionAttribute.rollbackOn(Throwable) for a detailed explanation.
Bien que sans rapport avec le sujet de cet article, «@ Transactional» de Spring ne supprime pas les exceptions de vérification (par exemple, «IOException») par défaut, donc «la transaction a été validée même si une exception s'est produite. Il y a souvent une histoire qui dit "Ta!"
Par conséquent, il existe un certain savoir-faire pour lequel il est moins déroutant de spécifier explicitement rollbackFor
.
Recommended Posts