Spring Boot⾃动配置

一、Spring Boot的自动配置原理

Spring Boot使用一种称为"约定优于配置"的方法,这意味着如果你按照预定的方式来安排你的代码和依赖项,Spring Boot可以自动配置你的应用程序。主要特点包括:

  • 自动检测:Spring Boot在应用启动时会自动检测添加到项目中的jar依赖,并基于这些依赖尝试推断需要配置哪些Bean。例如,如果Spring Boot检测到classpath中包含Spring Web MVC(通过spring-webmvc jar),它会自动配置你的应用程序为一个web应用,注册必要的Controller、ViewResolver等Bean。
  • 自动配置:Spring Boot提供了大量的自动配置,这些配置尝试根据classpath下的库自动设置Spring应用。这包括内嵌服务器的配置、数据源、事务管理等。用户可以通过添加自定义属性来覆盖这些自动配置的默认设置

二、Spring Boot自动配置原理源码

SpringBoot的自动配置原理源码口是@SpringBootApplication注解,这个注解封装了3个注解

1.@SpringBootConfiguration
  • 描述 :这是一个特化的@Configuration注解,它标记了一个类作为Spring Boot应用的配置类。@Configuration注解本身表明这个类可以使用Spring IoC容器作为bean定义的来源。
2. @ComponentScan
  • 作用 :这个注解告诉Spring从哪里开始扫描组件,所以它会自动发现和注册Spring容器中的bean。默认情况下,它会扫描@SpringBootApplication所在的包及其子包中的所有类。
  • 用途 :这允许开发者通过注解如@Component@Service@Repository@Controller等自动注册bean,无需显式书写bean的注册代码。
3. @EnableAutoConfiguration
  • 重要性 :这是Spring Boot的自动配置魔法所在。该注解利用Spring的条件注解(如@Conditional)来自动配置bean,假设根据类路径下的jar依赖、已定义的bean以及各种属性设置,条件成立的话。
  • 实现机制
    • @Import注解 :它导入AutoConfigurationImportSelector,这个选择器通过读取META-INF/spring.factories文件中的配置来自动选择配置类。这些配置类通常包括针对Spring Boot应用优化的自动配置类,这些类会配置如数据源、事务管理器、web配置等常见的功能。
    • @AutoConfigurationPackage :这个注解自动注册了配置类所在的包,这有助于确定需要自动配置的基本包。实际上,这个注解负责注册一个特殊的注册器,它会把主配置类(即@SpringBootApplication所在的类)所在的包注册到Spring IoC容器中。

这个流程使得Spring Boot应用可以几乎不需要任何显式配置就快速启动和运行。通过这些自动配置的能力,开发者可以将更多的精力集中在业务逻辑上,而非配置上,大大提高了开发效率和应用的启动速度。这种设计也是Spring Boot广受欢迎的重要原因之一

三、如何覆盖默认的自动配置

虽然自动配置大大简化了应用的配置工作,但有时候你可能需要修改默认的行为或覆盖自动配置的一部分。你可以通过以下方式做到这一点:

指定属性 :在application.propertiesapplication.yml中指定不同的属性值。
添加自定义@Configuration :自定义配置类可以定义额外的bean或使用@Primary注解覆盖自动配置的bean。
  • 你可以在你的启动类上使用@ComponentScan注解来指定Spring Boot扫描其他包。例如,如果你的启动类在com.example.demo包中,而你想加载com.bite.autoconfig包中的配置,你可以这样做:

    java 复制代码
    package com.example.demo;
    
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.ComponentScan;
    
    @SpringBootApplication
    @ComponentScan(basePackages = {"com.example.demo", "com.bite.autoconfig"})
    public class DemoApplication {
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    }
  • 使用@Import注解 :直接在你的配置类上使用@Import来导入特定的配置类,这将覆盖自动配置。

    • 如果你知道具体的配置类,可以直接在启动类或任何配置类上使用@Import来显式地导入配置。这适用于需要导入具体配置类的场景:

      java 复制代码
      package com.example.demo;
      
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.context.annotation.Import;
      import com.bite.autoconfig.BiteConfig;
      
      @SpringBootApplication
      @Import(BiteConfig.class)
      public class DemoApplication {
          public static void main(String[] args) {
              SpringApplication.run(DemoApplication.class, args);
          }
      }
使用@SpringBootApplicationscanBasePackages
  • @SpringBootApplication注解本身包含了@ComponentScan的功能。因此,你也可以直接在这个注解中指定要扫描的包:
java 复制代码
package com.example.demo;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication(scanBasePackages = {"com.example.demo", "com.bite.autoconfig"})
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
处理第三方JAR包
  • 对于第三方JAR包中的Bean,如果它们不是通过Spring的方式配置(比如使用Spring Boot的自动配置),你可能需要创建自己的配置类来实例化这些Bean。例如,如果一个第三方库提供了一个服务,你可以创建一个配置类,在那里创建一个Bean实例:

    java 复制代码
    package com.example.demo.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import third.party.LibraryClass;
    
    @Configuration
    public class ThirdPartyConfig {
        @Bean
        public LibraryClass libraryClass() {
            return new LibraryClass();
        }
    }
相关推荐
suweijie7683 小时前
SpringCloudAlibaba | Sentinel从基础到进阶
java·大数据·sentinel
公贵买其鹿3 小时前
List深拷贝后,数据还是被串改
java
向前看-7 小时前
验证码机制
前端·后端
xlsw_7 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
神仙别闹7 小时前
基于java的改良版超级玛丽小游戏
java
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭8 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
暮湫8 小时前
泛型(2)
java
超爱吃士力架8 小时前
邀请逻辑
java·linux·后端
南宫生8 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
转码的小石8 小时前
12/21java基础
java