摘要:另一個很重要的因素是定義了一種標準的描述元數(shù)據(jù)的方式。對于注解,它的用戶就是虛擬機,工作在字節(jié)碼層面,在編譯階段進行檢查,其處理機制主要是內(nèi)部處理。
什么是注解
用一個詞就可以描述注解,那就是元數(shù)據(jù),即一種描述數(shù)據(jù)的數(shù)據(jù)。所以,可以說注解就是源代碼的元數(shù)據(jù)。比如,下面這段代碼:
@Override public String toString() { return "This is String Representation of current object."; }
上面的代碼中,重寫了toString()方法并使用了@Override注解。
事實上,@Override告訴編譯器這個方法是一個重寫方法(描述方法的元數(shù)據(jù)),如果父類中不存在該方法,編譯器便會報錯,提示該方法沒有重寫父類中的方法。如果不小心拼寫錯誤,例如將toString()寫成了toStrring(){double r},而且也沒有使用@Override注解,那程序依然能編譯運行,但運行結(jié)果會和期望的大不相同。
Annotation是一種應(yīng)用于類、方法、參數(shù)、變量、構(gòu)造器及包聲明中的特殊修飾符。它是一種由JSR-175標準選擇用來描述元數(shù)據(jù)的一種工具。使用注解有助于閱讀程序。
為什么要引入注解使用Annotation之前(甚至在使用之后),XML被廣泛的應(yīng)用于描述元數(shù)據(jù)。不知何時開始一些應(yīng)用開發(fā)人員和架構(gòu)師發(fā)現(xiàn)XML的維護越來越糟糕了。他們希望使用一些和代碼緊耦合的東西,而不是像XML那樣和代碼是松耦合的(在某些情況下甚至是完全分離的)代碼描述。如果你在Google中搜索“XML vs. annotations”,會看到許多關(guān)于這個問題的辯論。最有趣的是XML配置其實就是為了分離代碼和配置而引入的。上述兩種觀點可能會讓你很疑惑,兩者觀點似乎構(gòu)成了一種循環(huán),但各有利弊。下面我們通過一個例子來理解這兩者的區(qū)別。
假如你想為應(yīng)用設(shè)置很多的常量或參數(shù),這種情況下,XML是一個很好的選擇,因為它不會同特定的代碼相連。如果你想把某個方法聲明為服務(wù),那么使用Annotation會更好一些,因為這種情況下需要注解和方法緊密耦合起來,開發(fā)人員也必須認識到這點。
另一個很重要的因素是Annotation定義了一種標準的描述元數(shù)據(jù)的方式。在這之前,開發(fā)人員通常使用他們自己的方式定義元數(shù)據(jù)。例如,使用標記interfaces,注釋,transient關(guān)鍵字等等。每個程序員按照自己的方式定義元數(shù)據(jù),而不像Annotation這種標準的方式。
注解是如何工作的當注解標注到某個類或者方法或者某個成員變量或者某個輸入?yún)?shù)上的時候,一定有一個對應(yīng)的機制來對注解標注的類、方法、成員變量和參數(shù)進行某些處理。
編寫Annotation非常簡單,注解本身也可以說是一個類。可以將Annotation的定義同接口的定義進行比較。看個例子,標準的注解@Override:
package java.lang; import java.lang.annotation.*; @Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface Override { }
可以看見,@Override注解似乎什么都沒做,那它是如何檢查在父類中有一個同名的函數(shù)?@Override注解的定義僅僅是元數(shù)據(jù),不包含業(yè)務(wù)邏輯,而實現(xiàn)業(yè)務(wù)邏輯的就是注解的用戶。
對于@Override注解,它的用戶就是JVM虛擬機,工作在字節(jié)碼層面,在編譯階段進行檢查,其處理機制主要是JVM內(nèi)部處理。
再例如Spring中的 @Service 注解,Spring在啟動IOC容器的時候會對每個類進行掃描,把所有標注@Component及其子注解如@Service的類進行Bean處理。
編寫自定義的注解JDK5.0版本在 java.lang.annotation提供了四種元注解,專門注解其他的注解:
@Documented – 是否將注解信息添加在java文檔中
@Retention – 定義該注解的生命周期
@Target –注解用于什么地方
@Inherited – 是否允許子類繼承該注解
@Retention 注解定義該注解的生命周期,在什么階段丟棄,
RetentionPolicy.SOURCE – 在編譯階段丟棄。這些注解在編譯結(jié)束之后就不再有任何意義,所以它們不會寫入字節(jié)碼。@Override, @SuppressWarnings都屬于這類注解。
RetentionPolicy.CLASS – 在類加載的時候丟棄,在字節(jié)碼文件的處理中有用。注解默認使用這種方式。
RetentionPolicy.RUNTIME – 始終不會丟棄,運行期也保留該注解,因此可以使用反射機制讀取該注解的信息。自定義的注解通常使用這種方式。
@Target – 表示該注解用于什么地方。如果不明確指出,該注解可以放在任何地方。屬性的注解是兼容的。
ElementType.TYPE:用于描述類、接口或enum聲明
ElementType.FIELD:用于描述實例變量
ElementType.METHOD
ElementType.PARAMETER
ElementType.CONSTRUCTOR
ElementType.LOCAL_VARIABLE
ElementType.ANNOTATION_TYPE 另一個注釋
ElementType.PACKAGE 用于記錄java文件的package信息
那么,注解的內(nèi)部到底是如何定義的呢?Annotations只支持基本類型、String及枚舉類型。注釋中所有的屬性被定義成方法,并允許提供默認值。
定義一個 @AuthCheck 注解,作用在SpringMVC controller的方法上。
package com.liuning.sys.auth; import static java.lang.annotation.ElementType.METHOD; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Documented @Target(METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface AuthCheck { String value() default ""; }
注解中只有一個屬性,可以直接命名為“value”,使用時無需再標明屬性名。
在Spring的攔截器HandlerInterceptor中實現(xiàn)@AuthCheck注解的業(yè)務(wù)邏輯,這里使用了反射機制。
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HandlerMethod hm = (HandlerMethod) handler; AuthCheck ac = hm.getMethodAnnotation(AuthCheck.class); if (ac != null) { if (ac.value() == "Login") { //進行業(yè)務(wù)邏輯操作 } } return true; }
下面的例子演示了如何使用上面的注解。使用了該注解的方法在用戶調(diào)用的時候會需要用戶已登錄。
@PostMapping("/list") @AuthCheck(value = "Login") public ListgetUserList(@RequestBody @Valid User user) { return userService.getUserList(user); }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/75128.html
摘要:數(shù)據(jù)結(jié)構(gòu)和算法樹快速排序,堆排序,插入排序其實八大排序算法都應(yīng)該了解一致性算法,一致性算法的應(yīng)用的內(nèi)存結(jié)構(gòu)。如何存儲一個的。八大排序算法一定要手敲一遍快排,堆排尤其重要。面試是一個雙向選擇的過程,不要抱著畏懼的心態(tài)去面試,不利于自己的發(fā)揮。 前言 16年畢業(yè)到現(xiàn)在也近兩年了,最近面試了阿里集團(菜鳥網(wǎng)絡(luò),螞蟻金服),網(wǎng)易,滴滴,點我達,最終收到點我達,網(wǎng)易offer,螞蟻金服二面掛掉,...
摘要:操作完成后,服務(wù)會自行停止運行。創(chuàng)建工作隊列,用于將逐一傳遞給實現(xiàn),這樣您就永遠不必擔心多線程問題。是的消息機制,集中解決線程間通信問題。 2017 Android 面試題 [ 基礎(chǔ)與細節(jié) ] 感謝@chuyao拋出的這些問題,平時業(yè)務(wù)代碼寫多了,很多基礎(chǔ)的東西變得含糊不清了,這次裸辭出來找工作確實沒有之前順利,順便求上海Android開發(fā)的坑。我自己整理了些答案,不對或者不妥的地方請...
閱讀 3049·2021-11-22 15:29
閱讀 1729·2021-10-12 10:11
閱讀 1751·2021-09-04 16:45
閱讀 2229·2021-08-25 09:39
閱讀 2790·2021-08-18 10:20
閱讀 2509·2021-08-11 11:17
閱讀 447·2019-08-30 12:49
閱讀 3305·2019-08-30 12:49