zoukankan      html  css  js  c++  java
  • 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自动配置带来的好处。
  • 相关阅读:
    简单的登录模块
    contextmenu
    C#遍历FTP文件夹/下载
    完整的java字符串编码转换代码
    小技巧,把execl.exe转换成dll
    ExcelHelper Excel,Export,Import
    Python 快速统计数据的去重数和去重数据
    Python 库打包分发简易指南
    Python 函数式编程、装饰器以及一些相关概念简介
    Python 二分查找与 bisect 模块
  • 原文地址:https://www.cnblogs.com/yanquhonggui/p/11121740.html
Copyright © 2011-2022 走看看