SpringBoot @Annotation

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

@Service
@Repository
@Component
@...

转载于:https://www.cnblogs.com/vincenshen/p/10427879.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值