国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Java 注解實(shí)戰(zhàn)

Jochen / 1855人閱讀

摘要:注解是的一個(gè)新特性。很重要,生產(chǎn)中我們開發(fā)常用此值表示注解是否可被子元素繼承。類注解方法注解通過反射獲取方法對象此部分內(nèi)容可參考通過反射獲取注解信息注解處理器實(shí)戰(zhàn)接下來我通過在公司中的一個(gè)實(shí)戰(zhàn)改編來演示一下注解處理器的真實(shí)使用場景。

前言:Java 注解,對于很多人都不陌生了,但是在公司的實(shí)際開發(fā)中,可能讓我們自己去定義注解并應(yīng)用到生產(chǎn)環(huán)境中的機(jī)會比較少,所以會導(dǎo)致一部分人對注解的理解比較淺,在看到一些框架或者別人的代碼中有注解的代碼就會頭大,不知道這代表的是什么意思。其實(shí)究其原因,最主要的還是我們對注解的這個(gè)概念沒搞清楚,所以本文通篇會串插著這些重要的概念,從幾個(gè)主題入手,從淺到深的帶領(lǐng)大家進(jìn)入注解的世界,讓大家在今后的代碼旅程中輕松應(yīng)對注解。

注解是 Java 5 的一個(gè)新特性。先給大家梳理一個(gè)在生產(chǎn)環(huán)境中注解的常用使用流程。第一步: 定義一個(gè)注解;第二步: 在類上面或方法上面等地方使用注解;第三步: 通過注解處理器獲取注解信息并做相應(yīng)的處理(這個(gè)處理也就是注解真正起作用的地方了)。本篇文章的整個(gè)脈絡(luò)大致也是按照這三步來寫的。

JDK 內(nèi)置注解

先來看幾個(gè) Java 內(nèi)置的注解,讓大家熱熱身。

@Override 演示

class Parent {
    public void run() {
    }
}

class Son extends Parent {
    /**
     * 這個(gè)注解是為了檢查此方法是否真的是重寫父類的方法
     * 這時(shí)候就不用我們用肉眼去觀察到底是不是重寫了
     */
    @Override
    public void run() {
    }
}

@Deprecated 演示

class Parent {

    /**
     * 此注解代表過時(shí)了,但是如果可以調(diào)用到,當(dāng)然也可以正常使用
     * 但是,此方法有可能在以后的版本升級中會被慢慢的淘汰
     * 可以放在類,變量,方法上面都起作用
     */
    @Deprecated
    public void run() {
    }
}

public class JDKAnnotationDemo {
    public static void main(String[] args) {
        Parent parent = new Parent();
        parent.run(); // 在編譯器中此方法會顯示過時(shí)標(biāo)志
    }
}

@SuppressWarnings 演示

class Parent {

    // 因?yàn)槎x的 name 沒有使用,那么編譯器就會有警告,這時(shí)候使用此注解可以屏蔽掉警告
    // 即任意不想看到的編譯時(shí)期的警告都可以用此注解屏蔽掉,但是不推薦,有警告的代碼最好還是處理一下
    @SuppressWarnings("all")
    private String name;
}

@FunctionalInterface 演示

/**
 * 此注解是 Java8 提出的函數(shù)式接口,接口中只允許有一個(gè)抽象方法
 * 加上這個(gè)注解之后,類中多一個(gè)抽象方法或者少一個(gè)抽象方法都會報(bào)錯(cuò)
 */
@FunctionalInterface
interface Func {
    void run();
}
定義一個(gè)注解 完整注解

這里先提供一個(gè)比較完整的注解,即此注解內(nèi)容基本包含了我們在生產(chǎn)環(huán)境中常用的信息了,然后根據(jù)這個(gè)注解來介紹枚舉的重要概念。首先看到下面這個(gè)完整注解包含三部分內(nèi)容,第一部分就是 @interface 來定義注解,所有注解隱式繼承 java.lang.annotation.Annotation;第二部分就是這個(gè)注解的內(nèi)部信息;第三部分就是這個(gè)注解的頭部,即元注解。

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER, ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)
@Inherited // 此注解應(yīng)用的相對較少,本文不多做介紹,可自行研究
@Documented // 此注解應(yīng)用的相對較少,本文不多做介紹,可自行研究
public @interface ApiAuthAnnotation {
    int age();

