先定义两个注解,Annotation1和Annotation2
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface Annotation1 { String name(); }
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface Annotation2 { String name(); }
定义接入点方法,joinPointTest
@Annotation1(name="annotation1") @Annotation2(name="annotation2") public void joinPointTest() throws Throwable { System.out.println("This is joinPointTest"); }
定义通知方法adviseTest(一个方法即可说明问题,故省略另一个通知方法),并设为在接入点方法执行正常结束后调用
@AfterReturning("execution(* com.aop.test..*.*(..)) && @annotation(anno1)") public void adviseTest(JoinPoint joinPoint, Annotation1 anno1) throws Throwable { System.out.println(anno1.name()); }
按照以上的配置,在触发通知方法时 可能出现传递给adviseTest方法的参数不匹配的错误,具体表现就是adviseTest需要Annotation1类型的参数,但实际上传递的是Annotation2。
网上找了一下,没找到类似的问题,但是有其他的解决方案,修改后的adviseTest
@AfterReturning("execution(* com.aop.test..*.*(..)) && @annotation(com.aop.test.Annotation1)") public void adviseTest(JoinPoint joinPoint) throws Throwable { Signature signature = joinPoint.getSignature(); if (!(signature instanceof MethodSignature)) throw new SignatureException("The Signature's real type is not MethodSignature but " + signature.getClass().getName()); MethodSignature methodSignature = (MethodSignature) signature; Annotation1 anno1 = methodSignature.getMethod().getAnnotation(Annotation1.class); System.out.println(anno1.name()); }
因为这里的接入点是方法,因此JoinPoint的getSignature方法返回的实际类型是MethodSignature,可以通过该类的getMethod获得实际的Method对象,进而获得指定的Annotation。