美文网首页
SpringBoot 入门笔记(三)Annotation

SpringBoot 入门笔记(三)Annotation

作者: MonroeShen | 来源:发表于2019-01-16 23:33 被阅读0次

    Annotation简介

    Annotation是JDK1.5引入的特性,包含在java.lang.annotation包中。

    它是附加在代码中的一些元信息,将一个类的外部信息与内部成员联系起来,在 编译、运行时进行解析和使用(可以理解成Python的装饰器)。

    Java内置了一些Annotation(例如 @Override、@Deprecated等),也支持用户定义自己的Annotation,像Hibernate、Spring等框架都大量的自定义了Annotation。

    什么是Annotation?

    用一个词就可以描述Annotation —— "元数据",一种描述“数据”的“数据”;可以说Annotation就是源代码的“元数据”。

    @Override
    public String toString() {
      return "Annotation Demo";
    }
    

    上面的代码中重写了 toString()方法,并使用了@Override Annotation。该Annotation表示什么?有什么用处?实际上@Override会告诉编译器这个方法是一个重写方法,如果父类中不存在该方法,编译器就会报错。

    Annotation是一种应用与 类、接口、方法、参数、变量、构造器及包声明中的特殊修饰符,详细内容可以查看枚举ElementType。

    为什么要引入Annotation?

    在Annotation出现之前,XML被广泛应用关于描述元数据,但是程序员和架构师发现XML的维护越来越麻烦,他们希望使用一些和代码紧耦合的东西,而不是想XML那样和代码是松耦合的,最有趣的是XML配置实际上是为了分离代码和配置而引入的。

    假如你想为应用设置很多常量或参数,XML是一个很好的选择,因为它不会和特定的代码相连。如果你想把某个Method声明为服务,那么使用Annotation会更简单、方便一些,因为这种情况下需要Annotation和Method紧密耦合起来。

    目前需要框架将XML和Annotation两种方式都结合使用,平衡两者之间的利弊。

    Annotation是如何工作的?

    先来看看@Override的代码

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.SOURCE)
    public @interface Override {
    }
    

    对于@Override你肯定会有疑问,它的内部什么都没做,它是如何检查父类中有没有同名的方法呢?@Override的定义不仅仅只有这么一点代码(注意:Annotation仅仅是元数据,和业务逻辑无关),那@Override到底是如何实现的呢? 答:AnnotationProcessor

    Annotation示例代码:https://docs.google.com/file/d/0B1N2DVZFnNU0dVdFVjVFeTVtcXc/edit

    AnnotationProcessor

    是一个在javac中的,用来编译时扫描和处理的Annotation的工具。一个Annotation的AnnotationProcessor,以Java代码(或者编译过的字节码)作为输入,生成文件(通常是.java文件)作为输出。这具体的含义什么呢?你可以生成Java代码!

    生成的Java代码是在新的.java文件中,所以你并不能修改已存在的Java类,例如向已有的类中添加方法。并且这些生成的Java文件,会同其他普通的手动编写的Java源代码一样被javac编译。

    元注解

    用来标注其它注解而创建的新注解,元注解的类型有以下几种:
    @Target:注解所修饰的对象范围
    @Inherited:表示注解可以被继承
    @Documented:表示这个注解应该被JavaDoc工具记录
    @Rentation:用来声明注解的保留策略
    @Repeable:JDK8新增,允许一个注解在同一声明类型(类,属性或方法)上多次使用。

    自定义Annotation

    那么,注解的内部到底是如何定义的呢?Annotations只支持基本类型、String及枚举类型。注释中所有的属性被定义成方法,并允许提供默认值。

    示例代码:
    01、MyTag类

    import java.lang.annotation.*;
    
    @Target({ElementType.METHOD, ElementType.FIELD})
    @Inherited
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyTag {
        String name() default "Car";
        int size() default 10;
    }
    

    02、Car实体类

    public class Car {
    
        private String name;
        private int size;
    
        public Car(){
    
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getSize() {
            return size;
        }
    
        public void setSize(int size) {
            this.size = size;
        }
    
        public Car(String name, int size) {
            this.name = name;
            this.size = size;
        }
    
        @Override
        public String toString() {
            return "Car{" +
                    "name='" + name + '\'' +
                    ", size=" + size +
                    '}';
        }
    }
    

    03、AnnotationDemo

    public class AnnotationDemo {
    
        @MyTag(name = "Audi", size = 100)   // 装配Car这个类 
        private Car car;
    
        public Car getCar(){
            return car;
        }
    
        public void setCar(Car car){
            this.car = car;
        }
    
        @Override
        public String toString() {
            return "AnnotationDemo{" +
                    "car=" + car +
                    '}';
        }
    }
    

    04、AnnotationProcessor

    import java.lang.reflect.Field;
    
    public class AnnotationProcessor {
        public static void annotationProcess(AnnotationDemo annotationDemo){
            for(Field field: annotationDemo.getClass().getDeclaredFields()){
                if(field.isAnnotationPresent(MyTag.class)){     // 如果存在MyTag标签
                    MyTag myTag = field.getAnnotation(MyTag.class);
                    annotationDemo.setCar(new Car(myTag.name(), myTag.size()));
                }
            }
        }
    
        public static void main(String[] args){
            AnnotationDemo annotationDemo = new AnnotationDemo();
            annotationProcess(annotationDemo);
            System.out.println(annotationDemo.getCar());
    
        }
    }
    

    SpringBoot常用Annotation

    相关文章

      网友评论

          本文标题:SpringBoot 入门笔记(三)Annotation

          本文链接:https://www.haomeiwen.com/subject/dgtbdqtx.html