Java的面向?qū)ο缶幊?/a>">Java的面向?qū)ο缶幊?/a>
944
2022-05-30
問題起源
最近在學(xué)習(xí)shiro,shiro中一個(gè)很便利很優(yōu)雅的地方便是可以給方法添加注解,以便控制當(dāng)前接口內(nèi)部是否能夠被當(dāng)前登錄用戶訪問。
shiro控制樣例代碼如下:
@RequiresPermissions("all") public void test() { renderText("測(cè)試"); }
這行代碼的作用是:限制只有擁有all權(quán)限的用戶才可以訪問該接口,否則會(huì)拋出異常。
那么問題來了,如何實(shí)現(xiàn)Java中非常優(yōu)雅的注解這種形式呢?
注解的實(shí)現(xiàn)原理
注解的實(shí)現(xiàn)是基于反射原理的。
Talk is Cheap, Show me your Code!
一個(gè)注解的實(shí)現(xiàn)過程
下面我們將逐步嘗試實(shí)現(xiàn)一個(gè)我們自己的注解,比如我們叫它MyAnno,他的作用就是在其注解的方法執(zhí)行前輸出一段指定的文字。
實(shí)現(xiàn)注解,首先需要有一個(gè)被標(biāo)記為@interface的接口。
public @interface MyAnno { }
在Java中還有四種注解被稱為元注解,即Java庫幫助我們實(shí)現(xiàn)的注解,分別有Target, Retention,Documented,Inherited
分別表示:
@Target
修改其他注解類,標(biāo)注當(dāng)前注解會(huì)被用在什么地方,使用樣例如:@Target({ElementType.TYPE, ElementType.METHOD})。括號(hào)中可選的參數(shù)可以參考java.lang.annotation.ElementType,我們說幾個(gè)例子:
ElementType.TYPE:表示類注解,類型注解
ElementType.FIELD:字段注解
ElementType.METHOD:方法注解
ElementType.PARAMETER:參數(shù)注解
ElementType.CONSTRUCTOR:構(gòu)造方法注解
ElementType.LOCAL_VARIABLE:局部變量注解
ElementType.ANNOTATION_TYPE:注解的注解
ElementType.PACKAGE:包注解
比如,我們準(zhǔn)備定義的MyAnno為方法注解,則有:
@Target(ElementType.METHOD) public @interface MyAnno { }
@Rentention
表示當(dāng)前注解的運(yùn)行狀態(tài),可取值參見java.lang.annotation.RetentionPolicy:
RetentionPolicy.SOURCE:其注釋為將被編譯器丟棄,只在源碼運(yùn)行;
RetentionPolicy.CLASS:編譯類文件是運(yùn)行;
RetentionPolicy.RUNTIME:運(yùn)行時(shí)運(yùn)行。
比如,我們定義的MyAnno,需要添加代碼如下:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MyAnno { }
@Documented
該注解為生成說明文檔,添加類的解釋,不多說,我們暫且略過。
@Inherited
表示允許子類繼承父類中的繼承,我們也暫且略過。
到這里我們的注解就定義完了。我們來嘗試使用以下,僅僅是使用,還沒到運(yùn)行的時(shí)候。
public class TestAnno { @MyAnno public void testAnno() { System.out.println("testAnno方法內(nèi)部"); } public static void main(String[] args) { new TestAnno().testAnno(); } }
這段代碼可以編譯通過,沒有報(bào)錯(cuò),并且執(zhí)行也沒有問題,當(dāng)然,現(xiàn)在我們的注解還沒有添加動(dòng)作。
那么,怎么給注解添加指定動(dòng)作呢?
最最關(guān)鍵的內(nèi)容:注解執(zhí)行器
注解執(zhí)行器才是注解中最關(guān)鍵的內(nèi)容,上面的代碼僅僅是告訴我們,告訴編譯器與jvm,這個(gè)方法被我們標(biāo)記了。但是具體怎么執(zhí)行,還是要看注解執(zhí)行器的。但是執(zhí)行器設(shè)計(jì)到反射,復(fù)雜的執(zhí)行器還涉及到AOP編程,我們慢慢展開來講。
Java
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。