zoukankan      html  css  js  c++  java
  • java 注解

    1、什么是注解

    存放在java源码的类、方法、字段、参数的一种特殊注释。

    2、元注解

    @Target:定义该注解标注与java那个位置,参数为一个或多个

    • 类或接口:ElementType.TYPE;
    • 字段:ElementType.FIELD;
    • 方法:ElementType.METHOD;
    • 构造方法:ElementType.CONSTRUCTOR;
    • 方法参数:ElementType.PARAMETER。

    当定义字段注解标注在方法上会发生什么:编译报错

    @Retention
    另一个重要的元注解@Retention定义了Annotation的生命周期:默认为CLASS

    • 仅编译期:RetentionPolicy.SOURCE;
    • 仅class文件:RetentionPolicy.CLASS;
    • 运行期:RetentionPolicy.RUNTIME。

    @Documented:文档扫描
    @Repeatable:该注解可重复标注
    @Inherited:定义子类是否可以继承父类标注的注解,仅ElementTypp.TYPE有效

    3、自定义注解

    @interface : 为定义注解关键字

    @Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface SourceTarget {
    
        /**
         * 数据源type、field、method
         * @return
         */
        String source() default "type";
    
    }
    
    

    4、怎么使用注解

    一般通过反射获取到注解携带的信息

    在使用反射提供的api时注意注解标记地方的修饰符,private标记的字段用getDeclaredFields()来获取之类的。

    根据注解的生命周期进行处理,分别:

    • SOURCE类型的注解在编译期就被丢掉了;
    • CLASS类型的注解仅保存在class文件中,它们不会被加载进JVM;
    • RUNTIME类型的注解会被加载进JVM,并且在运行期可以被程序读取。

    获取ElementType.TYPE的注解:

    Class cla = userDTO.getClass();
    //验证是否带有SourceTarget注解,ElementTpe.TYPE
    if(cla.isAnnotationPresent(SourceTarget.class)){
        SourceTarget target = (SourceTarget) cla.getAnnotation(SourceTarget.class);
        log.info("target:{}",target);
    }
    

    获取ElementType.FIELD的注解:

    Field[] fields = cla.getDeclaredFields();//注意该方法获取到该字段的访问权限
    for(Field field : fields){
        if(field.isAnnotationPresent(SourceTarget.class)){
            SourceTarget target = field.getAnnotation(SourceTarget.class);
            log.info("Field target:{}",target.source());
        }
    }
    

    获取ElementType.METHOD的注解:

    Method[] methods = cla.getMethods();
    //Method method1 = cla.getMethod("getKey");
    for(Method method : methods){
        if(method.getName().equals("getKey")){
            //再一步验证
            SourceTarget target = method.getAnnotation(SourceTarget.class);
            log.info("Method target:{}",target.source());
        }
    }
    

    java 反射还提供了多种获取字段、注解、方法的api。

    5、注解与AOP配合实现

    例子:主要是利用aop拦截带有@SourceTarget注解的方法,对该方法返回值中的@DataTarget标注的字段进行一些相应操作。

    DataTarget:

    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    public @interface DataTarget {
        /**
         * 键
         * @return
         */
        String key() default "";
    
        /**
         * 值
         * @return
         */
        String value() default "";
    }
    
    

    SourceTargetAspect:

    @Slf4j
    @Aspect
    @Component
    public class SourceTargetAspect {
    
        @Around("@annotation(com.example.springboot.annotation.SourceTarget)")
        public Object around(ProceedingJoinPoint point) {
            log.info("进入around方法");
            Object result = null;
            try {
                //执行方法
                UserDTO userDTO = (UserDTO) point.proceed();
    
                Field[] fields = userDTO.getClass().getDeclaredFields();
    
                for (Field field : fields) {
                    if (field.isAnnotationPresent(DataTarget.class)) {
                        DataTarget dataTarget = (DataTarget) field.getAnnotation(DataTarget.class);
    
                        String key = dataTarget.key();
    
                        Field field1 = userDTO.getClass().getDeclaredField(key);
                        //权限
                        field1.setAccessible(true);
    
                        field.setAccessible(true);
                        field.set(userDTO, field1.get(userDTO).toString());
    
                    }
                }
                result = userDTO;
            } catch (Throwable throwable) {
                log.error("SourceTargetAspect is error,message:{}",throwable.getMessage());
                throwable.printStackTrace();
            }
            return result;
        }
    }
    

    注解与切面配合,注解起到标注和携带相应信息的作用,通过两者结合可以对方法拦截做各种的处理,不过要注意反射的使用。

    6、关于注解的思考

    注解起一个标记的作用,配合反射来获取注解的标记信息,我们根据该标记的信息执行不同的操作,可能是一些数据的处理、事件的监听等,使用注解时要注意注解标注的访问权限。

    关于学习到的一些记录与知识总结
  • 相关阅读:
    洛谷 P1653 猴子 解题报告
    洛谷 P2024 [NOI2001]食物链 解题报告
    洛谷 P1966 火柴排队 解题报告
    洛谷 P1311 选择客栈 解题报告
    洛谷 P3959 宝藏 解题报告
    二进制枚举子集技巧
    洛谷 P1841 [JSOI2007]重要的城市 解题报告
    洛谷 P2324 [SCOI2005]骑士精神 解题报告
    vector-size
    ubuntu 更换软件源
  • 原文地址:https://www.cnblogs.com/Zxq-zn/p/14287065.html
Copyright © 2011-2022 走看看