最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文詳解Spring構(gòu)造函數(shù)推斷

 更新時(shí)間:2023年04月07日 11:31:52   作者:這堆干貨有點(diǎn)猛  
這篇文章主要介紹了Spring構(gòu)造函數(shù)推斷自動(dòng)注入及底層原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加

正文

Spring 提供了一組基本的功能,例如依賴注入(DI)和面向切面編程(AOP)。其中一個(gè)非常強(qiáng)大的功能是構(gòu)造函數(shù)自動(dòng)注入,也稱為構(gòu)造函數(shù)推斷。在本文中,我們將深入探討Spring構(gòu)造函數(shù)推斷的底層原理,并解釋Spring是如何實(shí)現(xiàn)它的。

自動(dòng)注入

構(gòu)造函數(shù)自動(dòng)注入是指 Spring 自動(dòng)解析 bean 的構(gòu)造函數(shù)參數(shù),并將它們傳遞給相應(yīng)的構(gòu)造函數(shù)。這樣,我們就不必顯式地在XML或Java配置文件中指定每個(gè) bean 的構(gòu)造函數(shù)參數(shù)。這是一個(gè)非常方便的功能,特別是在有許多 bean 需要注入的情況下。

底層原理

Spring 使用 Java 反射機(jī)制來(lái)執(zhí)行構(gòu)造函數(shù)推斷。當(dāng) Spring 需要實(shí)例化一個(gè) bean 時(shí),它將首先使用 Java 反射機(jī)制檢查該 bean 的構(gòu)造函數(shù)。

然后,它將檢查每個(gè)構(gòu)造函數(shù)的參數(shù)類型,并嘗試在 Spring 應(yīng)用程序上下文中查找與參數(shù)類型匹配的 bean。

如果找到匹配的 bean,則 Spring 將使用該 bean 實(shí)例化構(gòu)造函數(shù)參數(shù)。如果找不到匹配的 bean,則 Spring 將繼續(xù)檢查下一個(gè)構(gòu)造函數(shù)。

如果沒(méi)有任何構(gòu)造函數(shù)可以匹配,則 Spring 將拋出一個(gè)異常。但是,可以使用 @Autowired(required=false) 注解來(lái)取消必需的依賴關(guān)系,這意味著如果找不到與構(gòu)造函數(shù)參數(shù)類型匹配的bean,則 Spring 將不會(huì)拋出異常。

以下是一個(gè)簡(jiǎn)單的例子,說(shuō)明如何在 Spring 中使用構(gòu)造函數(shù)推斷:

public class MyBean {
    private final MyDependency myDependency;
    public MyBean(MyDependency myDependency) {
        this.myDependency = myDependency;
    }
    public void doSomething() {
        myDependency.doSomething();
    }
}

在這個(gè)例子中,MyBean依賴于MyDependency。Spring 將使用構(gòu)造函數(shù)推斷自動(dòng)注入 MyDependency,而不需要在XML或Java配置文件中顯式指定。

@Configuration
public class AppConfig {
    @Bean
    public MyDependency myDependency() {
        return new MyDependency();
    }
    @Bean
    public MyBean myBean() {
        return new MyBean(myDependency());
    }
}

在這個(gè)例子中,AppConfig 類使用 @Configuration 注解指定一個(gè) Spring 應(yīng)用程序上下文,并定義兩個(gè)bean:MyDependency 和 MyBean。在 MyBean 的構(gòu)造函數(shù)中,我們將 MyDependency 作為參數(shù)傳遞,Spring 將使用構(gòu)造函數(shù)推斷自動(dòng)注入 MyDependency。

構(gòu)造函數(shù)推斷的限制

構(gòu)造函數(shù)推斷有一些限制,例如:

  • 如果有多個(gè)構(gòu)造函數(shù)可以匹配,則 Spring 將拋出一個(gè)異常。在這種情況下,您需要使用 @Qualifier 注解來(lái)指定要注入的 bean。

  • 如果構(gòu)造函數(shù)參數(shù)是原始類型(例如int、float、boolean等),則 Spring 無(wú)法推斷它們。在這種情況下,您需要使用 @Value 注解將值直接注入到構(gòu)造函數(shù)參數(shù)中。

  • 如果構(gòu)造函數(shù)參數(shù)是數(shù)組或集合,則 Spring 無(wú)法推斷它們。在這種情況下,您需要使用 @Qualifier 注解和 @Autowired 的 List 或 Set 類型的字段來(lái)手動(dòng)注入數(shù)組或集合。

源碼解析

