前提 1、一般來說,xxxAware接口,都提供了一個setXxx的方法,以便于其實現(xiàn)類將Xxx注入自身的xxx字段中,從而進行操作。 例如 ApplicationContextAware ,就提供了 void setApplicationContext(ApplicationContext applicationContext) throws BeansException; ,從而讓其實現(xiàn)可以直接操作 applicationContext 。 2、Spring中的 BeanFactory,這是訪問bean container 的root interface。其實現(xiàn)類的對象通常擁有一系列 bean 定義,并以不同的String 名字來區(qū)分。 但是,官方文檔不建議直接使用這種方式獲取bean,而是建議使用注入的方式獲取bean(@Autowire)。--這個,前期不能使用初始化注入吧? 正文 Spring Boot提供的自動配置都是位于包 org.springframework.boot.autoconfigure 之下。 注意, ① 這里是Spring Boot提供的,而非第三方(如MyBatis-Spring-Boot-Starter)提供的。 ② 不包含Spring Boot Actuator部分的。 Spring Boot的自動配置類可以通過autoconfig report查看,需要開啟 --debug 或 -Debug?;蛘咴?Actuator 項目的autoconfig 端點查看。 這里先從Web開始學(xué)習(xí) 由于Spring Boot的web Starter集成了Spring MVC,而非其他,所以實際上提供的Web自動配置為Spring MVC的自動配置。 Spring MVC的自動配置在包 org.springframework.boot.autoconfigure.web 之下,該包中的內(nèi)容如下: ![]()
從上圖中可以清楚的看到Spring Boot為Spring MVC提供了哪些自動配置:
另外,還有一類文件:xxxProperties.class。這些文件都是 @ConfigurationProperties classes 。 在 @Configuration classes上可以使用 @EnableConfigurationProperties 進行 @ConfigurationProperties classes 的注入。 -- 也可以在@Configuration classes內(nèi)部使用@Bean,略麻煩。 接下來,我們有針對性的來捋一遍。 先看一下這些類的聲明 ![]() 1 @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) 2 @Configuration 3 @ConditionalOnWebApplication 4 @ConditionalOnClass(DispatcherServlet.class) 5 @AutoConfigureAfter(EmbeddedServletContainerAutoConfiguration.class) 6 public class DispatcherServletAutoConfiguration { ... } 7 8 @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) 9 @Configuration 10 @ConditionalOnWebApplication 11 @Import(BeanPostProcessorsRegistrar.class) 12 public class EmbeddedServletContainerAutoConfiguration { ... } 13 14 @Configuration 15 @ConditionalOnClass(Gson.class) 16 class GsonHttpMessageConvertersConfiguration { ... } 17 18 @Configuration 19 @EnableConfigurationProperties(HttpEncodingProperties.class) 20 @ConditionalOnWebApplication 21 @ConditionalOnClass(CharacterEncodingFilter.class) 22 @ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true) 23 public class HttpEncodingAutoConfiguration { ... } 24 25 @Configuration 26 @ConditionalOnClass(HttpMessageConverter.class) 27 @AutoConfigureAfter({ GsonAutoConfiguration.class, JacksonAutoConfiguration.class }) 28 @Import({ JacksonHttpMessageConvertersConfiguration.class, GsonHttpMessageConvertersConfiguration.class }) 29 public class HttpMessageConvertersAutoConfiguration { ... } 30 31 @Configuration 32 class JacksonHttpMessageConvertersConfiguration{ ... } 33 34 @Configuration 35 @ConditionalOnClass({ Servlet.class, StandardServletMultipartResolver.class, MultipartConfigElement.class }) 36 @ConditionalOnProperty(prefix = "spring.http.multipart", name = "enabled", matchIfMissing = true) 37 @EnableConfigurationProperties(MultipartProperties.class) 38 public class MultipartAutoConfiguration { ... } 39 40 @Configuration 41 @EnableConfigurationProperties 42 @ConditionalOnWebApplication 43 public class ServerPropertiesAutoConfiguration { ... } 44 45 @Configuration 46 @AutoConfigureAfter(HttpMessageConvertersAutoConfiguration.class) 47 public class WebClientAutoConfiguration { ... } 48 49 @Configuration 50 @ConditionalOnWebApplication 51 @ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurerAdapter.class }) 52 @ConditionalOnMissingBean(WebMvcConfigurationSupport.class) 53 @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10) 54 @AutoConfigureAfter(DispatcherServletAutoConfiguration.class) 55 public class WebMvcAutoConfiguration { ... } 整理一下優(yōu)先級: 最高級 EmbeddedServletContainerAutoConfiguration DispatcherServletAutoConfiguration 次高級 WebMvcAutoConfiguration 無級別 HttpEncodingAutoConfiguration MultipartAutoConfiguration ServerPropertiesAutoConfiguration 依賴鏈(屬于無級別) GsonHttpMessageConvertersConfiguration JacksonHttpMessageConvertersConfiguration HttpMessageConvertersAutoConfiguration WebClientAutoConfiguration 一、先看一下 EmbeddedServletContainerAutoConfiguration,這是內(nèi)置Servlet容器的自動配置 -- 默認就是那個 pivotal-tc-server (定制版tomcat,商業(yè)的)。 該類的聲明如下: 1 @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) // 自動配置里面的最高優(yōu)先級 2 @Configuration 3 @ConditionalOnWebApplication // 僅限于web應(yīng)用 4 @Import(BeanPostProcessorsRegistrar.class) // 導(dǎo)入內(nèi)置容器的設(shè)置 5 public class EmbeddedServletContainerAutoConfiguration { 6 @Configuration 7 @ConditionalOnClass({ Servlet.class, Tomcat.class }) 8 @ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT) 9 public static class EmbeddedTomcat { 10 // ... 11 } 12 13 @Configuration 14 @ConditionalOnClass({ Servlet.class, Server.class, Loader.class, WebAppContext.class }) 15 @ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT) 16 public static class EmbeddedJetty { 17 // ... 18 } 19 20 @Configuration 21 @ConditionalOnClass({ Servlet.class, Undertow.class, SslClientAuthMode.class }) 22 @ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT) 23 public static class EmbeddedUndertow { 24 // ... 25 } 26 27 public static class BeanPostProcessorsRegistrar implements ImportBeanDefinitionRegistrar, BeanFactoryAware { 28 // ... 29 } 30 } @ConditionalOnWebApplication 是基于application context 是否 web application context 進行判斷。 @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) ,這里的 Ordered.HIGHEST_PRECEDENCE 其實是int類型的最小值,代表最高的優(yōu)先級。 @Import(BeanPostProcessorsRegistrar.class) ,這里 BeanPostProcessorsRegistrar 中進行的操作是注冊了一個bean, EmbeddedServletContainerCustomizerBeanPostProcessor 。是通過 ImportBeanDefinitionRegistrar 進行早期注冊。 這個配置類,內(nèi)部共有4個靜態(tài)內(nèi)部類:3個容器類(tomcat、jetty、undertow)、1個bean注冊類。
下面重點看一下這個bean注冊類的相關(guān)。 1、EmbeddedServletContainerCustomizerBeanPostProcessor public class EmbeddedServletContainerCustomizerBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware { // ... } 2、BeanPostProcessor接口,該接口內(nèi)容如下: ![]() 1 public interface BeanPostProcessor { 2 Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; 3 Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException; 4 } 根據(jù)方法的名字可以知道這是對在bean初始化之前、之后進行操作的方法。 該接口的Javadoc如下:
EmbeddedServletContainerCustomizerBeanPostProcessor 中提供了 postProcessBeforeInitialization 的實現(xiàn)(對bean有更多的操作,而非直接返回bean),對內(nèi)置容器進行了定制操作。(插一句,這里的定制操作是通過applicationContext 中 EmbeddedServletContainerCustomizer beans進行的,所以需要先獲取applicationContext(ApplicationContextAware的功勞),再從applicationContext中獲取EmbeddedServletContainerCustomizer beans) 3、回過頭來再看一下BeanPostProcessorsRegistrar ![]() 1 public static class BeanPostProcessorsRegistrar implements ImportBeanDefinitionRegistrar, BeanFactoryAware { 2 // ... 3 } 這是個靜態(tài)內(nèi)部類,實現(xiàn)了兩個接口。 4、接口ImportBeanDefinitionRegistrar public interface ImportBeanDefinitionRegistrar { public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry); } 該接口用于在系統(tǒng)處理@Configuration class時注冊更多的bean。是bean定義級別的操作,而非@Bean method/instance級別的。 這個方法,應(yīng)該是在Spring加載bean時被Spring調(diào)用。 org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader
未完待續(xù)。 |
|
來自: 昵稱53689559 > 《文件夾1》