(排坑)自定义注解通过Method类‘getAnnotation()’取值为‘NULL’

‘aspectj’版本:1.8.9 (绝大部分版本针对此问题不会有影响)

依赖如下:

<dependency>
  	<groupId>org.aspectj</groupId>
   	<artifactId>aspectjweaver</artifactId>
   	<version>1.8.9</version>
</dependency>

先从注解类开始检查

注解类

import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
@Order(Ordered.HIGHEST_PRECEDENCE)
public @interface Test {

    int value() default 9;
    
}
  • @Retention: 定义被它所注解的注解保留多久

source注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;被编译器忽略
class注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期
runtime注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在

  • @Target: 注解的作用目标
  • @Documented: 标记注解,表明这个注解应该被 javadoc工具记录
  • @Order: 定义Spring IOC容器中Bean的执行顺序的优先级

Aspect类

import cn.annotation.APILimit;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;


@Aspect
@Component
public class TestAspect {

    private Logger logger = LoggerFactory.getLogger(TestAspect.class);


    @Pointcut("execution(* cn.controller..*.*(..))")
    public void before(){
    }

    @Before("before()")
    public Void handle(ProceedingJoinPoint joinPoint) throws Exception {

        // 获取HttpRequest
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        // 判断request不能为空
        if (request == null) {
            throw new Exception("HttpServletRequest获取有误...");
        }

        Test test = this.getAnnotation(joinPoint);
        logger.info(test.toString());
        
    }

    // 获取注解
    private Test getAnnotation(JoinPoint joinPoint) throws Exception {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();

        if (method != null) {
            return method.getAnnotation(Test.class);
        }
        return null;
    }


}

  • 入参类: ‘ProceedingJoinPoint ’与‘JoinPoint’都能获取到接口信息,对于获取注解类无影响

重点是‘getAnnotation()’函数获取值为NULL

网上大部分博客说明此处是‘目标对象’和‘代理对象’的问题
比起这个,先检查拦截的方法是否有声明指定类型的注解(绝大部分都是因为这个原因导致)

Method.getAnnotation(Class< T > annotationClass)

  • 如果该方法对象存在指定类型的注解,则返回该注解,否则返回 null
  • 只有类级别的注解会被继承得到,对于其他对象而言,getAnnotation() 方法与 getDeclaredAnnotation() 方法作用相同
	例如一个方法:
	    @Override
	    @SneakyThrows
	    public void method1(){}

	method.getAnnotation(Test.class) == NULL
	method.getAnnotation(Override.class) != NULL 
要实现字段英文转换为中文描述,您可以自定义一个注解,然后在实体的字段上使用该注解。以下是一个示例: 首先,创建一个自定义注解 `@FieldDescription`: ```java import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface FieldDescription { String value() default ""; } ``` 然后,在您的实体中使用该注解,并将字段的英文描述作为注解的值: ```java public class MyClass { @FieldDescription("姓名") private String name; @FieldDescription("年龄") private int age; // 省略其他字段和方法 } ``` 接下来,您可以编写一个工具,使用反射来获取字段的中文描述: ```java import java.lang.reflect.Field; public class FieldTranslator { public static String translateField(Class<?> clazz, String fieldName) { try { Field field = clazz.getDeclaredField(fieldName); FieldDescription annotation = field.getAnnotation(FieldDescription.class); if (annotation != null) { return annotation.value(); } } catch (NoSuchFieldException e) { e.printStackTrace(); } return fieldName; // 如果找不到注解,则返回字段名 } } ``` 使用该工具,您可以将实体的字段名称转换为中文描述: ```java public class Main { public static void main(String[] args) { MyClass obj = new MyClass(); System.out.println(FieldTranslator.translateField(MyClass.class, "name")); // 输出:姓名 System.out.println(FieldTranslator.translateField(MyClass.class, "age")); // 输出:年龄 } } ``` 这样,您就可以通过自定义注解和工具来实现实体字段的英文转换为中文描述了。希望对您有所帮助!如有其他问题,请随时提问。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值