Spring 使用 BeanWrapperImpl 類來(lái)執(zhí)行構(gòu)造函數(shù)推斷。BeanWrapperImpl 類是 Spring 的核心類之一,它提供了一種方便的方式來(lái)對(duì) Java 對(duì)象進(jìn)行包裝和訪問(wèn)。以下是 Spring 中用于執(zhí)行構(gòu)造函數(shù)推斷的 BeanWrapperImpl 類的源代碼:

public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWrapper {
    // ...
    @Override
    public Object createInstance() throws BeansException {
        // 獲取Bean的構(gòu)造函數(shù)
        Constructor<?> constructorToUse = this.constructorResolver.autowireConstructor;
        if (constructorToUse == null) {
            throw new BeansException("No default constructor found");
        }
        try {
            // 使用構(gòu)造函數(shù)創(chuàng)建Bean實(shí)例,并返回
            return constructorToUse.newInstance(getConstructorArgumentValues(constructorToUse), getBeanClassLoader());
        }
        catch (Throwable ex) {
            throw new BeanCreationException("Could not instantiate bean", ex);
        }
    }
    // ...
    private Constructor<?> autowireConstructor;
    // ...
    public BeanWrapperImpl(Class<?> clazz) {
        super();
        this.objectType = clazz;
        this.propertyEditorRegistry = new SimpleTypeConverter();
        this.constructorResolver = new ConstructorResolver(this.objectType, this);
    }
    // ...
    private class ConstructorResolver {
        // ...
        public ConstructorResolver(Class<?> clazz, BeanWrapperImpl bw) {
            // 查找可以使用的構(gòu)造函數(shù)并將其緩存
            Constructor<?>[] candidates = clazz.getDeclaredConstructors();
            Constructor<?> autowireCandidate = null;
            int numAutowireCandidates = 0;
            for (Constructor<?> candidate : candidates) {
                if (candidate.isAnnotationPresent(Autowired.class)) {
                    autowireCandidate = candidate;
                    numAutowireCandidates++;
                }
            }
            if (numAutowireCandidates == 1) {
                this.autowireConstructor = autowireCandidate;
            }
            else if (numAutowireCandidates > 1) {
                throw new BeansException("Multiple autowire constructors found");
            }
        }
        // ...
    }
    // ...
}

在BeanWrapperImpl 類中,構(gòu)造函數(shù)推斷是在 createInstance() 方法中執(zhí)行的。該方法首先獲取與Bean匹配的構(gòu)造函數(shù)(由constructorResolver.autowireConstructor決定),然后使用該構(gòu)造函數(shù)創(chuàng)建 Bean 實(shí)例。

ConstructorResolver 內(nèi)部類中,構(gòu)造函數(shù)推斷是通過(guò)查找?guī)в?@Autowired 注解的構(gòu)造函數(shù)來(lái)實(shí)現(xiàn)的。如果找到了一個(gè)帶有 Autowired注解 的構(gòu)造函數(shù),則它將被緩存到 autowireConstructor 字段中,并在 createInstance() 方法中使用。

結(jié)論

構(gòu)造函數(shù)自動(dòng)注入是 Spring 的一個(gè)非常強(qiáng)大的功能,它可以大大簡(jiǎn)化 bean 的配置和管理。我們深入探討了 Spring 構(gòu)造函數(shù)推斷的底層原理,并解釋了 Spring 是如何實(shí)現(xiàn)它的,還提供了一個(gè)簡(jiǎn)單的例子和源代碼解析,以幫助大家更好地了解構(gòu)造函數(shù)推斷的工作方式。

