Die Zeiten können kommen? Aspektorientierte Programmierung, was ist die Sprache von Aspekt J wurde zusammengefasst und über Punktschnitte beschrieben, aber es gab mehr Punktschnitte als ich erwartet hatte. Es ist lang und schwer zu verstehen, und es scheint, dass in AspectJ Punktkürzungen implementiert sind, also habe ich beschlossen, es zu teilen. Bitte beachten Sie, dass es in Dogmatismus und Vorurteile unterteilt war.
Die statische Initialisierung wird für Punktschnitte bereitgestellt, die sich auf statische Initialisierer beziehen Stellt die "Zeit" dar, zu der ein statischer Initialisierer aufgerufen und ausgeführt wird, der ein Typmuster als Argument verwendet und das statische Feld der Klasse initialisiert.
Sample.java
//Schreiben Sie den Klassennamen direkt oder verwenden Sie Platzhalter
staticinitialization(Session+)
Wird auch als statischer Initialisierer oder Klasseninitialisierer bezeichnet Eine spezielle Methode, die für jede Klasse deklariert wird, um den Wert eines statischen Felds zu initialisieren
staticInitializer.java
static {
//Code, der den Wert eines statischen Feldes initialisiert
}
Punktschnitte können mit Operatoren kombiniert werden Seien Sie jedoch vorsichtig, da der Aufruf die Ausführung wie in der obigen Abbildung gezeigt zu verpacken scheint. Rufen Sie daher && exectuion und auf Auch wenn es wie der folgende Code aussieht, ist es tatsächlich anders
Sample.java
class Sample {
Sample() {
Main.init()
}
}
class Main {
static void init() {
hoge();
}
static int length() {
return hoge
}
}
Wie in der folgenden Abbildung gezeigt, gibt die Ausführung den hellblauen Teil (den Teil außerhalb des Verbindungspunkts) an, und der Aufruf befindet sich im grünen Teil. && Bedingung wird niemals wahr
Aber was ist, wenn Sie eine solche Bedingung erstellen möchten? Zusätzlich zur Auswahl eines bestimmten Verbindungspunkttyps für die Lösung bieten wir auch einen primitiven Punktschnitt an, der den Verbindungspunkt basierend auf der Position im Programm auswählt.
: black_small_square: ** innerhalb (Typmuster) ** Wählen Sie alle Verknüpfungspunkte aus, die in Klassen- oder Schnittstellendeklarationen vorkommen, die dem Typmuster entsprechen Jede Art von Verbindungspunkt
: black_small_square: ** Withincode (Methodenmuster) ** oder ** Withincode (Konstruktormuster) ** Wählen Sie alle Verknüpfungspunkte aus, die im Hauptteil der Methode oder des Konstruktors auftreten und mit dem Argumentmuster übereinstimmen Jede Art von Verbindungspunkt
Mithilfe der obigen Informationen können Sie angeben, dass es sich um eine bestimmte Klasse oder Methode handelt.
Es gibt zwei Punktkürzungen in Bezug auf den Geschäftsfluss, ** Fluss ** und ** Fluss unten **. Nehmen Sie einen Punktschnitt als Argument, um "Zeit" darzustellen.
Sample.java
cflow(call(void Main.init()))
:black_small_square:cflow Wählt alle Verbindungspunkte aus, die zwischen dem Anfang und dem Ende des Verbindungspunkts P auftreten, der durch den Punktschnitt des Arguments ausgewählt wurde. cflow wählt den Verknüpfungspunkt P aus, der durch den Punktschnitt des Arguments ausgewählt wird
:black_small_square:cflowbelow Fast das gleiche wie cflow, aber im Gegensatz zu cflow wird der durch den Punktschnitt des Arguments ausgewählte Verbindungspunkt P nicht ausgewählt
withincode
withincode.java
call(void Main.hogeB()) && withincode(void Main.init())
Da Withincode ein Verknüpfungspunkt ist, der im Hauptteil der Methode auftritt, der dem Argumentmuster entspricht In diesem Fall wird nur der Verknüpfungspunkt aufgerufen, an dem die Methode main.hogeA aufgerufen wird Es gibt also keine Übereinstimmung für den Aufruf (void Main.hogeB ())
cflow
cflow.java
call(void Main.hogeB()) && cflow(call(void Main.init()))
Da cflow alle Verbindungspunkte auswählt, die zwischen dem Anfang und dem Ende des Verbindungspunkts P auftreten, der durch den Punktschnitt des Arguments ausgewählt wird. In diesem Fall der Verknüpfungspunkt, an dem die Methoden main.hogeA und main.hogeB aufgerufen werden Daher gibt es etwas, das mit call übereinstimmt (void Main.hogeB ()).
Der Aufrufpunktschnitt wählt das "Wann" aus, wenn die im Methodenmuster angegebene Methode als Verbindungspunkt aufgerufen wird. Dieser Verknüpfungspunkt gilt nicht nur für Methoden, sondern auch für Methodenaufrufe, die in der Aspektdefinition angezeigt werden. Dies gilt auch für andere Punktschnitte als Aufruf.
Hello.java
impoort java.io.*;
aspect Tracer {
pointcut tracedMethods(): call(* PrintStream.println(..));
before(): tracedMethods() {
System.out.println("** method call");
}
}
public class Hello {
public static void say() {
System.out.println("Hello");
}
public static void main(String[] args) {
say();
}
}
Das Schreiben eines Programms wie dem oben genannten würde zu einer Endlosschleife führen
Um dieses Problem zu vermeiden, gibt es ** Hinweisausführung ** im beratungsbezogenen Punktschnitt Stellt die "Zeit" dar, zu der der Text eines Hinweises ohne Argumente ausgeführt wird
Sample.java
!cflow(adviceexecution())
//Wählen Sie alle Verbindungspunkte aus, außer während Sie die Ratschläge ausführen
Es gibt drei Pointcuts, die sich auf Kontextinformationen zur Programmausführung beziehen: ** this **, ** target ** und ** args **.
:black_small_square:this Wählen Sie alle Verknüpfungspunkte aus, die im Hauptteil einer Methode oder eines Konstruktors auftreten, die von einer Instanz eines Typs (einschließlich Unterklassen und Unterschnittstellen) ausgeführt werden, die dem Argument pointcut entspricht Jede Art von Verbindungspunkt
:black_small_square:target Wählen Sie alle Methodenaufrufe und Feldzugriffe für Instanzen von Typen (einschließlich Unterklassen und Unterschnittstellen) aus, die den Pointcut-Argumenten als Verknüpfungspunkte entsprechen. Jede Art von Verbindungspunkt
:black_small_square:args Wählen Sie einen Methoden- oder Konstruktoraufruf aus, der ein Argument des Typs, der dem pointcut-Argument entspricht, als Verknüpfungspunkt verwendet.
Wählen Sie einen Verknüpfungspunkt aus, wenn die Klasse des Objekts, auf das diese Variable zeigt, mit dem Argument pointcut übereinstimmt
Sample.java
call(* *(..)) && this(Session)
//Das Obige wählt den Aufruf einer beliebigen Methode aus den Methoden der Session-Klasse oder ihrer Unterklasse als Join-Punkt aus.
Wählen Sie einen Verknüpfungspunkt aus, wenn er mit dem Klassentyp des aufgerufenen Objekts oder des Feldzugriffs und dem Argument pointcut übereinstimmt
Sample.java
class Session {}
class BookSession extends Session{}
Sample.java
call(* Session.*(..)) && target(BookSession)
//Das Obige wird nur als Verbindungspunkt ausgewählt, wenn ein BookSession-Objekt unter den in der Session-Klasse deklarierten Methoden aufgerufen wird.
Session s = new BookSession(301);
s.doIt();
Sample.java
call(* *(..)) && args(BookSession, ..)
//Wählen Sie einen Methodenaufruf als Verknüpfungspunkt aus, dessen erstes Argument eine Instanz der BookSession-Klasse ist
Beachten Sie, dass der Argumentschnitt von args beim Nachschlagen des Typs auch den tatsächlichen Typ des Argumentobjekts verwendet.
Recommended Posts