什麼是註解?html
#======================================================================================================================
Annotation(註解)是一個接口,程序能夠經過反射來獲取指定程序元素的Annotation對象,而後經過Annotation對象來獲取註解裏面的元數據。
Annotation能夠用於建立文檔,跟蹤代碼中的依賴性,執行編譯時的檢查。Annotation就像修飾符同樣被使用,可用於包,類型,構造方法,方法,成員變量,
參數,本地變量的申明中。這些信息會被存儲在Annotation的「name=value」結構對中。
#======================================================================================================================
什麼是metadata元數據?java
#==========================================================================================================================
元數據,即「描述數據的數據」的意思,元數據一詞從「metadata」翻譯過來。
Annotation的行爲很是相似於public,final這樣的修飾符。
Annotation類型定義了Annotation的名字,類型,成員默認值,一個Annotation能夠說是一個特殊的Java接口,它的成員變量是受限制的,當咱們經過Java反射
API訪問註解的時候,返回值將是一個實現了該Annotation類型接口的對象,經過這個對象咱們能方便的訪問到其餘的Annotation成員。
#============================================================================================================================
註解的分類?ide
#==========================================================================================================================
JDK內置系統的註解:@Override,@Deprecated
元註解:@Target,@Retention,@Document,@Inhrited,
自定義註解:(元註解的做用就是負責註解其餘註解)
#==========================================================================================================================
註解是如何使用? spa
#==========================================================================================================================
// 用於描述註解的使用範圍 @Target(ElementType.Constructor)
@Target(ElementType.Field)
@Target(ElementType.Local_Variable)
@Target(ElementType.Method)
@Target(ElementType.Package)
@Target(ElementType.Paramater)
@Target(ElementType.Type)
// 用於描述註解的生命週期
@Rentention(RetentionPolicy.source)
@Rentention(RetentionPolicy.class)
@Rentention(RetentionPolicy.runtime)
@Document 和 @Inhrited 不經常使用,暫時不作介紹;
#==========================================================================================================================
自定義註解(註解與反射機制).net
#==========================================================================================================================
@Target(ElementType.Parameter)
@Retention(RetentionPolicy.Runtime)
public @interface CacheKey{
String value();
}
好比咱們在代碼中定義上述註解,直觀的咱們能看到註解使用在參數上,使用週期是運用在運行時使用,註解的參數名是value。闡述自定義註解:
1. 使用@interface自定義註解的時候,自動繼承了java.lang.annotation.Annotation接口,由編譯程序自動完成其餘細節。
2. 自定義註解,不能繼承其餘的註解或者接口。
3. @interface用來申明一個註解,其中的每個方法其實是申明瞭一個配置參數,方法的名稱就是參數的名稱。
4. 返回值類型僅僅包括:基本數據類型 + class + Enum + String
5. 參數只能用public或default修飾,若是隻有一個參數,最好把參數名稱設置爲value()。
註解元素的默認值:註解元素必須有肯定的值,要麼在定義註解的默認值中指定,要麼在使用註解時指定,非基本類型的註解元素的值不可爲null。所以,
使用空字符串或0做爲默認值是一種經常使用的作法。這個約束使得處理器很難表現一個元素的存在或缺失的狀態,由於每一個註解的聲明中,全部元素都存在,
而且都具備相應的值,爲了繞開這個約束,咱們只能定義一些特殊的值,例如空字符串或者負數,一次表示某個元素不存在,在定義註解時,這已經成爲一個習慣用法。
#==========================================================================================================================
關於註解的一些其餘說明翻譯
#==========================================================================================================================
public interface Annotation{
boolean equals(Object obj);
int hasCode();
String toString();
Class<? extends Annotation> annotationType();
}
Java中的註解是一種繼承自接口的java.lang.annotation.Annotation的接口。
#==========================================================================================================================
註解在程序運行時是如何做處理的code
java在java.lang.reflect下新增了AnnotatedElement接口,java處理註解的原理以下:htm
@Getter @Setter public class Person{ @Name("狂刀") private String name; @Gender(gender=Gender.GenderType) private String gender; @Profile(id=1001, height=180, nativePlace="CN") private String profile; } public class CustomUtils{ public static void getInfo(Class<?> clazz){ Sring name; String gender; String profile; Field[] fields = clazz.getDeclaredFields(); for(Field field : fields){ if(field.isAnnotationPresent(Name.class)){
Name arg0 = field.getAnnotation(Name.class);
name = name + arg0.value();
} if(field.isAnnotationPresent(Gender.class)){
Gender arg0 = field.getAnnotation(Gender.class);
gender = gender + arg0.gender().toString();
}
if(field.isAnnotationPresent(Profile.class)){
Profile arg0 = field.getAnnotation(Profile.class);
profile = profile + "id = " + arg0.id + ", height = " + arg0.height + ",nativePlace = " + arg0.nativePlace;
} } } }
自定義註解 && Spring AOP的使用對象
#========================================================================================================================== 一般使用場景:自定義註解 ==》Spring AOP中獲取註解,並處理
@Around("publicMethods() && @annotation(timedAnnotation)")
public Object instrumentTimed(ProceedingJoinPoint pjp, TimingTimed timedAnnotation) throws Throwable {
String name = name(pjp.getTarget().getClass(), StringUtils.hasLength(timedAnnotation.name()) blog
? timedAnnotation.name() : pjp.getSignature().getName(), "timingTimer");
Metric metric = registry.getMetric(name);
if (metric == null) {
RedAlertMetric redAlertMetric = new RedAlertMetric(new TimingTimer(), name,
timedAnnotation.measurement(), timedAnnotation.interval());
metric = registry.register(name, redAlertMetric);
}
if (metric != null && metric instanceof RedAlertMetric) {
Metric timer = ((RedAlertMetric) metric).getMetric();
if (timer != null && timer instanceof TimingTimer) {
TimingTimer.Context tc = ((TimingTimer) timer).time();
try {
return pjp.proceed();
} finally {
tc.stop();
}
} else {
return pjp.proceed();
}
} else {
return pjp.proceed();
}
}
#==========================================================================================================================
附,參考文章:
[1] http://blog.csdn.net/u013045971/article/details/53433874
[2] 自定義註解的使用Demo