springboot 自動裝配原理概述:
1.當啟動Springboot應用程序時,會先創建 SpringApplication 對象。在對象的構造函數中會進行參數的初始化工作,最主要的是判斷當前應用程序的類型以及讀取初始化器和監聽器。在這個過程中會加載整 個應用程序中的spring.factories文件,將文件的內容放到緩存對象中,方便后續獲取。
2. SpringApplication創建完成后,開始執行run方法,進行整個應該程序的啟動。在啟動過程中,最主要的有兩個方法,prepareContext,refreshContext方法。程序會在這兩個方法中完成自動裝配的核心功 能。具體包括 上下文對象創建,banner打印,異常報告器的準備等邏輯處理,為后續程序完整啟動做準備。
3. 在 prepareContext 方法中,主要完成對上下對象的初始化操作,具體包括屬性值的設置。其中有一個非常重要的方法load。load 主要將當前啟動類作為一個bean,以beanDefinition的配置注冊到 beanFactory 中,為后續調用 BeanFactoryPostProcessor的增強方法做準備。 后續 執行時,發現程序中有@Configuration配置時,會觸發@SrpingBootApplication,@EnableAutoConfiguration 等注解的解析工作。
4. 在 refreshContext 方法中,會進行整個容器的刷新過程。這個方法會間接調用spring中refresh方法,完成整個Spring應用程序的啟動。其中在依次調用 BeanFactoryPostProcessor 實現類的方法時,會使 用到一個主要的實現類 ConfigurationClassPostProcessor 處理類。在調用該類 postProcessBeanDefinitonRegister 方法,緊接著調用 postProcessBeanFactory方法時會進行解析配置相關的注解。主要包 括 @PropertySource, @ComponentScan, @Bean,@Import 等注解,其中最重要的時@Import注解。
5. 在解析@Import注解時,會調用一個 getImports 方法,從主要類開始遞歸解析注解,找到所有@Import注解信息,然后再調用 processImport方法對Import類進行分類處理,此處主要識別 AutoConfigurationImportSelect 歸屬的ImportSelect 子類,后續過程會調用 deferredImportSelectorHandler 中的process 方法,來加載所有的 EnableAutoConfiguration 的配置。
一. SpringApplication 創建:
org.springframework.boot.SpringApplication(Class<?>... primarySources)
org.springframework.boot.SpringApplication#SpringApplication(ResourceLoader, Class<?>...)
1. 設置資源引導(ResourceLoader)。
2. 設置主要資源信息(primarySources)。
3. 推斷Web應用類型(webApplicationType)。默認有三種:java標準的 SERVLET 類型, 反應式 REACTIVE 類型,以及未知的 NONE 類型。
4. 設置初始化程序(ApplicationContextInitializer)對象實例列表 (List<ApplicationContextInitializer<?>>)。即讀取 jar 文件中 META-INF/spring.factories 配置的所有 org.springframework.context.ApplicationContextInitializer 實現。
常用的實現類:
org.springframework.boot.devtools.restart.RestartScopeInitializer org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer org.springframework.boot.context.ContextIdApplicationContextInitializer org.springframework.boot.context.config.DelegatingApplicationContextInitializer org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer
5. 設置監聽器(ApplicationListener)對象實例列表 (List<ApplicationListener<?>>)。即 jar 文件中 META-INF/spring.factories 配置的所有 org.springframework.context.ApplicationListener 實現。
常用的實現類:
org.springframework.boot.devtools.restart.RestartApplicationListener org.springframework.boot.devtools.logger.DevToolsLogFactory.Listener org.springframework.boot.autoconfigure.BackgroundPreinitializer org.springframework.boot.ClearCachesApplicationListener org.springframework.boot.builder.ParentContextCloserApplicationListener org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor org.springframework.boot.context.FileEncodingApplicationListener org.springframework.boot.context.config.AnsiOutputApplicationListener org.springframework.boot.context.config.ConfigFileApplicationListener org.springframework.boot.context.config.DelegatingApplicationListener org.springframework.boot.context.logging.ClasspathLoggingApplicationListener org.springframework.boot.context.logging.LoggingApplicationListener org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener
6. 推斷運行程序的主類類型(mainApplicationClass)。
/** * Create a new {@link SpringApplication} instance. The application context will load * beans from the specified primary sources (see {@link SpringApplication class-level} * documentation for details. The instance can be customized before calling * {@link #run(String...)}. * @param resourceLoader the resource loader to use * @param primarySources the primary bean sources * @see #run(Class, String[]) * @see #setSources(Set) */ @SuppressWarnings({ "unchecked", "rawtypes" }) public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { this.resourceLoader = resourceLoader; Assert.notNull(primarySources, "PrimarySources must not be null"); this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources)); this.webApplicationType = WebApplicationType.deduceFromClasspath(); setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class)); setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); this.mainApplicationClass = deduceMainApplicationClass(); }
二. Springboot 的SPI機制加載類邏輯
org.springframework.boot.SpringApplication#getSpringFactoriesInstances(Class<T> type)
org.springframework.boot.SpringApplication#getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args)
org.springframework.core.io.support.SpringFactoriesLoader#loadFactoryNames(Class<?> factoryType, ClassLoader classLoader)
org.springframework.boot.SpringApplication#createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes,
ClassLoader classLoader, Object[] args, Set<String> names)
1. 獲得當前環境的類加載器。默認是從 Thread.currentThread().getContextClassLoader() 獲取的。
JDK8中為 :sun.misc.Launcher$AppClassLoader。
JDK9及以后版本:jdk.internal.loader.ClassLoaders$AppClassLoader
2. 從 META-INF/spring.factories 配置中尋找 type 實現類的配置列表。如果已加載,則從本地緩存中讀取。
3. 根據傳遞的參數,實例化 type 的實例。
4. 排序 type 實現類列表,并返回。
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) { ClassLoader classLoader = getClassLoader(); // Use names and ensure unique to protect against duplicates Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader)); List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names); AnnotationAwareOrderComparator.sort(instances); return instances; }
三. SpringApplication#run() 分析
org.springframework.boot.SpringApplication#run(java.lang.Class<?>, java.lang.String...)
org.springframework.boot.SpringApplication#run(java.lang.Class<?>[], java.lang.String[])
org.springframework.boot.SpringApplication#run(java.lang.String...)
(一) run 方法概述:
1. 創建 StopWatch 實例,記錄當前開始時間,以及任務名稱等信息。
2. 設置系統屬性 java.awt.headless 值。默認為true。Headless是指服務器的無顯示設備狀態。
3. 獲取程序運行監聽器輔助類(SpringApplicationRunListeners)實例,并觸發 starting() 事件。SpringApplicationRunListeners#starting()
SpringApplicationRunListener 監聽 SpringApplication 類執行run方法觸發的七個事件。這七個事件對應運行時的七個周期節點,開發人員根據需要,可以在相關節點進行擴展。
該接口默認只有一個實現 EventPublishingRunListener 類。創建時注入了 SpringApplication 類,事件廣播類 SimpleApplicationEventMulticaster 實例。最終將SpringApplication 事件監聽器和Spring的事件監聽器關聯上。
4. 創建 請求參數包裝類實例。
5. 預處理環境變量信息。SpringApplication#prepareEnvironment()
6. 設置是否忽略 beanInfo 信息參數。 spring.beaninfo.ignore
7. 打印 Banner 信息。SpringApplication#printBanner() 。創建對象 SpringApplicationBannerPrinter 實例,打印Banner。
8. 根據Web應用類型(webApplicationType) 創建程序上下文實例(ConfigurableApplicationContext)。
SERVLET AnnotationConfigServletWebServerApplicationContext
REACTIVE AnnotationConfigReactiveWebServerApplicationContext
默認類型 AnnotationConfigApplicationContext
當前環境創建 AnnotationConfigServletWebServerApplicationContext 實例,進行spring 邏輯的處理。
9. 獲得 異常報告處理接口(SpringBootExceptionReporter)的所有實現,并創建實例。默認實現類: org.springframework.boot.diagnostics.FailureAnalyzers
10. 預處理 程序上下文。SpringApplication#prepareContext()
11. 刷新 程序上下文。注冊程序停機Hook,并調用Spring 的 AbstractApplicationContext#refresh() 方法,進行Spring 的程序運行環境的創建。
12. 刷新 程序上下文后置處理。留給用戶擴展的方法。
13. 調用 StopWatch 實例stop() 方法,標記任務執行完成,記錄任務結束時間。
14. 執行 started() 方法。SpringApplicationRunListeners#started()
15. 找到注入的所有 ApplicationRunner,CommandLineRunner 實現類,依次調用。默認沒用實現類。
16. 執行 runing() 方法。SpringApplicationRunListeners#running(ConfigurableApplicationContext context)。
17. 如果出現異常,進行異常處理。
SpringApplication#handleRunFailure(ConfigurableApplicationContext context, Throwable exception, Collection<SpringBootExceptionReporter> exceptionReporters, SpringApplicationRunListeners listeners)
(二) 重要步驟詳解
SpringApplicationRunListeners#starting() 事件詳解:
org.springframework.boot.SpringApplicationRunListeners#starting()
org.springframework.boot.context.event.EventPublishingRunListener#starting()
this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));
org.springframework.context.event.SimpleApplicationEventMulticaster#multicastEvent(org.springframework.context.ApplicationEvent)
常見支持 ApplicationStartingEvent 事件的監聽器有如下幾個:
org.springframework.boot.devtools.restart.RestartApplicationListener,
org.springframework.boot.context.logging.LoggingApplicationListener,
org.springframework.boot.autoconfigure.BackgroundPreinitializer,
org.springframework.boot.context.config.DelegatingApplicationListener,
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener
RestartApplicationListener 監聽器, 程序調試時使用的,方便自動重啟服務。經過相關邏輯處理后,設置使用 org.springframework.boot.devtools.restart.RestartLauncher 類實現服務的重新啟動。
org.springframework.boot.devtools.restart.RestartApplicationListener#onApplicationEvent(ApplicationEvent event)
org.springframework.boot.devtools.restart.RestartApplicationListener#onApplicationStartingEvent(ApplicationStartingEvent event)
org.springframework.boot.devtools.restart.Restarter#initialize(java.lang.String[], boolean, org.springframework.boot.devtools.restart.RestartInitializer, boolean)
org.springframework.boot.devtools.restart.Restarter#initialize(boolean)
org.springframework.boot.devtools.restart.Restarter#immediateRestart
LoggingApplicationListener 監聽器,進行日志的初始化處理。當前環境配置的是Logback日志實現。
org.springframework.boot.context.logging.LoggingApplicationListener#onApplicationEvent(ApplicationEvent event)
org.springframework.boot.context.logging.LoggingApplicationListener#onApplicationStartingEvent(ApplicationStartingEvent event)
org.springframework.boot.logging.logback.LogbackLoggingSystem#beforeInitialize()
BackgroundPreinitializer 監聽器,后臺線程早期初始化處理器。 當前事件不觸發邏輯處理。
DelegatingApplicationListener 監聽器, 和 EventPublishingRunListener 類功能類似。當前事件不觸發邏輯處理。
LiquibaseServiceLocatorApplicationListener 監聽器, 當前事件不觸發。LiquiBase是一個用于數據庫重構和遷移的開源工具,通過日志文件的形式記錄數據庫的變更,然后執行日志文件中的修改,將數據庫更新或回滾到一致的狀態。
環境變量預處理 SpringApplication#prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments)
1. 創建環境變量(ConfigurableEnvironment)的實現類。
SERVLET StandardServletEnvironment
REACTIVE StandardReactiveWebEnvironment
default StandardEnvironment
2. 用 程序啟動參數 和 默認環境變量配置處理。
3. 進行環境屬性 configurationProperties 處理。ConfigurationPropertySources.attach(environment)。
4. 執行SpringApplicationRunListeners#environmentPrepared(ConfigurableEnvironment environment)方法,觸發 ApplicationEnvironmentPreparedEvent 事件。
滿足 ApplicationEnvironmentPreparedEvent 事件的監聽器:
org.springframework.boot.devtools.restart.RestartApplicationListener, 未觸發相關邏輯處理。
org.springframework.boot.context.config.ConfigFileApplicationListener, 配置處理邏輯
讀取 EnvironmentPostProcessor 接口實現列表,依次處理屬性配置:
org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor,
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor,
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,
org.springframework.boot.context.config.ConfigFileApplicationListener,
org.springframework.boot.devtools.env.DevToolsHomePropertiesPostProcessor,
org.springframework.boot.devtools.env.DevToolsPropertyDefaultsPostProcessor,
org.springframework.boot.reactor.DebugAgentEnvironmentPostProcessor
org.springframework.boot.context.config.AnsiOutputApplicationListener,
org.springframework.boot.context.logging.LoggingApplicationListener, 日志處理初始化
org.springframework.boot.autoconfigure.BackgroundPreinitializer, 后臺線程早期初始化處理。
org.springframework.boot.context.logging.ClasspathLoggingApplicationListener, 打印ClassPath路徑。
org.springframework.boot.context.config.DelegatingApplicationListener, 委派處理。此處無滿足條件,無處理邏輯。
org.springframework.boot.context.FileEncodingApplicationListener 文件字符配置檢查 spring.mandatory-file-encoding
5. 將環境變量信息綁定到應用程序上。 Binder.get(environment).bind("spring.main", Bindable.ofInstance(this));
6. 重新進行環境屬性 configurationProperties 處理。ConfigurationPropertySources.attach(environment)。
根據Web應用類型(webApplicationType) 創建程序上下文實例(ConfigurableApplicationContext)

