欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java元注解meta-annotation和依賴注入詳解

 更新時(shí)間:2020年12月20日 08:22:13   作者:sorra  
這篇文章主要給大家介紹了關(guān)于Java元注解meta-annotation和依賴注入的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

這篇文章既介紹一個(gè)技術(shù),又記錄一個(gè)逐漸探索發(fā)現(xiàn)的過程,以供大家參考。

緣起

注意到Java的依賴注入DI規(guī)范(起初以為是CDI規(guī)范,然后發(fā)現(xiàn)是DI規(guī)范)有個(gè)叫@Qualifier的注解,用于當(dāng)一個(gè)interface或base class有多個(gè)實(shí)現(xiàn)類時(shí),能選擇其中一個(gè)實(shí)現(xiàn)。如不用這一注解,一般的(按類型)注入就會(huì)報(bào)錯(cuò)說“不知道要在多個(gè)實(shí)現(xiàn)中選哪一個(gè)”。這一注解可以放在一個(gè)自定義注解上(例如@MyPreferredImplementation),從而將自定義注解變成一個(gè)qualifier annotation(限定符注解),然后只要在某一個(gè)實(shí)現(xiàn)類上放上這個(gè)自定義注解,也在注入處放上這個(gè)自定義注解,就能起到連通雙方的作用,指定注入這個(gè)實(shí)現(xiàn)類了,很方便也很語義化。(大家可以搜索學(xué)習(xí)@Qualifier的教程。)

Spring支持DI規(guī)范,而它自己也有一個(gè)叫@Qualifier注解(包名不相同,在spring的package里),不但支持以上功能,還可以直接放在待注入的變量上,用name參數(shù)(例如@Qualifier(name = “myBeanName”))來指定要注入的那個(gè)實(shí)現(xiàn)類的bean name。Spring的這個(gè)功能好像更常用,至少在某公司就是這樣,DI規(guī)范的qualifier功能反而有些不為人所知了。

我認(rèn)為DI規(guī)范的更好,更加語義化。而這種把一個(gè)注解放在另一個(gè)注解上,是什么Java特性呢?起初不知道正確的關(guān)鍵詞,用“annotation on annotation”之類的詞語左查右查也查不到。然后看JDK的Javadoc,看哪一個(gè)呢,看已知的幾個(gè)“annotation on annotation”,懂的朋友可能想到了,@Retention @Target @Inherited這些JDK內(nèi)置的用來放在另一個(gè)注解上的注解,Javadoc說它們叫做元注解meta-annotation。JDK的這幾個(gè)元注解有很多文章講解,我就不講了,這一篇專講元注解。

探索

我就好奇了,依賴注入框架所用的元注解是怎么實(shí)現(xiàn)的?大家有想過嗎?比如說,框架怎么知道哪些注解被標(biāo)了@Qualifier元注解?第一反應(yīng)是Java內(nèi)置了這方面的支持,因?yàn)閱卧獪y(cè)試框架的@Test等注解也有元注解功能,這么常用的功能或許是Java原生支持的?

因此我就做了試驗(yàn),寫兩個(gè)自定義注解,一個(gè)叫@Virtual元注解,一個(gè)叫@Real注解,把@Virtual放在@Real上,把@Real放到一個(gè)User類上,看看編譯結(jié)果,然后用反射從這個(gè)類上取@Virtual,看@Real能不能自動(dòng)引導(dǎo)到@Virtual上。示例代碼如下:

@Retention(RetentionPolicy.RUNTIME)
public @interface Virtual {
}

@Virtual
@Retention(RetentionPolicy.RUNTIME)
public @interface Real {
}

@Real
public class User {
}

編譯后用IDE查看class文件,發(fā)現(xiàn)@Virtual元注解仍然只標(biāo)在@Real上,User類上只標(biāo)有@Real注解,可證明編譯器沒有為元注解做什么工作。然后反射的結(jié)果也是不能從User類拿到@Virtual,可證明JVM runtime也沒有為元注解做什么工作。因此@Qualifier的元注解特性極有可能是相關(guān)框架自行實(shí)現(xiàn)的。

要怎么實(shí)現(xiàn)呢?我們可以自己動(dòng)腦筋想一想??紤]到,Spring框架掃描所有的class文件(之所以要掃描class文件而非class對(duì)象,是因?yàn)镴ava不提供遍歷所有class對(duì)象的功能,使框架不得不重復(fù)實(shí)現(xiàn)對(duì)class文件的解析工作),將其中有相應(yīng)注解的class轉(zhuǎn)化為BeanDefinition注冊(cè)到BeanFactory。那么@Qualifier也可以類似地處理,對(duì)于掃描到的class,如果它具有@Qualifer注解,并且自身也是注解(實(shí)現(xiàn)了java.lang.Annotation interface),就作為一個(gè)自定義注解注冊(cè)到框架里(比如說,QualifierAnnotationRegistry?),如此一來框架就認(rèn)識(shí)所有的包含@Qualifier元注解的自定義注解了,之后要使用就順理成章了。

