如何通过AspectJ为带@Monitor注解的成员配置get/set方法的Around切点?
问题描述
希望为类中的成员添加@Monitor注解,并通过AspectJ配置Around切点,使其在该成员的get和set方法被调用时触发。示例代码如下:
public class Point { @Monitor private int x; public int getX() { return x;} public void setX(int v) {x = v; } }
@Aspect public class MonitorAspect { @Around("annotation(Monitor) && ???) public void actionOnGet(ProceedingJoinPoint jp) { // do stuff related to get } @Around("annotation(Monitor) && ???) public void actionOnSet(ProceedingJoinPoint jp) { // do stuff related to set } }
请问这种实现方式是否可行?
解答
这种实现方式是可行的,但需要调整切点表达式——因为你把@Monitor标注在字段上,默认的annotation(Monitor)切点只会匹配直接标注了该注解的方法,无法关联到字段对应的get/set方法。需要通过AspectJ的字段切点来关联对应的访问/修改方法,具体实现如下:
1. 定义@Monitor注解
首先确保注解的保留策略足够让AspectJ识别,比如设置为RUNTIME或CLASS:
import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) public @interface Monitor { }
2. 修正AspectJ切点与逻辑
通过get(@Monitor *)匹配所有访问带@Monitor注解字段的get方法,set(@Monitor *)匹配所有修改带@Monitor注解字段的set方法:
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; @Aspect public class MonitorAspect { // 匹配get方法:访问带@Monitor注解的字段 @Around("get(@Monitor *)") public Object actionOnGet(ProceedingJoinPoint jp) throws Throwable { // 处理get方法调用前/后的逻辑 System.out.println("触发get方法监控:" + jp.getSignature().getName()); return jp.proceed(); // 执行原get方法 } // 匹配set方法:修改带@Monitor注解的字段 @Around("set(@Monitor *)") public Object actionOnSet(ProceedingJoinPoint jp) throws Throwable { // 处理set方法调用前/后的逻辑 System.out.println("触发set方法监控:" + jp.getSignature().getName() + ",参数:" + jp.getArgs()[0]); return jp.proceed(); // 执行原set方法 } }
3. 关键注意事项
- 织入方式:需要确保AspectJ的织入生效,可选择编译时织入(通过ajc编译器)或加载时织入(LTW),具体根据项目构建方式配置(比如Maven的
aspectj-maven-plugin)。 - 方法命名规范:AspectJ的
get()/set()切点默认遵循JavaBean命名规范(getX对应字段x,setX对应字段x),如果你的get/set方法命名不符合该规范,需要自定义切点逻辑来匹配。 - 返回值处理:Around切点方法的返回值要和原方法匹配,get方法需要返回原方法的结果,set方法通常返回void,所以可以调整返回值类型为
Object并正确返回jp.proceed()的结果。
内容的提问来源于stack exchange,提问作者bkqdad
相关产品推荐
相关产品推荐