    String name() default "lyf";

    AnnotationDemo annotattion() default @AnnotationDemo;

    Season Sason() default Season.SPRING;

    int[] nums() default {1, 2, 3};

    Class clazz() default String.class;
}
注解內(nèi)部信息

所謂注解內(nèi)部信息,也就是這個(gè)注解里面都寫什么,通過如上的完整注解可以很直觀的看到都寫了什么,其實(shí)就是一種比較特殊的方法了,帶有返回值類型,沒有具體實(shí)現(xiàn),后面可以選填默認(rèn)值。大概也就這么點(diǎn)內(nèi)容了。其支持的數(shù)據(jù)類型有:

基本數(shù)據(jù)類型

java.lang.String

注解

枚舉

一維數(shù)組

java.lang.Class

元注解

元注解是指用于注解類型上的注解。通俗來講,元注解的作用就是,規(guī)范我們定義的注解,給這個(gè)注解一些規(guī)則。比如說: 我在注解頭部沒有寫元注解,那么我們自定義的這個(gè)注解在使用的時(shí)候放在類上面,方法上面,或者放在成員變量上面,沒有規(guī)則,想放哪里就放哪里;但是當(dāng)我們在注解頭部寫了元注解,并把元注解的 Target 設(shè)置為 ElementType.METHOD,那么我們自定義的這個(gè)注解在使用的時(shí)候就只能放在方法上面,放在類上面或者成員變量上面就會報(bào)錯(cuò)。

元注解的注解類型主要有如下幾種:

@Target: 表示定義的注解的作用域,其值包括:

CONSTRUCTOR: 構(gòu)造方法聲明;

FIELD: 屬性/字段聲明;

LOCAL_VARIABLE: 局部變量聲明;

METHOD: 方法聲明;

PACKAGE: 包聲明;

PARAMETER: 參數(shù)聲明;

TYPE: 類接口聲明;

ANNOTATION_TYPE: 注解類型聲明;

TYPE_PARAMETER: 類型參數(shù)聲明(jdk1.8 提供);

TYPE_USE: 類型使用(jdk1.8 提供)

@Retention: 自定義注解的生命周期,其值包括:

SOURCE: 只在源碼顯示,編譯時(shí)丟棄;(比如 jdk 自帶的 @SuppressWarnings 和 @Override)

CLASS: 編譯時(shí)記錄到.class中,運(yùn)行時(shí)忽略;

RUNTIME: 運(yùn)行時(shí)存在,可通過反射來讀取。(很重要,生產(chǎn)中我們開發(fā)常用此值)

@Inherited: 表示注解是否可被子元素繼承。

@Documented: 表示 javadoc 是否為實(shí)例產(chǎn)生文檔

注意事項(xiàng)

注解不能繼承另一個(gè)注解

方法不能有參數(shù)

方法不能拋出異常

不能定義 Object 或 Annotation 接口中的方法(因?yàn)樽⒔舛茧[式繼承 Annotation 接口)

注解不能是泛型

使用 default 指定屬性的默認(rèn)值

不能使用 null 作為屬性的默認(rèn)值

使用注解

這個(gè)當(dāng)然就相當(dāng)簡單了,哪個(gè)地方需要使用我們自定義的注解,那我們在其地方添加上注解就 ok 了。如下代碼: 如果要作用到類,那就在類頭上加上注解;如果要作用到方法,那就在方法上加上注解。

@ApiAuthAnnotation(age = 16, name = "lyf")
@RestController
public class ApiController {

    @ApiAuthAnnotation(age = 20, name = "lisi")
    @RequestMapping(value = "/topic1", method = RequestMethod.GET)
    public void getByTopic1() {
        System.out.println("年齡大于 18 歲的可以訪問此 API");
    }

    @ApiAuthAnnotation(age = 16, name = "zhangsan")
    @RequestMapping(value = "/topic2", method = RequestMethod.GET)
    public void getByTopic2() {
        System.out.println("年齡小于 18 歲的不可以訪問此 API");
    }

}

