java - joinPoint 中的 getAnnotations 方法未列出该方法的注释之一

标签 java spring java-7 aop aspectj

我在 Spring 使用 AOP:

我写了一个注释

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

}

我在 Controller 方法上使用它:

@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。

知道为什么吗?

最佳答案

对我来说这有效,也许你做错了什么。可能您的示例代码并不能真正反射(reflect)您的情况。我在普通的 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=[])

关于java - joinPoint 中的 getAnnotations 方法未列出该方法的注释之一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28351440/

相关文章:

security - JRE 1.7 漏洞

java - Java 8 支持 TLS 1.2 但 Java 7 不支持

java - JPA将某列的值加一

java.io.FileNotFoundException :/storage/emulated/0/New file. txt:打开失败:EACCES(权限被拒绝)

java - @IfProfileValue 从环境变量导入集,测试未执行

java - 用于图像上传/显示的文件系统替代方案

Java 继承 : Calling a subclass method in a superclass

java - 如果在多个属性文件中定义了一个属性,Spring 如何选择要使用的属性值?

java - 对 getSingleResult 使用可选

java - JDK 7 中使用的 ZonedDateTime 和 ChronoUnit 的替代方案