發(fā)現(xiàn)

那么Spring實(shí)際上是怎么實(shí)現(xiàn)的呢?我們可以查源碼。到GitHub上找到spring-framework這項(xiàng)目,搜索代碼關(guān)鍵詞Qualifer或javax.inject.Qualifier,查到90多個(gè)Java文件,再在頁面中高亮關(guān)鍵詞”main”以過濾掉單元測(cè)試,憑經(jīng)驗(yàn)翻閱,在前3頁就能找到實(shí)現(xiàn)代碼了:

QualifierAnnotationAutowireCandidateResolver https://github.com/spring-pro... 用于注冊(cè)那些包含javax.inject.Qualifer的自定義注解。

CustomAutowireConfigurer https://github.com/spring-pro... 順便發(fā)現(xiàn)這個(gè)類允許用戶手動(dòng)注冊(cè)自定義注解,無需元注解。

到此這篇關(guān)于Java元注解meta-annotation和依賴注入的文章就介紹到這了,更多相關(guān)Java元注解meta-annotation和依賴注入內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JAVA 時(shí)間區(qū)間的字符串合法性驗(yàn)證

    JAVA 時(shí)間區(qū)間的字符串合法性驗(yàn)證

    需要對(duì)獲得的諸如08:30-11:00這樣的字符串進(jìn)行合法性驗(yàn)證,判定表示的時(shí)間區(qū)間是否合法,以及對(duì)高峰期時(shí)間的區(qū)間是否在總的時(shí)間區(qū)間內(nèi)部進(jìn)行判斷。
    2013-03-03
  • Spring security如何重寫Filter實(shí)現(xiàn)json登錄

    Spring security如何重寫Filter實(shí)現(xiàn)json登錄

    這篇文章主要介紹了Spring security 如何重寫Filter實(shí)現(xiàn)json登錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • java 中的volatile關(guān)鍵字

    java 中的volatile關(guān)鍵字

    這篇文章主要介紹了java 中的volatile關(guān)鍵字,volatile在多處理器開發(fā)中保證共享變量的“可見性”??梢娦缘囊馑际钱?dāng)一個(gè)線程修改一個(gè)共享變量時(shí),另一個(gè)一個(gè)線程立馬可以讀到這個(gè)修改的值。下面我們來看看文章的具體介紹內(nèi)容吧

    2021-12-12
  • 隱藏idea的.idea和.mvn文件的解決方案

    隱藏idea的.idea和.mvn文件的解決方案

    這篇文章主要介紹了隱藏idea的.idea和.mvn文件的解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • Java實(shí)現(xiàn)商品管理系統(tǒng)代碼實(shí)例講解

    Java實(shí)現(xiàn)商品管理系統(tǒng)代碼實(shí)例講解

    這篇文章主要介紹了Java實(shí)現(xiàn)商品管理系統(tǒng)代碼實(shí)例講解,文中代碼實(shí)例講解的很清楚,有需要的同學(xué)可以借鑒參考下
    2021-02-02
  • Java格式化日期和時(shí)間三種方法

    Java格式化日期和時(shí)間三種方法

    這篇文章主要給大家介紹了關(guān)于Java格式化日期和時(shí)間三種方法的相關(guān)資料,最近遇到很多在Java里獲取當(dāng)前時(shí)間的問題,文中通過圖文以及實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • 如何只返回實(shí)體類中的部分字段問題

    如何只返回實(shí)體類中的部分字段問題

    這篇文章主要介紹了如何只返回實(shí)體類中的部分字段問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • Disconf實(shí)現(xiàn)分布式配置管理的原理與設(shè)計(jì)

    Disconf實(shí)現(xiàn)分布式配置管理的原理與設(shè)計(jì)

    這篇文章主要為大家介紹了Disconf實(shí)現(xiàn)分布式配置管理的原理與設(shè)計(jì)分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-03-03
  • springboot連接neo4j報(bào)錯(cuò)的解決方案

    springboot連接neo4j報(bào)錯(cuò)的解決方案

    這篇文章主要介紹了springboot連接neo4j報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • mybatisplus?@Select注解中拼寫動(dòng)態(tài)sql異常問題的解決

    mybatisplus?@Select注解中拼寫動(dòng)態(tài)sql異常問題的解決

    這篇文章主要介紹了mybatisplus?@Select注解中拼寫動(dòng)態(tài)sql異常問題的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12

最新評(píng)論