Spring利用注解进行多次拦截

        最近在用Spring AOP时遇到一个问题。一个切入点会触发两个通知,而切入点是通过注解进行标注的,而注解作为参数传递给通知方法。这样的情况下同时触发两个通知,Spring调用通知方法时传递的注解参数会出现类型错误的问题。

        先定义两个注解,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。

猜你喜欢

转载自paddy-w.iteye.com/blog/2237373