溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

springBoot之spring.factories擴(kuò)展機(jī)制是什么

發(fā)布時(shí)間:2023-04-17 15:30:53 來源:億速云 閱讀:108 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容主要講解“springBoot之spring.factories擴(kuò)展機(jī)制是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“springBoot之spring.factories擴(kuò)展機(jī)制是什么”吧!

1. spring.factories八股總結(jié)

1.1 spring.factories文件格式

在分析spring.factories的底層實(shí)現(xiàn)之前,我們需要了解spring.factories文件的格式。spring.factories文件是一個(gè)標(biāo)準(zhǔn)的Properties文件,其中鍵是要擴(kuò)展的類型的全限定名,值是要注冊(cè)的bean的全限定名。

例如 

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.example.MyAutoConfiguration。

1.2 SpringFactoriesLoader類

SpringFactoriesLoader是一個(gè)實(shí)用類,它用于加載spring.factories文件并注冊(cè)bean定義。以下是SpringFactoriesLoader類的源代碼: loadFactory方法首先使用傳遞的Class對(duì)象的名稱作為鍵調(diào)用loadFactories方法來獲取已注冊(cè)bean的全限定名列表。然后,它使用Java 8的Stream API將全限定名列表映射到相應(yīng)的Class對(duì)象,并使用反射通過無參數(shù)構(gòu)造函數(shù)實(shí)例化每個(gè)Class對(duì)象。最后,它將實(shí)例化的對(duì)象收集到一個(gè)List對(duì)象中并返回。

1.3 loadFactories方法

loadFactories方法是SpringFactoriesLoader類的私有方法,它接收一個(gè)要擴(kuò)展的類型的Class對(duì)象和一個(gè)ClassLoader對(duì)象,并返回一個(gè)包含所有已注冊(cè)bean的List對(duì)象loadFactories方法首先使用傳遞的Class對(duì)象的名稱作為鍵從緩存Map中獲取已注冊(cè)bean的全限定名列表。

如果緩存中沒有,則使用傳遞的ClassLoader對(duì)象從classpath中獲取所有spring.factories文件的URL,并使用PropertiesLoaderUtils類加載每個(gè)文件中的Properties對(duì)象。

對(duì)于每個(gè)Properties對(duì)象,它獲取與傳遞的Class對(duì)象的名稱相對(duì)應(yīng)的屬性值, 在Spring Boot中,spring.factories是一個(gè)非常重要的配置文件,它用于實(shí)現(xiàn)Spring Boot的自動(dòng)化配置。這個(gè)文件位于META-INF/spring.factories路徑下,通??梢栽陧?xiàng)目的classpath下找到。

spring.factories文件的格式如下所示:

# Auto Configuration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.MyAutoConfiguration

這個(gè)文件中定義了一個(gè)名為org.springframework.boot.autoconfigure.EnableAutoConfiguration的屬性,它的值是一個(gè)類的完全限定名,即com.example.MyAutoConfiguration。這個(gè)類通常是一個(gè)Spring配置類,用于定義一些自動(dòng)化配置。

Spring Boot在啟動(dòng)時(shí)會(huì)掃描classpath中的所有spring.factories文件,并讀取其中定義的屬性。然后,它會(huì)根據(jù)這些屬性值加載對(duì)應(yīng)的類,并將它們注冊(cè)到Spring的ApplicationContext中。

好吧,如上所示是Spring Boot中spring.factories的底層源碼解析: 整個(gè)加載過程我們可以大致分為5步.

你也可以理解為咱們整理的為了方便記憶八股文吧 

  • Spring Boot通過SpringFactoriesLoader類來加載spring.factories文件。這個(gè)類是Spring框架中的一個(gè)工具類,用于加載classpath下的所有spring.factories文件,并將它們的內(nèi)容存儲(chǔ)在一個(gè)Map<String, List<String>>對(duì)象中。

  • Spring Boot使用SpringFactoriesLoader.loadFactoryNames方法來加載指定屬性名的所有實(shí)現(xiàn)類。這個(gè)方法會(huì)從步驟1中加載的Map<String, List<String>>對(duì)象中獲取對(duì)應(yīng)屬性名的實(shí)現(xiàn)類列表。

  • Spring Boot使用SpringFactoriesLoader.loadFactories方法來加載指定屬性名的所有實(shí)現(xiàn)類的實(shí)例。這個(gè)方法會(huì)遍歷步驟2中獲取的實(shí)現(xiàn)類列表,并使用反射機(jī)制實(shí)例化每一個(gè)類。

  • Spring Boot會(huì)將步驟3中實(shí)例化的類注冊(cè)為Spring的Bean。它會(huì)調(diào)用AnnotationConfigUtils.registerAnnotationConfigProcessors方法來注冊(cè)自動(dòng)配置類。這個(gè)方法會(huì)調(diào)用BeanDefinitionRegistryPostProcessor接口的實(shí)現(xiàn)類的postProcessBeanDefinitionRegistry方法,來注冊(cè)自動(dòng)配置類的BeanDefinition。

  • Spring Boot會(huì)啟動(dòng)Spring的ApplicationContext,并讓它自動(dòng)掃描所有的Bean。它會(huì)調(diào)用AnnotationConfigApplicationContext.refresh方法來啟動(dòng)ApplicationContext,并讓它自動(dòng)掃描所有的Bean。在掃描過程中,Spring會(huì)發(fā)現(xiàn)步驟4中注冊(cè)的自動(dòng)配置類,并嘗試自動(dòng)配置應(yīng)用程序。

/**
 * SpringFactoriesLoader類是Spring框架中的一個(gè)工具類,用于加載classpath下的所有spring.factories文件,
 * 并將它們的內(nèi)容存儲(chǔ)在一個(gè)Map<String, List<String>>對(duì)象中。
 */
public final class SpringFactoriesLoader {
    /**
     * 私有構(gòu)造函數(shù),不允許實(shí)例化。
     */
    private SpringFactoriesLoader() {
    }
    /**
     * 加載指定屬性名的所有實(shí)現(xiàn)類的類名列表。
     * @param factoryType 屬性名
     * @param classLoader 類加載器
     * @return 類名列表
     */
    public static List<String> loadFactoryNames(Class<?> factoryType, ClassLoader classLoader) {
        // ...
    }
    /**
     * 加載指定屬性名的所有實(shí)現(xiàn)類的實(shí)例。
     * @param factoryType 屬性名
     * @param classLoader 類加載器
     * @param <T> 實(shí)現(xiàn)類的類型
     * @return 實(shí)現(xiàn)類的實(shí)例列表
     */
    public static <T> List<T> loadFactories(Class<T> factoryType, ClassLoader classLoader) {
        // 省略 ...
    }
}
/**
 * AnnotationConfigUtils類提供了一些用于處理注解配置的工具方法。
 */
class AnnotationConfigUtils {
    /**
     * 注冊(cè)自動(dòng)配置類。
     * @param registry Bean定義注冊(cè)器
     */
    public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
        // ...
    }
}
/**
 * AnnotationConfigApplicationContext類是Spring的ApplicationContext接口的一個(gè)實(shí)現(xiàn)類,
 * 用于支持基于Java配置的應(yīng)用程序上下文。
 */
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
    /**
     * 啟動(dòng)ApplicationContext,并讓它自動(dòng)掃描所有的Bean。
     */
    @Override
    public void refresh() throws BeansException, IllegalStateException {
        // ...
    }
}

到此,相信大家對(duì)“springBoot之spring.factories擴(kuò)展機(jī)制是什么”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI