Spring Boot自動配置


Spring Boot自動配置

原文鏈接:https://www.jianshu.com/p/a827ecdda99f
https://www.bysocket.com/technique/2001.html

一、SpringBoot為我們做了那些配置

  • 自動配置類都存放在spring-boot-autoconfigure-版本號.jar下的org.springframework.boot.autoconfigure中
  • 當我們在application.properties中配置debug=true后啟動容器。可以看到服務器初始化的初始化配置
    • DispatcherServletAutoConfigratio 注冊前端控制器
    • EmbeddedServletContainerAutoConfiguration注冊容器類型
    • HttpMessageConvertersAutoConfiguration注冊json或者xml處理器
    • JacksonAutoConfiguration注冊json對象解析器
  • 如果加入其他功能的依賴,springBoot還會實現這些功能的自動配置

二、自動配置原理

1. 外化配置和自動配置

Spring boot 配置,包括自動配置和外化配置

可以鍵屬性外化配置在application.properties應用配置文件,然后在工程中獲取該屬性。

對於自動配置,spring-boot-autoconfigure依賴做了很多默認的配置項,即應用默認值。spring boot 自動配置會根據添加的依賴,自動加載依賴相關的配置屬性並啟動依賴。自動配置的意義是利用這種模式代替了配置XML煩瑣模式。以前使用spring MVC ,需要進行組件掃描,調度器,視圖解析器等。使用sping boot自動配置后,只需要添加MVC組件即可自動配置所需要的Bean.所有的配置實現都在spring-boot-autoconfigure依賴中。

外化配置指的不是把配置內容分離到propertires文件里、而是配置存儲在classpath之外

自動化配置本身包含了兩塊內容:@Configration的定義和properties屬性的定義。外部化配置是跟加載過程相關的。

2.自動配置原理淺析

spring-boot-autoconfigure依賴

spring-boot-autoconfigure依賴的工作原理。通過@EnableAutoConfiguration核心注解初始化。並掃描classPath目錄中自動配置類對應依賴。比如工程中有沒有添加Thymeleaf的Starter組件依賴。如果有,就按照一定規則獲取默認配置並自動初始化所需要的Bean.

@EnableAutoConfiguration注解

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.boot.autoconfigure;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({EnableAutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

    Class<?>[] exclude() default {};

    String[] excludeName() default {};
}

@EnableAutoConfiguration 注解核心點是@Impot的自動配置選擇器類AutoConfigurationImportSelector。核心代碼為

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
	List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.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;
}
  1. AutoConfigurationImportSelector通過springFactoriesLoader.loadFactoryName()核心方法讀取ClassPath目錄下面META-INF/spring.factories文件。

  2. spring.factories文件中配置的SpringBoot自動配置類,例如常見的Jpa自動配置類JpaRepostioriesAutoConfiguration、WebMvcAutoConfiguration WebMVC自動配置類和ServletWebServerFactoryAutoConfiguration容器自動配置類等。

  3. spring.factories文件和application.properties文件都屬於配置文件,配置的格式均為鍵值對。里面配置的每個自動配置類都會定義相關Bean的實例配置,也會定義什么條件下自動配置和那些Bean被實例化。

    spring.factories內容

    # Auto Configure
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
    org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
    org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
    org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
    org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
    org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
    org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\
    org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
    
    
  4. 當pom.xml添加某Starter依賴組件的時候,就會自動觸發該依賴的默認配置。

    具體Starter組件依賴是如何觸發它的默認配置的呢

3. Starter組件淺析

Starter組件

spring boot提供了很多”開箱即用“的Starter組件。Starter組件是可被加載在應用中的Maven依賴項項。只有在Maven配置中添加對應的依賴配置,即可使用對應的Starter組件。例如,添加spring-boot-starter-web依賴,就可以用於構建REST API服務,其包含了SpringMVC和Tomcat內嵌容器。

一個完整的Starter組件包括以下兩點:

  • 提供自動配置功能的自動配置模塊
  • 提供依賴關系管理崗功能的組件模塊,即封裝了組件所有功能,開箱即用。

spring-boot-starter-web依賴源碼

當我們添加spring-boot-starter-web依賴,並啟動應用會觸發容器自動配置類。容器自動配置類ServletWebServerFactoryAutoConfiguration的部分代碼如下:

package org.springframework.boot.autoconfigure.web.servlet;

@Configuration
@ConditionalOnClass({ServletRequest.class})
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
@EnableConfigurationProperties({ServerProperties.class})
@Import({ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class})
public class ServletWebServerFactoryAutoConfiguration {
	......
}
  • @ConditionalOnClass 注解表示對應的 ServletRequest 類在 ClassPath 目錄下面存在,並且 @ConditionalOnWebApplication 注解表示該應用是 Servlet Web 應用時,才會去啟動容器默認配置
  • 通過 ServerProperties 類默認設置了端口為 8080
  • Type.SERVLET 枚舉代表 Servlet Web 應用,Type.REACTIVE 枚舉代表響應式 WebFlux 應用。

三、SpringBoot的自動配置

@SpringBootApplication這個注解,因為其包含@EnableAutoConfiguration和@ComponentScan注解,可以自動掃描相關的自動配置類,從而實現自動配置功能的。

SpringBoot默認會初始化很多的自動配置,這些配置有些我們項目中可能用不到。

1.去掉不需要的自動配置類

比如我們不需要開啟webSocket和JMX的自動配置,我們需要在@SpringBootApplication這個注解中指定exclude屬性

@SpringBootApplication(exclude={webSocketAutoConfiguration.class,JmxAutonConfiguration})
public class SpringBootWebDemoApplication{
    public static void main(String[] args){
        SpringApplication.run(SpringBootWebDemoApplication,args);
    }
}

2.明確指定需要啟用那些自動配置

去掉@SpringBootApplication注解,改用@Configuraion,@Import、@CommponentScan注解

在@Import注解中明確指定需要啟用那些自動配置

//@SpringBootApplication(exclude={webSocketAutoConfiguration.class,JmxAutonConfiguration})

@Configuration
@ComponentScan
@Import({
        DispatcherServletAutoConfiguration.class,
        EmbeddedServletContainerAutoConfiguration.class,
        ErrorMvcAutoConfiguration.class,
        HttpEncodingAutoConfiguration.class,
        HttpMessageConvertersAutoConfiguration.class,
        JacksonAutoConfiguration.class,
        MultipartAutoConfiguration.class,
        ServerPropertiesAutoConfiguration.class,
        WebMvcAutoConfiguration.class
})
public class SpringBootWebDemoApplication{
    public static void main(String[] args){
        SpringApplication.run(SpringBootWebDemoApplication,args);
    }
}

3.其他

  • 這里推薦使用第一種方式:@SpringBootApplication(exclude={})
  • 實際上,開啟默認的自動配置功能,只是會影響項目啟動時間,所以沒有特殊需要,可以不需要關閉某個自動配置功能;
  • 在某些情況,比如項目需要多數據源時,在項目中就會包含多個DataSource的Bean,因為DataSourceAutoConfiguration自動配置只能綁定一個數據源,此時發現多個DataSource的Bean被Spring注冊就會拋出異常。
    • 這時就可以采用去掉DataSourceAutoConfiguration的方式;
    • 或者也可以在某一個DataSource的Bean上聲明@Primary注解,指定其為主數據源,這時DataSourceAutoConfiguration只會加載被指定@Primary注解的主數據源,這樣就可以享受到SpringBoot自動配置帶來的好處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM