springBoot?之spring.factories擴展機制示例解析
引言
這個月準備寫完Spring源碼解析系列文章。我相信大多點進來看的同學們都應該或多或少對springBoot的擴展機制有一些了解,我們這次通過八股文歸納法和源碼淺層解析,達到大家對SpringBoot擴展的機制的理解。全文看完大概三分鐘,希望大家都有收獲,畢竟藝多不壓身,知其然知其所以然。
在Spring Boot中,我們通常會看到一些源碼包的META-INF下又一個文件spring.factories。大家都知道它是一種擴展機制,有的同學可能在其他博客中看到把它稱之為Spring Boot SPI。為什么這么稱謂呢,后續(xù)我專門分享一篇Java SPI。那么到底它是如何實現(xiàn)spring Boot的擴展的呢。在本文中,我們將深入探討這種擴展機制的底層源代碼實現(xiàn),以及我們在源碼上標注注釋的形式,共同揭開Spring.factories 的神秘面紗。
1. spring.factories八股總結
如果只是需要應付面試或者只是想大概了解,看完此章節(jié)就可以了
1.1 spring.factories文件格式
在分析spring.factories的底層實現(xiàn)之前,我們需要了解spring.factories文件的格式。spring.factories文件是一個標準的Properties文件,其中鍵是要擴展的類型的全限定名,值是要注冊的bean的全限定名。
例如
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.example.MyAutoConfiguration。
1.2 SpringFactoriesLoader類
SpringFactoriesLoader是一個實用類,它用于加載spring.factories文件并注冊bean定義。以下是SpringFactoriesLoader類的源代碼: loadFactory方法首先使用傳遞的Class對象的名稱作為鍵調用loadFactories方法來獲取已注冊bean的全限定名列表。然后,它使用Java 8的Stream API將全限定名列表映射到相應的Class對象,并使用反射通過無參數(shù)構造函數(shù)實例化每個Class對象。最后,它將實例化的對象收集到一個List對象中并返回。
1.3 loadFactories方法
loadFactories方法是SpringFactoriesLoader類的私有方法,它接收一個要擴展的類型的Class對象和一個ClassLoader對象,并返回一個包含所有已注冊bean的List對象loadFactories方法首先使用傳遞的Class對象的名稱作為鍵從緩存Map中獲取已注冊bean的全限定名列表。
如果緩存中沒有,則使用傳遞的ClassLoader對象從classpath中獲取所有spring.factories文件的URL,并使用PropertiesLoaderUtils類加載每個文件中的Properties對象。
對于每個Properties對象,它獲取與傳遞的Class對象的名稱相對應的屬性值, 在Spring Boot中,spring.factories是一個非常重要的配置文件,它用于實現(xiàn)Spring Boot的自動化配置。這個文件位于META-INF/spring.factories路徑下,通??梢栽陧椖康腸lasspath下找到。
spring.factories文件的格式如下所示:
# Auto Configuration org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.example.MyAutoConfiguration
這個文件中定義了一個名為org.springframework.boot.autoconfigure.EnableAutoConfiguration的屬性,它的值是一個類的完全限定名,即com.example.MyAutoConfiguration。這個類通常是一個Spring配置類,用于定義一些自動化配置。
Spring Boot在啟動時會掃描classpath中的所有spring.factories文件,并讀取其中定義的屬性。然后,它會根據(jù)這些屬性值加載對應的類,并將它們注冊到Spring的ApplicationContext中。
好吧,如上所示是Spring Boot中spring.factories的底層源碼解析: 整個加載過程我們可以大致分為5步.
你也可以理解為咱們整理的為了方便記憶八股文吧
- Spring Boot通過
SpringFactoriesLoader類來加載spring.factories文件。這個類是Spring框架中的一個工具類,用于加載classpath下的所有spring.factories文件,并將它們的內容存儲在一個Map<String, List<String>>對象中。 - Spring Boot使用
SpringFactoriesLoader.loadFactoryNames方法來加載指定屬性名的所有實現(xiàn)類。這個方法會從步驟1中加載的Map<String, List<String>>對象中獲取對應屬性名的實現(xiàn)類列表。 - Spring Boot使用
SpringFactoriesLoader.loadFactories方法來加載指定屬性名的所有實現(xiàn)類的實例。這個方法會遍歷步驟2中獲取的實現(xiàn)類列表,并使用反射機制實例化每一個類。 - Spring Boot會將步驟3中實例化的類注冊為Spring的Bean。它會調用
AnnotationConfigUtils.registerAnnotationConfigProcessors方法來注冊自動配置類。這個方法會調用BeanDefinitionRegistryPostProcessor接口的實現(xiàn)類的postProcessBeanDefinitionRegistry方法,來注冊自動配置類的BeanDefinition。 - Spring Boot會啟動Spring的ApplicationContext,并讓它自動掃描所有的Bean。它會調用
AnnotationConfigApplicationContext.refresh方法來啟動ApplicationContext,并讓它自動掃描所有的Bean。在掃描過程中,Spring會發(fā)現(xiàn)步驟4中注冊的自動配置類,并嘗試自動配置應用程序。
/**
* SpringFactoriesLoader類是Spring框架中的一個工具類,用于加載classpath下的所有spring.factories文件,
* 并將它們的內容存儲在一個Map<String, List<String>>對象中。
*/
public final class SpringFactoriesLoader {
/**
* 私有構造函數(shù),不允許實例化。
*/
private SpringFactoriesLoader() {
}
/**
* 加載指定屬性名的所有實現(xiàn)類的類名列表。
* @param factoryType 屬性名
* @param classLoader 類加載器
* @return 類名列表
*/
public static List<String> loadFactoryNames(Class<?> factoryType, ClassLoader classLoader) {
// ...
}
/**
* 加載指定屬性名的所有實現(xiàn)類的實例。
* @param factoryType 屬性名
* @param classLoader 類加載器
* @param <T> 實現(xiàn)類的類型
* @return 實現(xiàn)類的實例列表
*/
public static <T> List<T> loadFactories(Class<T> factoryType, ClassLoader classLoader) {
// 省略 ...
}
}
/**
* AnnotationConfigUtils類提供了一些用于處理注解配置的工具方法。
*/
class AnnotationConfigUtils {
/**
* 注冊自動配置類。
* @param registry Bean定義注冊器
*/
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
// ...
}
}
/**
* AnnotationConfigApplicationContext類是Spring的ApplicationContext接口的一個實現(xiàn)類,
* 用于支持基于Java配置的應用程序上下文。
*/
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
/**
* 啟動ApplicationContext,并讓它自動掃描所有的Bean。
*/
@Override
public void refresh() throws BeansException, IllegalStateException {
// ...
}
}
好了,今天的內容就到這兒了,每天寫點東西整理和總結。謝謝大家的閱讀。放棄很容易但堅持一定很酷。一起加油
更多關于springBoot spring.factories擴展的資料請關注腳本之家其它相關文章!
- Spring中的spring.factories文件用法(Spring如何加載第三方Bean)
- springboot自動配置原理以及spring.factories文件的作用詳解
- springboot 加載 META-INF/spring.factories方式
- SpringBoot借助spring.factories文件跨模塊實例化Bean
- 關于SpringBoot3.x中spring.factories功能被移除的解決方案
- SpringBoot?spring.factories加載時機分析
- SpringBoot 自動掃描第三方包及spring.factories失效的問題解決
- SpringBoot3.x中spring.factories?SPI?服務發(fā)現(xiàn)機制的改變問題小結
- SpringBoot之spring.factories的使用方式
- 在SpringBoot3中spring.factories配置不起作用的原因和解決方法
- 淺談spring.factories文件的作用
相關文章
jquery uploadify和apache Fileupload實現(xiàn)異步上傳文件示例
這篇文章主要介紹了jquery uploadify和apache Fileupload實現(xiàn)異步上傳文件示例,需要的朋友可以參考下2014-05-05
Java網(wǎng)絡編程UDP實現(xiàn)多線程在線聊天
這篇文章主要為大家詳細介紹了Java網(wǎng)絡編程UDP實現(xiàn)多線程在線聊天,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-07-07
Spark調優(yōu)多線程并行處理任務實現(xiàn)方式
這篇文章主要介紹了Spark調優(yōu)多線程并行處理任務實現(xiàn)方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-08-08