從如上代碼來看,使用注解的時(shí)候則是相當(dāng)?shù)暮唵瘟耍覀冞@里是在類上和方法上都加上了自定義的注解了,至于這些注解加上以后怎么起作用,那就跟注解處理器有關(guān)了。
【注: 在使用注解的時(shí)候其實(shí)還有很多小的語法技巧,很多時(shí)候可以簡寫一些代碼,不過有沒有必要簡寫代碼,這個(gè)自己去衡量,這個(gè)不是重點(diǎn),就是語法,可以自行去研究下。就比如當(dāng)注解只要一個(gè)元素,且其名字是 value 時(shí),賦值的時(shí)候可以簡寫】

注解處理器

注解處理器才是使用注解整個(gè)流程中最重要的一步了。所有在代碼中出現(xiàn)的注解,它到底起了什么作用,都是在注解處理器中定義好的。
概念:注解本身并不會對程序的編譯方式產(chǎn)生影響,而是注解處理器起的作用;注解處理器能夠通過在運(yùn)行時(shí)使用反射獲取在程序代碼中的使用的注解信息,從而實(shí)現(xiàn)一些額外功能。前提是我們自定義的注解使用的是 RetentionPolicy.RUNTIME 修飾的。這也是我們在開發(fā)中使用頻率很高的一種方式。

我們先來了解下如何通過在運(yùn)行時(shí)使用反射獲取在程序中的使用的注解信息。如下類注解和方法注解。

類注解
Class aClass = ApiController.class;
Annotation[] annotations = aClass.getAnnotations();

for(Annotation annotation : annotations) {
    if(annotation instanceof ApiAuthAnnotation) {
        ApiAuthAnnotation apiAuthAnnotation = (ApiAuthAnnotation) annotation;
        System.out.println("name: " + apiAuthAnnotation.name());
        System.out.println("age: " + apiAuthAnnotation.age());
    }
}
方法注解
Method method = ... //通過反射獲取方法對象
Annotation[] annotations = method.getDeclaredAnnotations();

for(Annotation annotation : annotations) {
    if(annotation instanceof ApiAuthAnnotation) {
        ApiAuthAnnotation apiAuthAnnotation = (ApiAuthAnnotation) annotation;
        System.out.println("name: " + apiAuthAnnotation.name());
        System.out.println("age: " + apiAuthAnnotation.age());
    }
}   

此部分內(nèi)容可參考: 通過反射獲取注解信息

注解處理器實(shí)戰(zhàn)

接下來我通過在公司中的一個(gè)實(shí)戰(zhàn)改編來演示一下注解處理器的真實(shí)使用場景。
需求: 網(wǎng)站后臺接口只能是年齡大于 18 歲的才能訪問,否則不能訪問
前置準(zhǔn)備: 定義注解(這里使用上文的完整注解),使用注解(這里使用上文中使用注解的例子)
接下來要做的事情: 寫一個(gè)切面,攔截瀏覽器訪問帶注解的接口,取出注解信息,判斷年齡來確定是否可以繼續(xù)訪問。

在 dispatcher-servlet.xml 文件中定義 aop 切面


    
    
    
    
        
    

切面類處理邏輯即注解處理器代碼如

@Component("apiAuthAspect")
public class ApiAuthAspect {

    public Object auth(ProceedingJoinPoint pjp) throws Throwable {
        Method method = ((MethodSignature) pjp.getSignature()).getMethod();
        ApiAuthAnnotation apiAuthAnnotation = method.getAnnotation(ApiAuthAnnotation.class);
        Integer age = apiAuthAnnotation.age();
        if (age > 18) {
            return pjp.proceed();
        } else {
            throw new RuntimeException("你未滿18歲,禁止訪問");
        }
    }
}
總結(jié)

注解其實(shí)在我們的代碼中用的也越來越多了,特別是框架里面都會提供很多的注解,把注解的概念搞清楚之后,對于以后看別人的代碼和框架源碼都很多幫助,所以平時(shí)沒事也可以多了解了解。比如我們經(jīng)常使用的 @Autowired 注解,其背后做了什么事情,有興趣都可以去了解一下。再比如,權(quán)限框架 Shiro,里面也提供很多注解來管理權(quán)限,他們是怎么使用注解和處理注解的,都可以去研究下。有什么問題,歡迎老鐵們一起交流。。。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/70707.html

相關(guān)文章

  • Spring Boot 最核心的 3 個(gè)注解詳解

    摘要:核心注解講解最大的特點(diǎn)是無需配置文件,能自動掃描包路徑裝載并注入對象,并能做到根據(jù)下的包自動配置。所以最核心的個(gè)注解就是這是添加的一個(gè)注解,用來代替配置文件,所有這個(gè)配置文件里面能做到的事情都可以通過這個(gè)注解所在類來進(jìn)行注冊。 最近面試一些 Java 開發(fā)者,他們其中有些在公司實(shí)際用過 Spring Boot, 有些是自己興趣愛好在業(yè)余自己學(xué)習(xí)過。然而,當(dāng)我問他們 Spring Boo...

    hzx 評論0 收藏0
  • Spring AOP就是這么簡單啦

    摘要:是一種特殊的增強(qiáng)切面切面由切點(diǎn)和增強(qiáng)通知組成,它既包括了橫切邏輯的定義也包括了連接點(diǎn)的定義。實(shí)際上,一個(gè)的實(shí)現(xiàn)被拆分到多個(gè)類中在中聲明切面我們知道注解很方便,但是,要想使用注解的方式使用就必須要有源碼因?yàn)槲覀円? 前言 只有光頭才能變強(qiáng) 上一篇已經(jīng)講解了Spring IOC知識點(diǎn)一網(wǎng)打盡!,這篇主要是講解Spring的AOP模塊~ 之前我已經(jīng)寫過一篇關(guān)于AOP的文章了,那篇把比較重要的知...

    Jacendfeng 評論0 收藏0
  • 第12章 元編程與注解、反射 《Kotlin 項(xiàng)目實(shí)戰(zhàn)開發(fā)》

    摘要:第章元編程與注解反射反射是在運(yùn)行時(shí)獲取類的函數(shù)方法屬性父類接口注解元數(shù)據(jù)泛型信息等類的內(nèi)部信息的機(jī)制。本章介紹中的注解與反射編程的相關(guān)內(nèi)容。元編程本質(zhì)上是一種對源代碼本身進(jìn)行高層次抽象的編碼技術(shù)。反射是促進(jìn)元編程的一種很有價(jià)值的語言特性。 第12章 元編程與注解、反射 反射(Reflection)是在運(yùn)行時(shí)獲取類的函數(shù)(方法)、屬性、父類、接口、注解元數(shù)據(jù)、泛型信息等類的內(nèi)部信息的機(jī)...

    joyqi 評論0 收藏0
  • SpringBoot 實(shí)戰(zhàn) (十五) | 服務(wù)端參數(shù)校驗(yàn)之一

    摘要:前言估計(jì)很多朋友都認(rèn)為參數(shù)校驗(yàn)是客戶端的職責(zé),不關(guān)服務(wù)端的事。輕則導(dǎo)致服務(wù)器宕機(jī),重則泄露數(shù)據(jù)。所以,這時(shí)就需要設(shè)置第二道關(guān)卡,服務(wù)端驗(yàn)證了。老項(xiàng)目的服務(wù)端校驗(yàn)不能為空不能為空看以上代碼,就一個(gè)的校驗(yàn)就如此麻煩。 前言 估計(jì)很多朋友都認(rèn)為參數(shù)校驗(yàn)是客戶端的職責(zé),不關(guān)服務(wù)端的事。其實(shí)這是錯(cuò)誤的,學(xué)過 Web 安全的都知道,客戶端的驗(yàn)證只是第一道關(guān)卡。它的參數(shù)驗(yàn)證并不是安全的,一旦被有心人...

    QiShare 評論0 收藏0
  • SpringBoot 實(shí)戰(zhàn) (十) | 聲明式事務(wù)

    摘要:前言如題,今天介紹的聲明式事務(wù)。提供一個(gè)注解在配置類上來開啟聲明式事務(wù)的支持。而在配置里還開啟了對聲明式事務(wù)的支持,代碼如下所以在中,無須顯式開啟使用注解。源碼下載后語以上為聲明式事務(wù)的教程。 微信公眾號:一個(gè)優(yōu)秀的廢人如有問題或建議,請后臺留言,我會盡力解決你的問題。 前言 如題,今天介紹 SpringBoot 的 聲明式事務(wù)。 Spring 的事務(wù)機(jī)制 所有的數(shù)據(jù)訪問技術(shù)都有事務(wù)處...

    ygyooo 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<