一. 理解Java註解
註解本質是一個繼承了Annotation的特殊接口,其具體實現類是Java運行時生成的動態代理類。而咱們經過反射獲取註解時,返回的是Java運行時生成的動態代理對象$Proxy1。經過代理對象調用自定義註解(接口)的方法,會最終調用AnnotationInvocationHandler的invoke方法。該方法會從memberValues這個Map中索引出對應的值。而memberValues的來源是Java常量池。
實際上Java註解與普通修飾符(public、static、void等)的使用方式並無多大區別,下面的例子是常見的註解java
public class AnnotationDemo { @Test public static void A(){ System.out.println("Test....."); } @Deprecated @SuppressWarnings("uncheck") public static void B(){ } }
經過在方法上使用@Test註解後,在運行該方法時,測試框架會自動識別該方法並單獨調用,@Test其實是一種標記註解,起標記做用,運行時告訴測試框架該方法爲測試方法。而對於@Deprecated和@SuppressWarnings(「uncheck」),則是Java自己內置的註解,在代碼中,能夠常常看見它們,但這並非一件好事,畢竟當方法或是類上面有@Deprecated註解時,說明該方法或是類都已通過期不建議再用,@SuppressWarnings 則表示忽略指定警告,好比@SuppressWarnings(「uncheck」),這就是註解的最簡單的使用方式,那麼下面咱們就來看看註解定義的基本語法json
二. 基本語法
聲明註解與元註解
咱們先來看看前面的Test註解是如何聲明的:api
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @Documented public @interface OpenAPIMeta { /** * 字符參數長度(僅須要對字符串類型進行設置)。 */ String limit(); /** * 參數示例值(很重要不要隨意賦值,用於生成示例json)。 */ String demo(); /** * 參數說明。 */ String remark(); /** * 參數是否必填項(0爲非必填 ;1爲必填 ) */ int isRequired() default 0; /** * 是否有擴展參數說明 */ boolean hasExtend() default false; /** * 枚舉對象完整類型限定名 */ String enumType() default ""; }
三. 註解支持的數據類型
全部基本類型(int,float,boolean,byte,double,char,long,short)
String
Class (如:Class<?> 或 Class<T>)
enum
Annotation
上述類型的數組數組
四. 獲取類級註解框架
DomainEventHandlerMessageQueue dehmqAnnotation = null; Annotation[] annotations = obj.getClass().getAnnotations(); for (Annotation x : annotations) { if (x.annotationType() == DomainEventHandlerMessageQueue.class) { dehmqAnnotation = x; break; }
五. 獲取方法註解
測試
Field[] fields = obj.getClass().getDeclaredFields(); for (Field field : fields) { OpenAPIMeta apiAnnotation = null; for (Annotation x : field.getDeclaredAnnotations()) { if (x.annotationType() == OpenAPIMeta.class) { apiAnnotation = (OpenAPIMeta) x; break; } } }