以上就是一文詳解Spring構(gòu)造函數(shù)推斷的詳細(xì)內(nèi)容,更多關(guān)于Spring 構(gòu)造函數(shù)推斷的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring Boot整合SSE實(shí)時(shí)通信的問(wèn)題小結(jié)

    Spring Boot整合SSE實(shí)時(shí)通信的問(wèn)題小結(jié)

    本文介紹了服務(wù)器發(fā)送事件(Server-Sent Events,SSE)技術(shù),其主要特點(diǎn)包括單向數(shù)據(jù)流、自動(dòng)重連、自定義事件類型等,SSE適用于實(shí)時(shí)更新場(chǎng)景,如新聞推送、評(píng)論系統(tǒng)等,感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • SpringBoot 如何優(yōu)雅的實(shí)現(xiàn)跨服務(wù)器上傳文件的示例

    SpringBoot 如何優(yōu)雅的實(shí)現(xiàn)跨服務(wù)器上傳文件的示例

    這篇文章主要介紹了SpringBoot 如何優(yōu)雅的實(shí)現(xiàn)跨服務(wù)器上傳文件的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2006-11-11
  • SpringCloud持久層框架MyBatis Plus的使用與原理解析

    SpringCloud持久層框架MyBatis Plus的使用與原理解析

    MyBatisPlus為MyBatis的增強(qiáng)版,專注于簡(jiǎn)化數(shù)據(jù)庫(kù)操作,提供自動(dòng)化CRUD、內(nèi)置分頁(yè)和樂(lè)觀鎖等功能,極大提升開(kāi)發(fā)效率,在SpringCloud微服務(wù)架構(gòu)中,MyBatisPlus通過(guò)插件機(jī)制和自動(dòng)生成代碼功能,有效支持企業(yè)級(jí)應(yīng)用和分布式系統(tǒng)的開(kāi)發(fā)
    2024-10-10
  • Java中 URL實(shí)現(xiàn)斷點(diǎn)下載

    Java中 URL實(shí)現(xiàn)斷點(diǎn)下載

    Java中 URL實(shí)現(xiàn)斷點(diǎn)下載,需要的朋友可以參考一下
    2013-03-03
  • Java如何給Word文檔添加多行文字水印

    Java如何給Word文檔添加多行文字水印

    這篇文章主要介紹了Java如何給Word文檔添加多行文字水印,文章圖文講解的很清晰,有對(duì)于這方面不太懂得同學(xué)可以學(xué)習(xí)下
    2021-02-02
  • Java線程本地變量導(dǎo)致的緩存問(wèn)題解決方法

    Java線程本地變量導(dǎo)致的緩存問(wèn)題解決方法

    使用緩存可以緩解大流量壓力,顯著提高程序的性能,我們?cè)谑褂镁彺嫦到y(tǒng)時(shí),尤其是大并發(fā)情況下,經(jīng)常會(huì)遇到一些疑難雜癥,這篇文章主要給大家介紹了關(guān)于Java線程本地變量導(dǎo)致的緩存問(wèn)題的解決方法,需要的朋友可以參考下,
    2024-08-08
  • java字符串日期類Date和Calendar相互轉(zhuǎn)化及相關(guān)常用方法

    java字符串日期類Date和Calendar相互轉(zhuǎn)化及相關(guān)常用方法

    Java語(yǔ)言的Calendar(日歷),Date(日期),和DateFormat(日期格式)組成了Java標(biāo)準(zhǔn)的一個(gè)基本但是非常重要的部分,下面這篇文章主要給大家介紹了關(guān)于java字符串日期類Date和Calendar相互轉(zhuǎn)化及相關(guān)常用方法的相關(guān)資料,需要的朋友可以參考下
    2023-12-12
  • Java公平鎖與非公平鎖的核心原理講解

    Java公平鎖與非公平鎖的核心原理講解

    從公平的角度來(lái)說(shuō),Java 中的鎖總共可分為兩類:公平鎖和非公平鎖。但公平鎖和非公平鎖有哪些區(qū)別?核心原理是什么?本文就來(lái)和大家詳細(xì)聊聊
    2022-11-11
  • SpringBoot開(kāi)發(fā)教程之AOP日志處理

    SpringBoot開(kāi)發(fā)教程之AOP日志處理

    現(xiàn)在凡是企業(yè)級(jí)的或者稍微大點(diǎn)項(xiàng)目,基本都需要日志管理,下面這篇文章主要給大家介紹了關(guān)于SpringBoot開(kāi)發(fā)教程之AOP日志處理 的相關(guān)資料,需要的朋友可以參考下
    2021-10-10
  • Java枚舉學(xué)習(xí)之定義和基本特性詳解

    Java枚舉學(xué)習(xí)之定義和基本特性詳解

    枚舉是JAVA?5.0后增加的一個(gè)重要類型??梢杂脕?lái)表示一組取值范圍固定的變量。本文將通過(guò)示例為大家詳細(xì)講解枚舉的定義和基本特性,感興趣的可以了解一下
    2022-08-08

最新評(píng)論

建德市| 吉水县| 泰和县| 任丘市| 巴南区| 台山市| 从江县| 昌黎县| 昭平县| 咸丰县| 鄂托克旗| 铅山县| 太保市| 建宁县| 永胜县| 临朐县| 祥云县| 交口县| 永泰县| 娄烦县| 鸡西市| 宜春市| 松江区| 峨眉山市| 呼伦贝尔市| 南乐县| 乌恰县| 微博| 阿鲁科尔沁旗| 新沂市| 滦南县| 江孜县| 中山市| 德格县| 揭东县| 澄江县| 息烽县| 汤原县| 涞源县| 雅江县| 天津市|