注解介紹
Java 注解(Annotation)又稱 Java 標(biāo)注玩焰,是 JDK5.0 引入的一種注釋機(jī)制。
Java 語(yǔ)言中的類裤唠、方法砂客、變量泥张、參數(shù)和包等都可以被注解。
在編譯器生成類文件時(shí)鞠值,注解可以被嵌入到字節(jié)碼中媚创。Java 虛擬機(jī)可以保留注解內(nèi)容,在運(yùn)行時(shí)可以獲取到注解內(nèi)容 彤恶。
Java 注解支持自定義 Java 注解钞钙。
注解(Annotation)與注釋(Comments)是有區(qū)別的鳄橘。注解(Annotation)與注釋(Comments)不同在于Java注解可以通過(guò)反射獲取注解內(nèi)容。
注解語(yǔ)法
注解通過(guò) @interface 關(guān)鍵字進(jìn)行定義:
public @interface MyAnnotation {
}
注解分類
注解可以分為內(nèi)置注解芒炼、元注解瘫怜、自定義注解
內(nèi)置注解
- @Override - 檢查該方法是否是重寫方法。如果發(fā)現(xiàn)其父類本刽,或者是引用的接口中并沒(méi)有該方法時(shí)鲸湃,會(huì)報(bào)編譯錯(cuò)誤。
- @Deprecated - 標(biāo)記過(guò)時(shí)方法子寓。如果使用該方法唤锉,會(huì)報(bào)編譯警告。不推薦使用别瞭,可以使用或者有更好的方式窿祥。
- @SuppressWarnings - 指示編譯器去忽略注解中聲明的警告。
- @SafeVarargs - Java 7 開(kāi)始支持蝙寨,忽略任何使用參數(shù)為泛型變量的方法或構(gòu)造函數(shù)調(diào)用產(chǎn)生的警告晒衩。
- @FunctionalInterface - Java 8 開(kāi)始支持,標(biāo)識(shí)一個(gè)匿名函數(shù)或函數(shù)式接口墙歪。
- @Repeatable - Java 8 開(kāi)始支持听系,標(biāo)識(shí)某注解可以在同一個(gè)聲明上使用多次。
元注解
- @Retention - 標(biāo)識(shí)這個(gè)注解怎么保存虹菲,是只在代碼中靠胜,還是編入class文件中,或者是在運(yùn)行時(shí)可以通過(guò)反射訪問(wèn)毕源±四控制注解的作用時(shí)間范圍。
- @Documented - 標(biāo)記這些注解是否包含在用戶文檔中霎褐。
- @Target - 標(biāo)記這個(gè)注解應(yīng)該是哪種 Java 成員址愿。控制注解的作用區(qū)域范圍冻璃。
- @Inherited - 標(biāo)記這個(gè)注解是繼承于哪個(gè)注解類(默認(rèn) 注解并沒(méi)有繼承于任何子類)
@Retention屬性介紹
@Retention(RetentionPolicy.SOURCE) 只在編譯時(shí)有效
@Retention(RetentionPolicy.CLASS) 會(huì)寫到class字節(jié)碼文件里响谓,不可以通過(guò)反射讀取
@Retention(RetentionPolicy.RUNTIME), 注解會(huì)在class字節(jié)碼文件中存在省艳,在運(yùn)行時(shí)可以通過(guò)反射獲取到娘纷。一般自定義注解都是使用該元注解
@Target屬性介紹
@Target(ElementType.TYPE) 作用接口、類跋炕、枚舉赖晶、注解
@Target(ElementType.FIELD) 作用屬性字段、枚舉的常量
@Target(ElementType.METHOD) 作用方法
@Target(ElementType.PARAMETER) 作用方法參數(shù)
@Target(ElementType.CONSTRUCTOR) 作用構(gòu)造函數(shù)
@Target(ElementType.LOCAL_VARIABLE)作用局部變量
@Target(ElementType.ANNOTATION_TYPE)作用于注解
@Target(ElementType.PACKAGE) 作用于包
@Target(ElementType.TYPE_PARAMETER) 作用于類型泛型枣购,即泛型方法嬉探、泛型類、泛型接口 (jdk1.8加入)
@Target(ElementType.TYPE_USE) 類型使用.可以用于標(biāo)注任意類型除了 class (jdk1.8加入)
自定義注解
使用@interface
自定義注解時(shí)棉圈,自動(dòng)繼承了java.lang.annotation.Annotation
接口涩堤。
-
@interface
用來(lái)聲明一個(gè)注解,格式:public @interface 注解名稱{定義注解屬性}分瘾。
- 注解的默認(rèn)屬性為
String value()胎围;
只有一個(gè)value()屬性時(shí),可以忽略德召。 - 注解內(nèi)的每個(gè)方法實(shí)際上都聲明了一個(gè)配置參數(shù)白魂,方法名稱為參數(shù)名稱,方法返回值為參數(shù)類型(返回值類型可以是1.基本數(shù)據(jù)類型;2.String;3.枚舉類型4.注解類型;5.Class類型;6.以上類型的一維數(shù)組類型)
eg:
- 可以使用default來(lái)聲明參數(shù)的默認(rèn)值上岗。有默認(rèn)值的屬性福荸,使用注解時(shí)可以不將該屬性指定值。屬性沒(méi)有默認(rèn)值時(shí)肴掷,使用注解時(shí)必須賦值敬锐。
使用自定義注解實(shí)現(xiàn)記錄操作日志
基于注解的Aop日志記錄的實(shí)現(xiàn)方案:
- 自定義日志注解。
- 定義切面呆瞻。
- 切面方法中通過(guò)Java反射機(jī)制獲取注解內(nèi)的屬性值台夺。
- 在操作方法(增刪改重要表)時(shí),添加注解痴脾,eg:
@OperationLog(operationType = "1", operationDesc = "后臺(tái)管理系統(tǒng)添加用戶", operator = "admin", moduleId = "User")
自定義日志注解類
package com.hmio.study.annotion;
import java.lang.annotation.*;
@Target({ ElementType.PARAMETER, ElementType.METHOD })//作用方法颤介、作用方法參數(shù)
@Retention(RetentionPolicy.RUNTIME)//運(yùn)行時(shí)有效
@Documented//標(biāo)注注解在生成javadoc時(shí)是否顯示
public @interface OperationLog {
/** 要執(zhí)行的操作類型比如:增刪改導(dǎo)入導(dǎo)出等操作 可以使用枚舉類型**/
public String operationType();// 沒(méi)有默認(rèn)值,在使用時(shí)必須賦值
/** 要執(zhí)行的具體操作比如:操作具體描述 **/
public String operationDesc();// 沒(méi)有默認(rèn)值赞赖,在使用時(shí)必須賦值
/** 操作人:操作的操作人 任務(wù)操作可能沒(méi)有操作人**/
public String operator() default "";// 有默認(rèn)值滚朵,在使用時(shí)可以不賦值
/** 操作類型所屬模塊 僅用于特定場(chǎng)景日志采集使用,非要求請(qǐng)使用默認(rèn)值 可以使用枚舉類型 */
public String moduleId() default "";// 有默認(rèn)值,在使用時(shí)可以不賦值
}
使用示例:
@OperationLog (operationType = "IMPORT",
operationDesc = "用戶信息導(dǎo)入" ,
moduleId = "1")