亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

正文

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

自動注入

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

底層原理

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

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

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

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

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

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

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

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

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

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

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

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

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

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

源碼解析

Spring 使用 BeanWrapperImpl 類來執(zhí)行構(gòu)造函數(shù)推斷。BeanWrapperImpl 類是 Spring 的核心類之一,它提供了一種方便的方式來對 Java 對象進行包裝和訪問。以下是 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實例,并返回
            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 實例。

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

結(jié)論

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

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

相關(guān)文章

  • 深入淺出MappedByteBuffer(推薦)

    深入淺出MappedByteBuffer(推薦)

    MappedByteBuffer使用虛擬內(nèi)存,因此分配(map)的內(nèi)存大小不受JVM的-Xmx參數(shù)限制,但是也是有大小限制的,這篇文章主要介紹了MappedByteBuffer的基本知識,需要的朋友可以參考下
    2022-12-12
  • 基于Java實現(xiàn)音樂播放器的示例代碼

    基于Java實現(xiàn)音樂播放器的示例代碼

    這篇文章主要為大家詳細介紹了如何利用Java編寫一個簡單的音樂播放器,文中的示例代碼講解詳細,具有一定的學習價值,感興趣的小伙伴可以了解一下
    2023-07-07
  • 一文搞懂Java設(shè)計模式之責任鏈模式

    一文搞懂Java設(shè)計模式之責任鏈模式

    這篇文章主要給大家介紹了關(guān)于Java設(shè)計模式之責任鏈模式的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • 淺談Java中的Filter過濾器

    淺談Java中的Filter過濾器

    本篇文章主要介紹了淺談Java中的Filter過濾器,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02
  • SpringBoot中的static靜態(tài)資源訪問、參數(shù)配置、代碼自定義訪問規(guī)則詳解

    SpringBoot中的static靜態(tài)資源訪問、參數(shù)配置、代碼自定義訪問規(guī)則詳解

    這篇文章主要介紹了SpringBoot的static靜態(tài)資源訪問、參數(shù)配置、代碼自定義訪問規(guī)則,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-07-07
  • SpringBoot處理跨域請求的四種方法

    SpringBoot處理跨域請求的四種方法

    在現(xiàn)代Web應(yīng)用中,由于安全性和隱私的考慮,瀏覽器限制了從一個域向另一個域發(fā)起的跨域HTTP請求,解決這個問題的一種常見方式是實現(xiàn)跨域資源共享(CORS),SpringBoot提供了多種方式來處理跨域請求,本文將介紹其中的幾種方法,感興趣的朋友可以參考下
    2023-12-12
  • JAVA基于SnakeYAML實現(xiàn)解析與序列化YAML

    JAVA基于SnakeYAML實現(xiàn)解析與序列化YAML

    這篇文章主要介紹了JAVA基于SnakeYAML實現(xiàn)解析與序列化YAML,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • springboot2.x引入feign踩的坑及解決

    springboot2.x引入feign踩的坑及解決

    這篇文章主要介紹了springboot2.x引入feign踩的坑及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • httpclient的disableConnectionState方法工作流程

    httpclient的disableConnectionState方法工作流程

    這篇文章主要為大家介紹了httpclient的disableConnectionState方法工作流程源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-11-11
  • Java并發(fā)編程(CyclicBarrier)實例詳解

    Java并發(fā)編程(CyclicBarrier)實例詳解

    這篇文章主要介紹了Java并發(fā)編程(CyclicBarrier)實例詳解的相關(guān)資料,JAVA編寫并發(fā)程序的時候,我們需要仔細去思考一下并發(fā)流程的控制,如何讓各個線程之間協(xié)作完成某項工作。
    2017-07-07

最新評論