Ich denke, Sie sollten den Rat von Sotirios Delimanolis folgen und so weit wie möglich mit Spring on-board-Mitteln erhalten. Wenn Sie dann immer noch denken, dass sie unzureichend sind und Aspekte unbedingt zur Implementierung Ihrer Idee verwenden möchten, können Sie anstelle von Spring AOP AspectJ within Spring verwenden und die volle Leistungsfähigkeit von Pointcuts wie get()
und set()
nutzen, um Lese-/Schreibvorgänge für Klassenmitglieder abzufangen (sowohl statisch als auch nicht-statisch). Zum Beispiel:
Marker Anmerkung:
package de.scrum_master.app;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyAnnotation {}
Treiber Anwendung:
Die Anwendung liest (toString()
) und schreibt (Konstruktor, Hauptmethode) alle Bereiche, darunter die status
kommentierte Feld.
package de.scrum_master.app;
public class Application {
private int id;
private String name;
@MyAnnotation private String status;
public Application(int id, String name, String status) {
this.id = id;
this.name = name;
this.status = status;
}
@Override
public String toString() {
return "Application [id=" + id + ", name=" + name + ", status=" + status + "]";
}
public static void main(String[] args) {
Application application = new Application(11, "AspectJ demo", "starting");
System.out.println(application);
application.id = 22;
application.name = "AspectJ field access demo";
application.status = "running";
System.out.println(application);
application.status = "shutting down";
System.out.println(application);
application.status = "stopped";
System.out.println(application);
}
}
Richtung:
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class AnnotatedFieldAspect {
@Before("get(* *) && @annotation(de.scrum_master.app.MyAnnotation)")
public void interceptRead(JoinPoint thisJoinPoint) {
System.out.println(thisJoinPoint);
}
@Before("set(* *) && @annotation(de.scrum_master.app.MyAnnotation) && args(newValue)")
public void interceptWrite(JoinPoint thisJoinPoint, Object newValue) {
System.out.println(thisJoinPoint + " -> " + newValue);
}
}
Konsolenprotokoll:
set(String de.scrum_master.app.Application.status) -> starting
get(String de.scrum_master.app.Application.status)
Application [id=11, name=AspectJ demo, status=starting]
set(String de.scrum_master.app.Application.status) -> running
get(String de.scrum_master.app.Application.status)
Application [id=22, name=AspectJ field access demo, status=running]
set(String de.scrum_master.app.Application.status) -> shutting down
get(String de.scrum_master.app.Application.status)
Application [id=22, name=AspectJ field access demo, status=shutting down]
set(String de.scrum_master.app.Application.status) -> stopped
get(String de.scrum_master.app.Application.status)
Application [id=22, name=AspectJ field access demo, status=stopped]
Was meinst du mit _capture jeder Feld_? Spring (Proxy-basiert) AOP funktioniert nur mit Methodenaufrufen. –
ausgezeichneter Punkt. Also, sollte meine Methode vielleicht die Pointcut auf der Setter-Methode dieses Feldes sein? – Mostfoolish
Sie haben _inject_ erwähnt. Warum verwenden Sie nicht die eingebauten Auto-Window-Mechanismen? –