SpringBoot 入門筆記(三)Annotation

Annotation簡介

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

它是附加在代碼中的一些元信息,將一個類的外部信息與內(nèi)部成員聯(lián)系起來,在 編譯、運行時進行解析和使用(可以理解成Python的裝飾器)。

Java內(nèi)置了一些Annotation(例如 @Override、@Deprecated等),也支持用戶定義自己的Annotation,像Hibernate、Spring等框架都大量的自定義了Annotation。

什么是Annotation?

用一個詞就可以描述Annotation —— "元數(shù)據(jù)",一種描述“數(shù)據(jù)”的“數(shù)據(jù)”;可以說Annotation就是源代碼的“元數(shù)據(jù)”。

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

上面的代碼中重寫了 toString()方法,并使用了@Override Annotation。該Annotation表示什么?有什么用處?實際上@Override會告訴編譯器這個方法是一個重寫方法,如果父類中不存在該方法,編譯器就會報錯。

Annotation是一種應用與 類、接口、方法、參數(shù)、變量、構(gòu)造器及包聲明中的特殊修飾符,詳細內(nèi)容可以查看枚舉ElementType。

為什么要引入Annotation?

在Annotation出現(xiàn)之前,XML被廣泛應用關(guān)于描述元數(shù)據(jù),但是程序員和架構(gòu)師發(fā)現(xiàn)XML的維護越來越麻煩,他們希望使用一些和代碼緊耦合的東西,而不是想XML那樣和代碼是松耦合的,最有趣的是XML配置實際上是為了分離代碼和配置而引入的。

假如你想為應用設(shè)置很多常量或參數(shù),XML是一個很好的選擇,因為它不會和特定的代碼相連。如果你想把某個Method聲明為服務(wù),那么使用Annotation會更簡單、方便一些,因為這種情況下需要Annotation和Method緊密耦合起來。

目前需要框架將XML和Annotation兩種方式都結(jié)合使用,平衡兩者之間的利弊。

Annotation是如何工作的?

先來看看@Override的代碼

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

對于@Override你肯定會有疑問,它的內(nèi)部什么都沒做,它是如何檢查父類中有沒有同名的方法呢?@Override的定義不僅僅只有這么一點代碼(注意:Annotation僅僅是元數(shù)據(jù),和業(yè)務(wù)邏輯無關(guān)),那@Override到底是如何實現(xiàn)的呢? 答:AnnotationProcessor

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

AnnotationProcessor

是一個在javac中的,用來編譯時掃描和處理的Annotation的工具。一個Annotation的AnnotationProcessor,以Java代碼(或者編譯過的字節(jié)碼)作為輸入,生成文件(通常是.java文件)作為輸出。這具體的含義什么呢?你可以生成Java代碼!

生成的Java代碼是在新的.java文件中,所以你并不能修改已存在的Java類,例如向已有的類中添加方法。并且這些生成的Java文件,會同其他普通的手動編寫的Java源代碼一樣被javac編譯。

元注解

用來標注其它注解而創(chuàng)建的新注解,元注解的類型有以下幾種:
@Target:注解所修飾的對象范圍
@Inherited:表示注解可以被繼承
@Documented:表示這個注解應該被JavaDoc工具記錄
@Rentation:用來聲明注解的保留策略
@Repeable:JDK8新增,允許一個注解在同一聲明類型(類,屬性或方法)上多次使用。

自定義Annotation

那么,注解的內(nèi)部到底是如何定義的呢?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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容