Springboot自动配置原理

2023-11-18 08:14:24 浏览数 (1)

Springboot只需要导入starter,就可以愉快地写代码了,其余的配置都不需要我们来考虑,显得十分便捷,那么Springboot这种自动配置机制的原理是怎样的呢?

Springboot开发流程

以web应用程序开发为例:

  1. 导入starter-web,即导入了web开发场景
  2. 编写主程序,并且主程序类被注解@SpringBootApplication标识
  3. 编写业务代码,全程无需关心各种业务整合(Springboot代替我们完成了)

导入starter-web

导入web开发的场景启动器starter-web

代码语言:javascript复制
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

这个场景启动器对应的文件为spring-boot-starter-web-3.1.5.pom,它导入了相关场景的所有依赖。例如spring-boot-starter-json,spring-boot-starter-tomcat,springmvc等。 值得注意的是,每个场景启动器都引入了一个核心场景启动器,即spring-boot-starter

核心场景启动器spring-boot-starter

核心场景启动器对应的文件为spring-boot-starter-3.1.5.pom,可以看到核心场景启动器也引入了若干依赖,其中比较重要的一个是自动配置包,即spring-boot-autoconfigure

spring-boot-autoconfigure包下包含了springboot官方所有场景的配置类,只要这个包下的类可以生效,那么Springboot官方写好的整合功能就生效了。

但是,问题在于,Springboot默认只扫描主程序所在的包及其下面的子包,并不能扫描到spring-boot-autoconfigure包下的配置类,Springboot是如何让它们生效的呢?

主程序

一个简单的主程序示例如下:

代码语言:javascript复制
// springboot必需的注解
// 表示这是一个springboot应用
@SpringBootApplication
public class MainApp {
    public static void main(String[] args) {
        SpringApplication.run(MainApp.class,args);
    }
}

主程序上带有注解@SpringBootApplication,这个注解由三个注解组成,分别是@SpringBootConfiguration(标识这是一个配置类),@EnableAutoConfiguration@ComponentScan

@EnableAutoConfiguration注解

@EnableAutoConfiguration很关键,它是Springboot开启自动配置的核心注解。 @EnableAutoConfiguration上有一个@Import({AutoConfigurationImportSelector.class}),其作用是给容器中导入组件,这里是起到批量导入的功能,允许类AutoConfigurationImportSelector指定需要导入哪些组件。 这里使得Springboot启动会默认加载100多个配置类,这些类来自于spring-boot-autoconfigure包下META-INFspringorg.springframework.boot.autoconfigure.AutoConfiguration.imports文件指定的所有类,名称均为xxxAutoConfiguration形式。

虽然Springboot默认只扫描主程序所在的包及其子包,但是却通过注解把自动配置类都导入了进来。

虽然这些类全部都被导入了,但是这些类不一定都生效。

自动配置类生效

Kafka的自动配置类为例:

代码语言:javascript复制
@AutoConfiguration
@ConditionalOnClass({KafkaTemplate.class})
@EnableConfigurationProperties({KafkaProperties.class})
@Import({KafkaAnnotationDrivenConfiguration.class, KafkaStreamsAnnotationDrivenConfiguration.class})
public class KafkaAutoConfiguration {
    private final KafkaProperties properties;

    KafkaAutoConfiguration(KafkaProperties properties) {
        this.properties = properties;
    }

    @Bean
    @ConditionalOnMissingBean({KafkaConnectionDetails.class})
    PropertiesKafkaConnectionDetails kafkaConnectionDetails(KafkaProperties properties) {
        return new PropertiesKafkaConnectionDetails(properties);
    }
    ······

注意到,这个自动配置类之上,有一个注解@ConditionalOnClass({KafkaTemplate.class}),这意味着只有当类路径下存在KafkaTemplate这个类,也就是说我导入了这个包,整个配置才会生效。

这就是按需生效,不是导入的类都能生效,而是通过条件注解来控制哪些类生效。

在自动配置类中,会使用@Bean注解给容器中放一堆组件,这样Springboot就完成了自动配置。

通过配置文件配置

在写好了一个web程序后,为什么通过配置文件(.properties)就可以配置应用程序的信息,例如端口号等? 这是因为每个自动配置类之上都有一个注解形似: @EnableConfigurationProperties({KafkaProperties.class}),它用于把配置文件中指定前缀的属性值封装到xxxProperties属性类中。 在自动配置类生效时,会自动加载配置文件中的属性,这样只需要程序重启即可更新配置。

版权声明: 如无特别声明,本文版权归 月梦の技术博客 所有,转载请注明本文链接。

(采用 CC BY-NC-SA 4.0 许可协议进行授权)

本文标题:《 Springboot自动配置原理 》

本文链接:https://ymiir.netlify.app//springboot/Springboot自动配置原理.html

本文最后一次更新为 天前,文章中的某些内容可能已过时!

0 人点赞