SpringBoot - 自动配置原理

本文深入探讨了SpringBoot的自动配置原理,包括@SpringBootApplication注解的解析,自动配置的生效机制,以及@EnableAutoConfiguration如何根据依赖条件加载配置。通过分析@EnableAutoConfiguration、@ComponentScan和@ConfigurationProperties等注解的作用,揭示了SpringBoot如何简化项目配置。此外,文章还介绍了自动配置生效的条件注解,如@ConditionalOnBean、@ConditionalOnClass等,并附带了自动配置的流程图。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参看

  1. 博客1:https://blog.youkuaiyun.com/u014745069/article/details/83820511
  2. 博客2:https://afoo.me/posts/2015-07-09-how-spring-boot-works.html
  3. SpringBoot文档:http://felord.cn/_doc/_springboot/2.1.5.RELEASE/_book/pages/spring-boot-features.html


零、前言

SpringBoot基于Spring4提供的 按条件配置Bean 的能力使得SpringBoot没有了繁琐的配置。这些优点就使得我们 新建一个SpringBoot项目 变得及其的简单。

在SpringBoot中的配置文件如.properties.yml是不可或缺的,而在SpringBoot项目中,没有配置什么扫描或者是加载配置文件等,那么SpringBoot是如何使得我们的配置文件生效的?往下看。

SpringBoot自动装配,简而言之,原理就是

Spring Boot启动后,在 @EnableAutoConfiguration注解的作用下,启动器会找所有的External Libraries中的META-INF/spring.factories配置文件(都是以为键值对存储)中的所有自动配置类,并对其进行加载。而这些自动配置类都是以AutoConfiguration结尾来命名的,它实际上就是一个JavaConfig形式的Spring容器配置类。自动配置类能通过以Properties结尾命名的类,取得在全局配置文件中配置的属性,如:server.port(key-value形式)。而XxxxProperties类是通过 @ConfigurationProperties注解与全局配置文件中对应的属性进行绑定的。

JavaConfig:就是SpringBoot项目启动类中main方法里 SpringApplication.run()传递进去的类,比如

@SpringBootApplication
public class HelloSpringBoot {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(HelloSpringBoot.class, args);
    }
}

中的HelloSpringBoot就是一个JavaConfig,而SpringApplication.run就会开始加载必要的bean。

SpringBoot自动配置流程图

在这里插入图片描述

下面就是一些分析。


一、SpringBoot启动类注解

查看官方文档并没有发现自动配置的原理,但是我们知道SpringBoot必须有一个启动类,而启动类的@SpringBootApplication注解必不可少。

@SpringBootApplication
public class xxxApplication {

	public static void main(String[] args) {
		SpringApplication.run(xxxApplication.class, args);
	}

}

下面就来看一看@SpringBootApplication到底怎样。


@SpringBootApplication

查看@SpringBootApplication源码,可以看出它是一个复合注解

在这里插入图片描述

@SpringBootConfiguration、@EnableAutoConfiguration和@ComponentScan三个非常重要的注解。那么要明白@SpringBootApplication注解的作用,当然就得先明白以上那三个注解的作用了,一个一个来分析。


@SpringBootConfiguration

查看源码,顺便把注释Download下来,看一下注解:

在这里插入图片描述

注释的大致意思就是:在这个注解上面(@SpirngBootConfiguration),又有一个 @Configuration 注解。@SpirngBootConfiguration的作用就是声明当前类是一个配置类,然后Spring会自动扫描到添加了 @Configuration 的类,并且读取其中的配置信息。


@EnableAutoConfiguration

还是一样,查看源码:

在这里插入图片描述

这里的注解太多,大致就是说一些自动配置时需要开发者注意的点。而当你去阅读官方文档的时候,就会阅读到下面这一段话:

The second class-level annotation is @EnableAutoConfiguration . This annotation tells Spring Boot to “guess” how you want to configure Spring, based on the jar dependencies that you have added. Since spring-boot-starter-web added Tomcat and Spring MVC, the auto-configuration assumes that you are developing a web application and sets up Spring accordingly.

大致意思是:第二级的注解 @EnableAutoConfiguration ,告诉SpringBoot基于你所添加的依赖,去“猜测”你想要如何配置 Spring。比如我们引入了 spring-boot-starter-web ,而这个启动器中帮我们添加了 tomcat 、 SpringMVC 的 依赖。此时自动配置就知道你是要开发一个web应用,所以就帮你完成了web及SpringMVC的默认配置了!