AnnotationConfigServletWebServerApplicationContext 實例化分析:
1. 創建BeanFactory 默認實現類 DefaultListableBeanFactory 實例。
2. 創建 AnnotatedBeanDefinitionReader 實例,添加 BeanDefinition 配置處理器。
org.springframework.context.annotation.AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry)
org.springframework.context.annotation.AnnotatedBeanDefinitionReader#AnnotatedBeanDefinitionReader(BeanDefinitionRegistry, Environment)
org.springframework.context.annotation.AnnotatedBeanDefinitionReader#AnnotatedBeanDefinitionReader(BeanDefinitionRegistry, Environment)
org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(BeanDefinitionRegistry)
org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(BeanDefinitionRegistry, Object)
① 如果 BeanFactory 中沒用配置 org.springframework.context.annotation.internalConfigurationAnnotationProcessor 名稱的bean,則使用默認的 ConfigurationClassPostProcessor。
② 如果 BeanFactory 中沒用配置 org.springframework.context.annotation.internalAutowiredAnnotationProcessor 名稱的bean,則使用默認的 AutowiredAnnotationBeanPostProcessor。
② 如果 BeanFactory 中沒用配置 org.springframework.context.annotation.internalCommonAnnotationProcessor 名稱的bean,則使用默認的 CommonAnnotationBeanPostProcessor。
② 如果 BeanFactory 中配置JPA實現,但沒用配置 org.springframework.context.annotation.internalPersistenceAnnotationProcessor 名稱的bean,則使用默認的 PersistenceAnnotationBeanPostProcessor。
② 如果 BeanFactory 中沒用配置 org.springframework.context.event.internalEventListenerProcessor 名稱的bean,則使用默認的 EventListenerMethodProcessor。
② 如果 BeanFactory 中沒用配置 org.springframework.context.event.internalEventListenerFactory 名稱的bean,則使用默認的 DefaultEventListenerFactory。
3. 創建 ClassPathBeanDefinitionScanner 實例,掃描 @Component, @Repository, @Service, @Controller 配置的工具類。
預處理程序上下文(ConfigurableApplicationContext)。SpringApplication#prepareContext()
1. 設置上下文環境(ConfigurableApplicationContext) 的環境變量信息。
2. 處理上下文環境(ConfigurableApplicationContext) 相關信息。默認主要設置 ApplicationConversionService 實例。
3. 遍歷執行 ApplicationContextInitializer 接口實現,進行相關初始化處理。
常用的 ApplicationContextInitializer 接口實現類:
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer
向上下文環境(ConfigurableApplicationContext) 添加(CachingMetadataReaderFactoryPostProcessor) 處理器。
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,
讀取 context.initializer.classes 配置,委派處理自定義的 ApplicationContextInitializer 實現。
org.springframework.boot.context.ContextIdApplicationContextInitializer,
向上下文環境(ConfigurableApplicationContext) 注冊 ContextId 實例。
org.springframework.boot.devtools.restart.RestartScopeInitializer,
向上下文環境(ConfigurableApplicationContext) 注冊 RestartScope 實例。
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener,
添加 ConditionEvaluationReportLoggingListener 監聽器。
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,
向上下文環境(ConfigurableApplicationContext) 添加(ConfigurationWarningsPostProcessor) 處理器。
org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer,
添加 RSocketPortInfoApplicationContextInitializer.Listener 監聽器。
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer
添加 ServerPortInfoApplicationContextInitializer 監聽器。
4. 執行 SpringApplicationRunListeners#contextPrepared() 方法,觸發 ApplicationContextInitializedEvent 事件。
滿足 ApplicationContextInitializedEvent 事件的監聽器:
org.springframework.boot.devtools.restart.RestartApplicationListener, 未滿足執行條件,無處理邏輯。
org.springframework.boot.autoconfigure.BackgroundPreinitializer, 未滿足執行條件,無處理邏輯。
org.springframework.boot.context.config.DelegatingApplicationListener 未滿足執行條件,無處理邏輯。
5. 打印程序啟動日志信息。
6. 設置 beanFactory 信息。注冊 ApplicationArguments 和 Banner 的 bean實例。根據配置添加 LazyInitializationBeanFactoryPostProcessor 處理器。
7. 加載所有 bean 資源配置信息,并轉換成 BeanDefinition 配置對象。
創建 BeanDefinitionLoader 實例,設置 資源對象, 并創建讀取資源的默認實現類, AnnotatedBeanDefinitionReader, XmlBeanDefinitionReader, GroovyBeanDefinitionReader,ClassPathBeanDefinitionScanner。然后根據資源對象的類型,讀取資源里面配置的 BeanDefinition 信息。spring boot 默認是使用 AnnotatedBeanDefinitionReader 實現讀取資源。
8. 執行SpringApplicationRunListeners#contextLoaded() 方法,觸發ApplicationPreparedEvent 事件。
滿足 ApplicationPreparedEvent 事件的監聽器:
org.springframework.boot.devtools.restart.RestartApplicationListener,
執行Restarter#prepare(org.springframework.context.ConfigurableApplicationContext) 方法。
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,
解析 VCAP(又名 Cloud Foundry)元數據。
org.springframework.boot.context.config.ConfigFileApplicationListener,
添加配置文件相關的 PropertySourceOrderingPostProcessor 處理器。
org.springframework.boot.context.logging.LoggingApplicationListener,
注冊日志相關的 LogbackLoggingSystem 和 LoggerGroups 的 bean 實例。
org.springframework.boot.autoconfigure.BackgroundPreinitializer, 未滿足執行條件,無處理邏輯。
org.springframework.boot.context.config.DelegatingApplicationListener, 未滿足執行條件,無處理邏輯。
org.springframework.boot.devtools.logger.DevToolsLogFactory$Listener 日志處理。
執行 started() 方法。SpringApplicationRunListeners#started()
滿足 ApplicationStartedEvent 事件監聽器,
org.springframework.boot.devtools.restart.RestartApplicationListener, 未滿足執行條件,無處理邏輯。
org.springframework.boot.autoconfigure.BackgroundPreinitializer, 未滿足執行條件,無處理邏輯。
org.springframework.boot.context.config.DelegatingApplicationListener 未滿足執行條件,無處理邏輯。
執行 AvailabilityChangeEvent.publish(context, LivenessState.CORRECT) 方法,觸發 AvailabilityChangeEvent 事件:
org.springframework.boot.devtools.restart.RestartApplicationListener, 未滿足執行條件,無處理邏輯。
org.springframework.boot.context.config.DelegatingApplicationListener, 未滿足執行條件,無處理邏輯。
org.springframework.boot.availability.ApplicationAvailabilityBean 記錄 AvailabilityChangeEvent 事件。
執行 runing() 方法。SpringApplicationRunListeners#running(ConfigurableApplicationContext context)
滿足 ApplicationReadyEvent 事件監聽器:
org.springframework.boot.devtools.restart.RestartApplicationListener, 調用 Restarter.getInstance().finish() 方法。
org.springframework.boot.autoconfigure.BackgroundPreinitializer, 檢查后臺線程早期初始化處理器是否完成,如果沒完成則等待。
org.springframework.boot.context.config.DelegatingApplicationListener, 未滿足執行條件,無處理邏輯。
org.springframework.boot.devtools.autoconfigure.ConditionEvaluationDeltaLoggingListener 重啟時相關信息。
執行 AvailabilityChangeEvent.publish(context, ReadinessState.ACCEPTING_TRAFFIC) 方法,觸發 AvailabilityChangeEvent 事件:
org.springframework.boot.devtools.restart.RestartApplicationListener, 未滿足執行條件,無處理邏輯。
org.springframework.boot.context.config.DelegatingApplicationListener, 未滿足執行條件,無處理邏輯。
org.springframework.boot.availability.ApplicationAvailabilityBean 記錄 AvailabilityChangeEvent 事件。
當出現異常,進行異常處理
SpringApplication#handleRunFailure(ConfigurableApplicationContext context,
Throwable exception,
Collection<SpringBootExceptionReporter> exceptionReporters,
SpringApplicationRunListeners listeners)
1. 獲得退出異常的退出碼(exitCode)。如果找到了,則觸發 ExitCodeEvent 事件, 并用 SpringBootExceptionHandler 記錄退出碼信息。
2. 執行 SpringApplicationRunListeners#failed()方法,觸發 ApplicationFailedEvent 事件,進行相關事件處理。
3. SpringBootExceptionHandler 記錄異常類信息。
四. Spring 的 PostProcessor 分析
Spring 調用 BeanFactoryPostProcessor 處理器,進行 bean 配置的處理。
PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors)
SharedMetadataReaderFactoryContextInitializer$CachingMetadataReaderFactoryPostProcessor,
ConfigurationWarningsApplicationContextInitializer$ConfigurationWarningsPostProcessor@7baba5c4,
ConfigFileApplicationListener$PropertySourceOrderingPostProcessor
(一):依次執行BeanFactory的 BeanDefinitionRegistryPostProcessor 處理器 BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)方法。
1. SharedMetadataReaderFactoryContextInitializer$CachingMetadataReaderFactoryPostProcessor 注冊在 ConfigurationClassPostProcessor 和 Spring Boot 之間共享元數據的bean對象SharedMetadataReaderFactoryBean。
2.ConfigurationWarningsApplicationContextInitializer$ConfigurationWarningsPostProcessor 檢查@ComponentScan 配置是否有問題。即是否配置了 org.springframework 和 org 包掃描路徑。
3. ConfigurationClassPostProcessor 處理注冊配置的 BeanDefinition 信息。spring中所有注解配置,都是通過這個類來實現的。
org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions(BeanDefinitionRegistry registry)
① 獲取當前 BeanDefinitionRegistry 上加載的所有 BeanDefinition 配置。
② 循環處理加載的 BeanDefinition 配置。如果滿足指定條件,則將其添加到 待處理配置bean列表中(configCandidates)。
如果 BeanDefinition 實例以及被 ConfigurationClassPostProcessor 類處理,則不進行后續處理。
如果沒有經過處理,則判斷 BeanDefinition 配置的類是否使用 @Configuration 修飾。或者是否使用 @Component, @ComponentScan, @Import, @ImportResource 修飾,或者方法是否使 用 @Bean 修飾。
③ 根據當前環境,創建 ConfigurationClassParser 實例。
ConfigurationClassParser(MetadataReaderFactory metadataReaderFactory,
ProblemReporter problemReporter, Environment environment,
ResourceLoader resourceLoader,
BeanNameGenerator componentScanBeanNameGenerator,
BeanDefinitionRegistry registry)
④ 使用 ConfigurationClassParser 工具類實例,循環處理 @Configuration 修飾的類BeanDefinition 配置。
a. 依次解析 @Component, @PropertySource,@ComponentScan,@ComponentScans,@Import,@ImportResource,@Bean 注解的配置,
或實現 ImportBeanDefinitionRegistrar 接口的配置。
b. 校驗 解析的配置。
c. 創建讀取 Bean配置的 ConfigurationClassBeanDefinitionReader 實例reader。
d. 使用reader讀取 ConfigurationClass 配置的 BeanDefinition 信息。
e. 重新獲取 BeanDefinitionRegistry 上加載的所有 BeanDefinition 配置,去掉已經解析過的 @Configuration 配置。
f. 檢查是否還有 待處理配置 bean 。如果有則循環 a 至 e 步驟。
(二):依次執行BeanFactory的 BeanFactoryPostProcessor 處理器 BeanFactoryPostProcessor#postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) 方法
SharedMetadataReaderFactoryContextInitializer$CachingMetadataReaderFactoryPostProcessor, 無處理邏輯
ConfigurationWarningsApplicationContextInitializer$ConfigurationWarningsPostProcessor, 無處理邏輯
ConfigurationClassPostProcessor 處理配置類。如果配置類 中屬性 ConfigurationClassPostProcessor.configurationClass = "full"(即@Configuration(proxyBeanMethods=true)),則將beanClass設置為cglib代理的類。ConfigurationClassEnhancer#enhance(Class<?> configClass, @Nullable ClassLoader classLoader)
ConfigFileApplicationListener$PropertySourceOrderingPostProcessor 無滿足條件,無處理邏輯
PropertySourcesPlaceholderConfigurer 解析 ${...} 配置
PropertySourcesPlaceholderConfigurer#postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
PropertySourcesPlaceholderConfigurer#processProperties(ConfigurableListableBeanFactory, ConfigurablePropertyResolver)
PlaceholderConfigurerSupport#doProcessProperties(ConfigurableListableBeanFactory, StringValueResolver)
1. 創建 BeanDefinitionVisitor 實例visitor。
2. 依次取出所有 BeanDefinition 配置,使用 visitor 實例解析 BeanDefinition 配置的屬性。即將 ${...} 配置替換成實際的值。
3. 依次取出所有 別名 配置,使用 valueResolver 實例解析 alias, registeredName 值。即將 ${...} 配置替換成實際的值。
4. 將 valueResolver 解析器添加到 beanFactory 上。
EventListenerMethodProcessor, 將EventListenerFactory類型bean 取出,添加到 eventListenerFactories 屬性上。處理將 @EventListener 修飾的類包裝成ApplicationListener 。
ErrorMvcAutoConfiguration$PreserveErrorControllerTargetClassPostProcessor 確保在使用 AOP 時保留 ErrorController MVC bean 的目標類。
(三):在創建bean 對象實例時,再通過 BeanPostProcessor 進行bean對象實例的增強處理。在創建 bean 實例時,有六個位置調用BeanPostProcessor 實現進行bean增強處理。
1. 開始創建 bean 實例之前,嘗試 快捷方式創建 bean 實例。如果創建成功,則創建邏輯不再執行。
AbstractAutowireCapableBeanFactory#createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd)
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName)
InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
BeanPostProcessor#postProcessAfterInitialization(Object bean, String beanName)
ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor 無處理邏輯
CommonAnnotationBeanPostProcessor 無處理邏輯
AutowiredAnnotationBeanPostProcessor 無處理邏輯
ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor 無處理邏輯
2. 創建 bean 實例后,檢查 BeanDefinition 配置是否需要合并。
AbstractAutowireCapableBeanFactory#createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
AbstractAutowireCapableBeanFactory#doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName)
MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName)
ApplicationListenerDetector, 檢查配置的 beanDefinition 是否是 ApplicationListener 類型。如果是,則添加到成員字段上。
CommonAnnotationBeanPostProcessor 檢查 beanType 的字段和方法是否使用 @PostConstruct 和 @PreDestroy標識,如果是,則包裝成 LifecycleMetadata 實例,為后續處理進行準備。
檢查 beanType 的字段和方法是否使用 @WebServiceRef, @EJB 和 @Resource標識,如果是,則包裝成 WebServiceRefElement, EjbRefElement, ResourceElement 實例,添加到 AutowiredAnnotationBeanPostProcessor#injectionMetadataCache 中為后續依賴注入處理進行準備。
AutowiredAnnotationBeanPostProcessor 檢查 beanType 的字段和方法是否使用 @Autowired 和 @Value 標識。如果是,則將解析后包裝成 AutowiredFieldElement, AutowiredMethodElement 添加到
AutowiredAnnotationBeanPostProcessor#injectionMetadataCache 中。進行依賴注入管理。
3. 在填充 bean 屬性之前,進行 bean 實例后處理。
AbstractAutowireCapableBeanFactory#createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
AbstractAutowireCapableBeanFactory#doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
AbstractAutowireCapableBeanFactory#populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)
InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation(Object bean, String beanName)
默認無滿足條件的 InstantiationAwareBeanPostProcessor。
CommonAnnotationBeanPostProcessor 無處理
AutowiredAnnotationBeanPostProcessor 無處理
4. 使用 InstantiationAwareBeanPostProcessor 處理器,進行bean 屬性的處理
AbstractAutowireCapableBeanFactory#createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
AbstractAutowireCapableBeanFactory#doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
AbstractAutowireCapableBeanFactory#populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)
InstantiationAwareBeanPostProcessor#postProcessProperties(PropertyValues pvs, Object bean, String beanName)
默認無滿足條件的 InstantiationAwareBeanPostProcessor。
CommonAnnotationBeanPostProcessor 注入 @WebServiceRef, @EJB 和 @Resource 修飾的字段和方法。
AutowiredAnnotationBeanPostProcessor 注入 @Autowired 和 @Value 修飾的字段或方法。
5. 在初始化 bean 實例時,進行增強處理
AbstractAutowireCapableBeanFactory#createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
AbstractAutowireCapableBeanFactory#doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
AbstractAutowireCapableBeanFactory#initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
BeanPostProcessor#postProcessBeforeInitialization(Object bean, String beanName)
ApplicationContextAwareProcessor 檢查 bean 實例是否是Aware 系列接口的實現。當滿足條件時,設置相應的環境屬性。
ApplicationListenerDetector 無處理。
WebApplicationContextServletContextAwareProcessor 判斷是否是 ServletContextAware 和 ServletConfigAware 接口實現。是則進行相關屬性設置。
ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor 判斷是否是 ImportAware 的實例,如果是則設置 AnnotationMetadata 屬性。
PostProcessorRegistrationDelegate$BeanPostProcessorChecker 無處理邏輯
ConfigurationPropertiesBindingPostProcessor 檢查 bean 是由 @ConfigurationProperties 注解修飾。如果是,則使用 ConfigurationPropertiesBinder#bind(ConfigurationPropertiesBean) 處理。
CommonAnnotationBeanPostProcessor 獲取當前 bean 的 LifecycleMetadata 實例,回調 @PostConstruct 標記的方法。
AutowiredAnnotationBeanPostProcessor 無處理。
ErrorPageRegistrarBeanPostProcessor 當bean 是否是 ErrorPageRegistry 實現類時,則進行依次調用 ErrorPageRegistrar#registerErrorPages() 接口。
6. 在完成初始化 bean 實例后,進行增強處理
AbstractAutowireCapableBeanFactory#createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
AbstractAutowireCapableBeanFactory#doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
AbstractAutowireCapableBeanFactory#initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
BeanPostProcessor#postProcessAfterInitialization(Object bean, String beanName)
ApplicationContextAwareProcessor 無處理。
ApplicationListenerDetector 判斷是否是 ApplicationListener 的實例,并且是單例模式。如果是,則添加到 監聽器(ApplicationListener)列表中。
WebApplicationContextServletContextAwareProcessor 無處理
PostProcessorRegistrationDelegate$BeanPostProcessorChecker 檢查 BeanPostProcessor 數量。
ConfigurationPropertiesBindingPostProcessor 無處理
CommonAnnotationBeanPostProcessor 無處理
AutowiredAnnotationBeanPostProcessor 無處理
MethodValidationPostProcessor 檢查當前 bean 是否動態代理相關的邏輯。1.當是實現 Advised 接口,則直接返回。2.檢查是否配置了AOP增強處理(例如:@Validated ),則生成bean 的動態代理實例。
AsyncAnnotationBeanPostProcessor
WebServerFactoryCustomizerBeanPostProcessor 無處理
ApplicationContextAwareProcessor,
WebApplicationContextServletContextAwareProcessor,
ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor,
PostProcessorRegistrationDelegate$BeanPostProcessorChecker,
ConfigurationPropertiesBindingPostProcessor(proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false)
WebServerFactoryCustomizerBeanPostProcessor,
ErrorPageRegistrarBeanPostProcessor,
CommonAnnotationBeanPostProcessor,
AutowiredAnnotationBeanPostProcessor,
ApplicationListenerDetector
MethodValidationPostProcessor
五. Springboot 讀取加載 自動裝置配置信息
主要在啟動時,讀取所有jar文件中META-INF/spring.factories配置的 org.springframework.boot.autoconfigure.EnableAutoConfiguration 裝載類
org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions(ConfigurableListableBeanFactory beanFactory)
org.springframework.context.annotation.ConfigurationClassParser#parse(Set<BeanDefinitionHolder>)
org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorHandler#process()
org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorGroupingHandler#processGroupImports()
org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorGrouping#getImports()
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.AutoConfigurationGroup#process()
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getAutoConfigurationEntry(AnnotationMetadata annotationMetadata)
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes)
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getSpringFactoriesLoaderFactoryClass()
如果覺得這篇文章對你有小小的幫助的話,記得在右下角點個“推薦”哦,博主在此感謝!
浙公網安備 33010602011771號