<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [TOC] # @SpringBootApplication 跟著 Spring Boot 的啟動類的注解`@SpringBootApplication`進行源碼跟蹤,尋找自動配置的原理。 ~~~ @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan( excludeFilters = {@Filter( type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class} ), @Filter( type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class} )} ) public @interface SpringBootApplication { ~~~ `@EnableAutoConfiguration`開啟自動配置。 `@ComponentScan`開啟注解掃描 從`SpringBootApplication`我們可以發現,這是一個簡便的注解配置,它包含了自動配置,配置類,包掃描等一系列功能。 # @EnableAutoConfiguration 繼續跟蹤,查看`@EnableAutoConfiguration`源碼,里面比較重要的是`@Import`,導入了一個翻譯名為自動配置的選擇器的類。這個類其實就是自動配置的加載選擇器。 ~~~ @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import({AutoConfigurationImportSelector.class}) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class<?>[] exclude() default {}; String[] excludeName() default {}; } ~~~ 繼續跟蹤 `AutoConfigurationImportSelector.class` .在這個類有一個重要的方法 `getCandidateConfigurations`.用于加載 Spring Boot 配置的自動配置類。 `getAutoConfigurationEntry` 會篩選出有效的自動配置類。 ~~~ protected AutoConfigurationEntry getAutoConfigurationEntry( AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { return EMPTY_ENTRY; } AnnotationAttributes attributes = getAttributes(annotationMetadata); List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); configurations = removeDuplicates(configurations); Set<String> exclusions = getExclusions(annotationMetadata, attributes); checkExcludedClasses(configurations, exclusions); configurations.removeAll(exclusions); configurations = filter(configurations, autoConfigurationMetadata); fireAutoConfigurationImportEvents(configurations, exclusions); return new AutoConfigurationEntry(configurations, exclusions); } protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List<String> configurations = SpringFactoriesLoader.loadFactoryNames( getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()); Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you " + "are using a custom packaging, make sure that file is correct."); return configurations; } ~~~ 下圖是 DEBUG 模式下篩選之后的結果,因為我只添加了 web 模塊,所以只有 web 相關的自動配置。 ![](https://img.kancloud.cn/92/c4/92c4e869e1a171c6355971171474cc6e_449x181.png) # xxxAutoConfiguration 與 xxxProperties 在上面的 debug 里,我們看到了成功加載的自動配置,目前只看到了配置類,卻還沒有發現自動配置值,隨便選擇一個 `AutoConfiguration` 查看源碼。 這里選擇了 `ServletWebServerFactoryAutoConfiguration`. ~~~ @Configuration @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) //判斷當前項目有沒有這個類 //CharacterEncodingFilter;SpringMVC中進行亂碼解決的過濾器; @ConditionalOnClass(ServletRequest.class) //Spring底層@Conditional注解(Spring注解版),根據不同的條件,如果 //滿足指定的條件,整個配置類里面的配置就會生效; 判斷當前應用是否是web應用,如果是,當前配置類生效 @ConditionalOnWebApplication(type = Type.SERVLET) @EnableConfigurationProperties(ServerProperties.class) @Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, ServletWebServerFactoryConfiguration.EmbeddedTomcat.class, ServletWebServerFactoryConfiguration.EmbeddedJetty.class, ServletWebServerFactoryConfiguration.EmbeddedUndertow.class }) public class ServletWebServerFactoryAutoConfiguration { ~~~ 需要注意的是 `@EnableConfigurationProperties(ServerProperties.class)`.他的意思是啟動指定類的 `ConfigurationProperties`功能;將配置文件中對應的值和 `ServerProperties` 綁定起來;并把 `ServerProperties` 加入到 IOC 容器中。 再來看一下 `ServerProperties` . ~~~ @ConfigurationProperties(prefix = "server", ignoreUnknownFields = true) public class ServerProperties { /** * Server HTTP port. */ private Integer port; ~~~ 顯而易見了,這里使用 ConfigurationProperties 綁定屬性映射文件中的 server 開頭的屬性。結合默認配置 ~~~ # 路徑spring-boot-autoconfigure-2.1.1.RELEASE.jar # /META-INF/spring-configuration-metadata.json { "name": "server.port", "type": "java.lang.Integer", "description": "Server HTTP port.", "sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties", "defaultValue": 8080 } ~~~ 達到了自動配置的目的 # 自動配置總結 1. SpringBoot 啟動的時候加載主配置類,開啟了自動配置功能 @EnableAutoConfiguration 。 2. @EnableAutoConfiguration 給容器導入`META-INF/spring.factories` 里定義的自動配置類。 3. 篩選有效的自動配置類。 4. 每一個自動配置類結合對應的 `xxxProperties.java` 讀取配置文件進行自動配置功能 。 # 配置類 通過自動配置,我們發現已經幫我們省去了大量的配置文件的編寫,那么在自定義配置的時候,我們是不是需要編寫XML呢?Spring boot 盡管可以使用 `SpringApplication`XML 文件進行配置,但是我們通常會使用 `@Configuration` 類進行代替,這也是官方推薦的方式。 ## XML配置 定義 helloService Bean. ~~~ <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="helloService" class="net.codingme.boot.service.HelloService"></bean> </beans> ~~~ 引入配置 ~~~ @ImportResource(value = "classpath:spring-service.xml") @SpringBootApplication public class BootApplication { public static void main(String[] args) { SpringApplication.run(BootApplication.class, args); } } ~~~ ## 注解配置 此種方式和上面的XML配置是等效的,也是官方推薦的方式。`@Configuration`注解的類(要在掃描的包路徑中)會被掃描到。 ~~~ /** * <p> * 配置類,相當于傳統Spring 開發中的 xml-> bean的配置 */ @Configuration public class ServiceConfig { /** * 默認添加到容器中的 ID 為方法名(helloService) * * @return */ @Bean public HelloService helloService() { return new HelloService(); } } ~~~ # `@Conditional`擴展注解 | @Conditional擴展注解 | 作用(判斷是否滿足當前指定條件) | | --- | --- | | @ConditionalOnJava | 系統的java版本是否符合要求 | | @ConditionalOnBean | 容器中存在指定Bean; | | @ConditionalOnMissingBean | 容器中不存在指定Bean; | | @ConditionalOnExpression | 滿足SpEL表達式指定 | | @ConditionalOnClass | 系統中有指定的類 | | @ConditionalOnMissingClass | 系統中沒有指定的類 | | @ConditionalOnSingleCandidate | 容器中只有一個指定的Bean,或者這個Bean是首選Bean | | @ConditionalOnProperty | 系統中指定的屬性是否有指定的值 | | @ConditionalOnResource | 類路徑下是否存在指定資源文件 | | @ConditionalOnWebApplication | 當前是web環境 | | @ConditionalOnNotWebApplication | 當前不是web環境 | | @ConditionalOnJndi | JNDI存在指定項 |
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看