joinPoint中的getAnnotations方法未列出该方法的其中一个注释

时间:2015-02-05 18:31:41

标签: java spring java-7 aop aspectj

我在春天与AOP合作:

我写了一个注释

@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {

}

我在控制器方法上使用它:

@ResponseBody
@TestAnnotation
@RequestMapping(method = RequestMethod.PUT, value = "/path/{variable}")
public return_type controller_call(@PathVariable String variable) {
    return service.methodName(variable);
}

在我写的建议中,我写了以下代码:

 MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    String methodName = signature.getMethod().getName();
    Class<?>[] parameterTypes = signature.getMethod().getParameterTypes();
    Annotation[] annotations = joinPoint.getTarget().getClass().getMethod(methodName, parameterTypes).getAnnotations();

这列出了RequestMapping和ResponseBody注释,但它没有列出我的TestAnnotation。

知道为什么吗?

2 个答案:

答案 0 :(得分:1)

对我而言,这可行,也许你做错了什么。可能您的示例代码并不能真正反映您的情况。我已经在普通的Java + AspectJ设置中复制了这种情况,只是将Spring库放在类路径上,而不是使用Spring AOP运行。但是,它与Spring AOP应该是相同的结果,因为切入点匹配就像在原生AspectJ中一样。

示例注释:

package de.scrum_master.app;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {}

带入口点的示例类:

package de.scrum_master.app;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

public class Application {
    @ResponseBody
    @TestAnnotation
    @RequestMapping(method = RequestMethod.PUT, value = "/path/{variable}")
    public String controller_call(@PathVariable String variable) {
        return "dummy value";
    }

    public static void main(String[] args) {
        new Application().controller_call("my/path");
    }
}

带有示例切入点/建议的方面:

package de.scrum_master.aspect;

import java.lang.annotation.Annotation;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;

@Aspect
public class MyAspect {
    @Before("execution(!static * *..Application.*(..))")
    public void myAdvice(JoinPoint joinPoint) throws Throwable {
        System.out.println(joinPoint);
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String methodName = signature.getMethod().getName();
        Class<?>[] parameterTypes = signature.getMethod().getParameterTypes();
        Annotation[] annotations = joinPoint.getTarget().getClass().getMethod(methodName, parameterTypes).getAnnotations();
        for (Annotation annotation : annotations)
            System.out.println(annotation);
    }
}

控制台输出:

execution(String de.scrum_master.app.Application.controller_call(String))
@org.springframework.web.bind.annotation.ResponseBody()
@de.scrum_master.app.TestAnnotation()
@org.springframework.web.bind.annotation.RequestMapping(headers=[], name=, value=[/path/{variable}], produces=[], method=[PUT], params=[], consumes=[])

答案 1 :(得分:0)

我遇到了同样的问题,解决方案是设置确保设置了运行时保留策略,并且目标类型是方法。

@Target(ElementType.METHOD)    
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation { }