springMVC的自定義annotation(@Retention@Target)詳解

自定義註解:

  使用@interface自定義註解時,自動繼承了java.lang.annotation.Annotation接口,由編譯程序自動完成其餘細節。在定義註解時,不能繼承其餘的註解或接口。@interface用來聲明一個註解,其中的每個方法其實是聲明瞭一個配置參數。方法的名稱就是參數的名稱,返回值類型就是參數的類型(返回值類型只能是基本類型、Class、String、enum)。能夠經過default來聲明參數的默認值。html

定義註解格式:
  public @interface 註解名 {定義體}java

  註解參數的可支持數據類型:git

    1.全部基本數據類型(int,float,boolean,byte,double,char,long,short)
    2.String類型
    3.Class類型
    4.enum類型
    5.Annotation類型
    6.以上全部類型的數組github

  Annotation類型裏面的參數該怎麼設定:
  第一,只能用public或默認(default)這兩個訪問權修飾.例如,String value();這裏把方法設爲defaul默認類型;   
  第二,參數成員只能用基本類型byte,short,char,int,long,float,double,boolean八種基本數據類型和 String,Enum,Class,annotations等數據類型,以及這一些類型的數組.例如,String value();這裏的參數成員就爲String;  
  第三,若是隻有一個參數成員,最好把參數名稱設爲"value",後加小括號.例:下面的例子FruitName註解就只有一個參數成員。數組

  簡單的自定義註解和使用註解實例:
  app

package annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 水果名稱註解
 * @author peida
 *
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitName {
    String value() default "";
}
package annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 水果顏色註解
 * @author peida
 *
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitColor {
    /**
     * 顏色枚舉
     * @author peida
     *
     */
    public enum Color{ BULE,RED,GREEN};
    
    /**
     * 顏色屬性
     * @return
     */
    Color fruitColor() default Color.GREEN;

}
package annotation;

import annotation.FruitColor.Color;

public class Apple {
    
    @FruitName("Apple")
    private String appleName;
    
    @FruitColor(fruitColor=Color.RED)
    private String appleColor;
    
    
    
    
    public void setAppleColor(String appleColor) {
        this.appleColor = appleColor;
    }
    public String getAppleColor() {
        return appleColor;
    }
    
    
    public void setAppleName(String appleName) {
        this.appleName = appleName;
    }
    public String getAppleName() {
        return appleName;
    }
    
    public void displayName(){
        System.out.println("水果的名字是:蘋果");
    }
}

元註解(meta-annotation):

元註解的做用就是負責註解其餘註解。Java5.0定義了4個標準的meta-annotation類型,它們被用來提供對其它 annotation類型做說明。Java5.0定義的元註解:
 1.@Target,用於描述註解的使用範圍(方法、構造方法、成員變量、枚舉值)
   ide

取值(ElementType)有:函數

1.CONSTRUCTOR:用於描述構造器
2.FIELD:用於描述域
3.LOCAL_VARIABLE:用於描述局部變量
4.METHOD:用於描述方法
5.PACKAGE:用於描述包
6.PARAMETER:用於描述參數
7.TYPE:用於描述類、接口(包括註解類型) 或enum聲明工具

 
 2.@Retention,表示須要在什麼級別保存該註釋信息,用於描述註解的生命週期源碼分析

取值(RetentionPoicy)有:

1.SOURCE:在源文件中有效(即源文件保留)
2.CLASS:在class文件中有效(即class保留)
3.RUNTIME:在運行時有效(即運行時保留)(屬性值是RUTIME,這樣註解處理器能夠經過反射,獲取到該註解的屬性值)

 3.@Documented 用於描述其它類型的annotation應該被做爲被標註的程序成員的公共API,所以能夠被例如javadoc此類的工具文檔化
 
4.@Inherited@Inherited 元註解是一個標記註解,@Inherited闡述了某個被標註的類型是被繼承的。若是一個使用了@Inherited修飾的annotation類型被用於一個class,則這個annotation將被用於該class的子類。

註解的使用:

第一步:新建一個annotation,名字爲:MyAnnotation.java。

package com.dragon.test.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Created by gmq on 2015/9/10.
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation
{

    String hello () default "hello";
    String world();
}

第二步:創建一個MyTest.java 來使用上面的annotation。

package com.dragon.test.annotation;

/**
 * Created by gmq on 2015/9/10.
 */
public class MyTest
{

    @MyAnnotation(hello = "Hello,Beijing",world = "Hello,world")
    public void output() {
        System.out.println("method output is running ");
    }
}

第三步:用反射機制來調用註解中的內容

package com.dragon.test.annotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
 * 用反射機制來調用註解中的內容
 * Created by gmq on 2015/9/10.
 */
public class MyReflection
{
    public static void main(String[] args) throws Exception
    {
        // 得到要調用的類
        Class<MyTest> myTestClass = MyTest.class;
        // 得到要調用的方法,output是要調用的方法名字,new Class[]{}爲所須要的參數。空則不是這種
        Method method = myTestClass.getMethod("output", new Class[]{});
        // 是否有類型爲MyAnnotation的註解
        if (method.isAnnotationPresent(MyAnnotation.class))
        {
            // 得到註解
            MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
            // 調用註解的內容
            System.out.println(annotation.hello());
            System.out.println(annotation.world());
        }
        System.out.println("----------------------------------");
        // 得到全部註解。必須是runtime類型的
        Annotation[] annotations = method.getAnnotations();
        for (Annotation annotation : annotations)
        {
            // 遍歷全部註解的名字
            System.out.println(annotation.annotationType().getName());
        }
    }
}

輸出:

Hello,Beijing
Hello,world

參考:https://www.cnblogs.com/gmq-sh/p/4798194.html


註解的概念

註解(Annotation),也叫元數據(Metadata),是Java5的新特性,JDK5引入了Metadata很容易的就可以調用Annotations。註解與類、接口、枚舉在同一個層次,並能夠應用於包、類型、構造方法、方法、成員變量、參數、本地變量的聲明中,用來對這些元素進行說明註釋。

註解的語法與定義形式

(1)以@interface關鍵字定義
(2)註解包含成員,成員以無參數的方法的形式被聲明。其方法名和返回值定義了該成員的名字和類型。
(3)成員賦值是經過@Annotation(name=value)的形式。
(4)註解須要標明註解的生命週期,註解的修飾目標等信息,這些信息是經過元註解實現。

以 java.lang.annotation 中定義的 Target 註解來講明:

@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = { ElementType.ANNOTATION_TYPE } )
public @interface Target {
    ElementType[] value();
}

源碼分析以下:
第一:元註解@Retention,成員value的值爲RetentionPolicy.RUNTIME。
第二:元註解@Target,成員value是個數組,用{}形式賦值,值爲ElementType.ANNOTATION_TYPE
第三:成員名稱爲value,類型爲ElementType[]
另外,須要注意一下,若是成員名稱是value,在賦值過程當中能夠簡寫。若是成員類型爲數組,可是隻賦值一個元素,則也能夠簡寫。如上面的簡寫形式爲:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    ElementType[] value();
}

註解的分類

註解的分類有兩種分法:

第一種分法

一、基本內置註解,是指Java自帶的幾個Annotation,如@Override、Deprecated、@SuppressWarnings等;

二、元註解(meta-annotation),是指負責註解其餘註解的註解,JDK 1.5及之後版本定義了4個標準的元註解類型,以下:

@Target
@Retention
@Documented
@Inherited
三、自定義註解,根據須要能夠自定義註解,自定義註解須要用到上面的meta-annotation

參考:https://blog.csdn.net/github_35180164/article/details/52107204


Java元註解@Retention規則

@Retention是java當中的一個元註解,該元註解一般都是用於對軟件的測試

一、適用方式:
@Retention(RetentionPolicy.RUNTIME)
    @interface Task{.......}

參數RetentionPolicy.RUNTIME就說明了,@Task註解在程序運行時是可見的
RetentionPolicy的枚舉類型還有SOURCE、CLASS分別指定註解對於那個級別是可見的,可是,咱們通常都是用RUNTIME,由於這是在程序運行時能夠對註解進行讀取,從而易於軟件的測試

二、接下來咱們要先介紹一下java程序的內省和反射機制,以後在討論@Retention的具體用法實例

在java虛擬機JVM在運行時,就會將類進行加載,這時,每一個類都會生成一個Class數據類型的對象(Class類在java.lang.Class中),這個對象就是對應類的「運行時對象」,經過這個運行時對象,就可以獲取對應類的許多信息,也就是說,運行時對象實際就是對應類的一個映射,這就java的內省反射機制

三、接下來咱們討論一下,這個Class運行時對象的使用

① 獲取對應類的Class數據類型的運行時對象的引用——getClass()

public class Point{.....} //聲明一個類
     Point pt = new Point(); //建立對應類的實例對象
     Class cls = pt.getClass() ;    //則cls 就指向了Point類的運行時對象

②運行時對象cls的成員函數

<1>public String  getName()
     返回對應類的類名
     
<2>public boolean isAnnotationPresent(註解名.class)
     斷定指定的"註解"是否在運行時註解了 cls 的對應類
     
     <3>public boolean isAnnotation();
     斷定cls 是否在運行時被任何註解 註解過
     
<4>public A getAnnotation(註解名.class)
     A 指的是一個註解的類型,具體用法以下:
     @Retention(RetentionPolicy.RUNTIME) //指定@Task運行時可見
     @interface Task{String descirption(); }
     
     @Task(descroption="NoFinished")   //爲computer做注
     class Computer{.....} 
     則  Computer my = new Computer() ;
         Class cls = my.getClass() ;
         Task tk = (Task) cls.getAnnotation(Task.class);
         //這時 tk 就指向了標註Computer的註解@Task
         tk.description(); //調用@Task中的description(),輸出"NoFinishing"
         
 <5> public Method[] getMethods()
        返回由對應類中的全部的方法造成的Method數組,每一個Method對象都惟一對應
        一個對應類中的方法,經過Method[i]就能夠得到對應方法的信息
        (Method類在java.lang.reflect.Method中)
       
        這個Method類也有不少成員方法,用來獲取對應的方法的信息

        如也有:
       public boolean isAnnotationPresent(註解名.class)
       斷定對應的方法是否被指定的注所註解
       public A getAnnotation(註解名.class)
       用法和上面的講述的同樣,之不過建立的註解型的引用變量指向的是 "標記對應方法的註解"

上面將全部的成員方法只有在註解運行時可見的狀況下才可以發揮做用,因此@Retention變得頗有用

參考:https://www.cnblogs.com/PengLee/p/3902836.html

相關文章
相關標籤/搜索