乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Spring Boot自動配置類

       昵稱53689559 2018-03-20
      前提
      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開始學習
      由于Spring Boot的web Starter集成了Spring MVC,而非其他,所以實際上提供的Web自動配置為Spring MVC的自動配置。
      Spring MVC的自動配置在包 org.springframework.boot.autoconfigure.web 之下,該包中的內(nèi)容如下:

       


      從上圖中可以清楚的看到Spring Boot為Spring MVC提供了哪些自動配置:
      • DispatcherServletAutoConfiguration.class
      • EmbeddedServletContainerAutoConfiguration.class
      • ErrorMvcAutoConfiguration.class
      • GsonHttpMessageConvertersConfiguration.class
      • HttpEncodingAutoConfiguration.class
      • HttpMessageConvertersAutoConfiguration.class
      • JacksonHttpMessageConvertersConfiguration.class
      • MultipartAutoConfiguration.class
      • ServerPropertiesAutoConfiguration.class
      • WebClientAutoConfiguration.class
      • WebMvcAutoConfiguration.class
      另外,還有一類文件: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應用
       4 @Import(BeanPostProcessorsRegistrar.class) // 導入內(nèi)置容器的設置
       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注冊類。
      1. 3個容器類是基于classpath中的class文件來判斷使用哪個容器,默認使用內(nèi)置容器。
      2. 1個bean注冊類則是注冊了一個 BeanPostProcessor bean,用于對容器進行定制。
      下面重點看一下這個bean注冊類的相關。
      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如下:
      1. BeanPostProcessor則是一個工廠鉤子(factory hook),用于對新beans實例進行定制修改,例如檢查它們的標記接口或者使用代理包裝它們。
      2. ApplicationContexts能夠自動探測BeanPostProcessor beans,并將他們應用到后續(xù)創(chuàng)建的任意beans中。
      3. 簡單bean工廠允許代碼化的注冊post-processors,并將注冊的post-processors應用到該工廠創(chuàng)建的所有bean中。
      4. 典型的做法是,通過標記接口裝配beans時,post-processors會實現(xiàn)postProcessBeforeInitialization;而使用代理包裝beans時則會實現(xiàn)postProcessAfterInitialization。
      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級別的。

      這個方法,應該是在Spring加載bean時被Spring調(diào)用。
      org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader

       

      未完待續(xù)。

        本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多