我认为你应该遵循Sotirios Delimanolis的建议,尽可能地使用Spring。如果你仍然认为它们不足够并且一定要使用aspect来实现你的想法,那么你可以使用
Spring中的AspectJ而不是Spring AOP,并利用切入点的全部功能,如
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 {}
驱动程序应用:
该应用程序读取(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]
BeanPostProcessor
替代。 - Sotirios Delimanolis