简单点说就是:SpringBoot内部对大量的第三方库进行了默认配置,我们引入对应库所需的依赖,那么默认配置就会生效

而其中的@EnableAutoConfiguration实现的关键功能由@Import提供的,我们查看AutoConfigurationImportSelector类的源码就不看了,它的作用就是扫描所有导入依赖的具有META-INF/spring.factories的jar包。如spring-boot-autoconfigure-x.x.x.x.jar里就有一个这样的spring.factories文件。里面所有的配置文件都是键值对(key-value),可以去查看源代码。

之后找到所有的JavaConfig自动配置类的全限定名对应的class,之后实现自动配置类加载到Spring容器中。


@ComponentScan

点开源码,也没有什么特别的,发现这一段注释说明了此注解的作用

在这里插入图片描述

大致意思是:配置组件扫描的指令。提供了类似与<context:component-scan>标签的作用,通过basePackageClasses或者basePackages属性来指定要扫描的包。如果没有指定这些属性,那么将从声明这个注解的类所在的包开始,扫描包及子包。

而@SpringBootApplication注解声明的类就是main函数所在的启动类,因此扫描的包是该类所在包及其子 包。因此,一般启动类会放在一个比较前的包目录中。


二、自动配置生效

1.依靠注解

通过上面的分析,我们了解到启动类启动后会自动配置三方工具。而每一个XxxxAutoConfiguration自动配置类都是在某些条件之下才会生效的,这些条件的限制在Spring Boot中以注解的形式体现,常见的条件注解有如下几项:

  1. @ConditionalOnBean:当容器里有指定的bean的条件下生效。
  2. @ConditionalOnMissingBean:当容器里不存在指定bean的条件下生效。
  3. @ConditionalOnClass:当类路径下有指定类的条件下生效。
  4. @ConditionalOnMissingClass:当类路径下不存在指定类的条件下生效。
  5. @ConditionalOnProperty:指定的属性是否有指定的值,比如@ConditionalOnProperties(prefix=”xxx.xxx”, value=”enable”, matchIfMissing=true),代表当xxx.xxx为enable时条件的布尔值为true,如果没有设置的情况下也为true。

以大家都很熟悉的SpringMVC为例,查看mvc自动配置类WebMvcAutoConfiguration

在这里插入图片描述

@Configuration:声明这个类是一个配置类。

@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class }):判断是否引入了相 关依赖,引入依赖后该条件成立,当前类的配置才会生效。

@ConditionalOnMissingBean(WebMvcConfigurationSupport.class):WebMVCConfigurationSupport类配置后,那么这个默认配置就会失效。

当然还有其他的配置文件中 xxxAutoConfiguration 可能又会有各自的不同。


2.自动配置生效流程图

先看图,再看解释:

图片参考:https://afoo.me/posts/2015-07-09-how-spring-boot-works.html

在这里插入图片描述

SpringApplication作为一个Bootstrap(是Tomcat中的)类,可以加载JavaConfig形式的配置, 也可以加载XML形式的配置。之后以JavaConfig为主线,SpringBoot会创建一个对应处理JavaConfig形式配置的AnnotationConfigApplicationContext实例(或者有Servlet等类,则创建ConfigurableWebApplicationContext)。

在ApplicationContext创建的之前和之后, SpringBoot会使用SpringFactoriesLoader这个特性,从当前classpath下所有的META-INF/spring.factories下加载如下类型的一些callback接口并在前中后等不同时机执行:

  1. org.springframework.boot.SpringApplicationRunListener
  2. org.springframework.context.ApplicationContextInitializer
  3. org.springframework.context.ApplicationListener

ApplicationContext就正式加载SpringApplication.run方法传入进来的配置了(JavaConfig形式或者XML形式)。

因为标注了@SpringBootApplication,容器会自动完成指定语义的一系列职能,包括@EnableAutoConfiguration要求的事情。

之后的CommandLineRunner是用来扩展的,根据需求和场景,实现一些自己的CommandLineRunner并添加到容器来对SpringBoot应用进行某种扩展。


三、结语

一定要记得:

XxxxProperties类的含义是:封装配置文件中相关属性。

XxxxAutoConfiguration类的含义是:自动配置类,目的是给容器中添加组件。

而其他的主方法启动,则是为了加载这些五花八门的XxxxAutoConfiguration类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值