前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Springboot自动配置原理

Springboot自动配置原理

作者头像
月梦@剑心
发布2023-11-18 08:14:24
1220
发布2023-11-18 08:14:24
举报

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

pilc8AK.md.png
pilc8AK.md.png

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-INF\spring\org.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%E8%87%AA%E5%8A%A8%E9%85%8D%E7%BD%AE%E5%8E%9F%E7%90%86.html

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Springboot开发流程
  • 导入starter-web
    • 核心场景启动器spring-boot-starter
    • 主程序
      • @EnableAutoConfiguration注解
        • 自动配置类生效
        • 通过配置文件配置
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档