Die AOP-Bibliothek (Aspect-Oriented Programming) AspectJ ist nützlich, um Methodenaufrufe abzufangen und beliebige Verarbeitung in eine JVM-Umgebung und Frames einzufügen. Es wird häufig als Arbeitsimplementierung verwendet.
Beispielsweise gibt es einige Fälle, in denen AspectJ (CGLIB-Proxy [^ cglib]) verwendet wird, um Transaktionen mit der Annotation "@ Transactional" zu realisieren, selbst im Bereich der Verwendung des Spring Framework [^ aop-impl].
[^ cglib]: Obwohl es in den offiziellen Spring-Dokumenten als "CGLIB-Proxy" ausgedrückt wird, bezieht es sich auf AspectJ (GCLIB ist der Name der von AspectJ intern verwendeten Codegenerierungsbibliothek).
[^ aop-impl]: Spring verwendet standardmäßig java.lang.reflect.Proxy. lang / reflektieren / Proxy.html) kann nur für die Schnittstelle AOP sein, und es gibt viele Fälle, in denen AspectJ aufgrund seiner Einschränkungen verwendet wird.
Das weit verbreitete AspectJ ist eigentlich nützlich, aber in Projekten, in denen es funktioniert ** "My @ Transactional
wird nach stundenlangem Ausprobieren ignoriert ... warum ...!" Ich hörte den traurigen Schrei von ** viele Male an verschiedenen Orten.
Wenn Sie im Frühjahr die Kapitel des offiziellen Dokuments Kapitel 6. Aspektorientierte Programmierung mit Spring lesen, wird auch der Hintergrund angezeigt Ich kenne alle Arbeitsprinzipien und möglichen Optionen, aber wenn Sie Probleme mit ** "Ich möchte mein AOP jetzt verschieben !!" ** haben, siehe unten:
AOP funktioniert nicht, wenn die folgenden Bedingungen erfüllt sind:
Lassen Sie uns das Überschreiben ermöglichen.
Gemeinsame Muster:
this. Method ()
aufgerufenreturn this;
ausgeführtAspectJ erreicht AOP durch die folgenden Schritte:
[^ override]: Deshalb muss die Zielmethode überschreiben können
Der wichtige Punkt ist, dass ** AspectJ eine andere Klasse und ihre Instanz (Wrapper) erstellt, die von der von Ihnen geschriebenen Klasse erbt **.
Wenn Sie also eine Methode für eine Instanz des Wrappers aufrufen, funktioniert AOP. Wenn Sie jedoch eine Methode für eine Instanz der ursprünglichen Klasse aufrufen, funktioniert AOP überhaupt nicht.
Die Problemumgehung besteht darin, die Instanz, von der aus die Methode aufgerufen wird, aus dem Framework abzurufen (das sich um AspectJ kümmert).
Die spezifische Problemumgehung für das oben erwähnte "2)" Muster lautet beispielsweise wie folgt:
this. Method ()
aufgerufen
--das
in der Methode Ihrer Klasse ist kein Wrapper, sondern eine Originalinstanzreturn this;
ausgeführtWie diejenigen, die bisher alle Erklärungen gelesen haben, bereits wissen, kommt es auf das einfache Prinzip an, dass ** AspectJ die Methode aufruft, ohne den durch Vererbung / Überschreibung generierten Wrapper zu durchlaufen **.
In Artikeln auf der Welt gibt es Zeiten, in denen es eine Erklärung und Aufzählung gibt, dass "AspectJ in diesem Fall, in einem solchen Fall, in einem solchen Fall nicht gut funktioniert", und als ich das sah, "Was für eine komplizierte mysteriöse Bibliothek. Ich habe Leute gesehen, die viele Male verzweifelt waren, aber im Wesentlichen ist es nur dieses Problem (ich werde das wahrscheinlich in Zukunft erklären, also der Text Ich habe es zusammengefasst in).
Auch wenn die bisher genannten spezifischen Beispiele nicht direkt zutreffen, können Sie die Ursache wahrscheinlich finden, indem Sie an das in diesem Artikel erwähnte Funktionsprinzip von AspectJ denken.
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.
Obwohl dies für das Thema dieses Artikels nicht relevant ist, setzt Spring's "@ Transactional" standardmäßig keine Überprüfungsausnahmen (z. B. "IOException") zurück, sodass "Die Transaktion wurde festgeschrieben, obwohl eine Ausnahme aufgetreten ist. Es gibt oft eine Geschichte mit der Aufschrift "Ta!" Daher gibt es ein gewisses Know-how, dass es weniger verwirrend ist, "rollbackFor" explizit anzugeben.
Recommended Posts