Я думаю, вы должны следовать совету Sotirios Delimanolis и получить как можно больше с помощью весны на борту. Если вы все еще думаете, что они неадекватны и абсолютно хотят использовать аспекты для реализации своей идеи, вы можете использовать AspectJ within Spring вместо Spring AOP и использовать полную мощность pointcuts, например get()
и set()
, чтобы перехватывать операции чтения/записи на членах класса (как статические, так и нестатические). Например:
Маркер аннотаций: применение
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 {}
Driver:
Приложение читает (toString()
) и пишет (конструктор, главный метод) во всех областях, среди них аннотированный status
поле.
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);
}
}
Формат:
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);
}
}
консоли журнала:
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]
Что вы имеете в виду _capture любой field_? Spring (на основе прокси) AOP работает только с вызовами метода перехвата. –
отличная точка. Итак, возможно, моя методология должна состоять в том, чтобы иметь pointcut в методе setter этого поля? – Mostfoolish
Вы упомянули _inject_. Почему бы вам не использовать встроенные механизмы автонастройки? –