自动配置
学习SSM整合时,需要配置 Tomcat ,配置 Spring MVC,以及配置如何扫描包,配置字符过滤器,配置视图解析器,文件上传等。非常麻烦。而在 Spring Boot 中,存在自动配置 机制,提高开发效率。
现在,自动配置会自动配置好这些组件,容器中有什么组件,就具有什么功能
验证
1 | public static void main(String[] args) { |
导入场景后,容器中就会自动配置好这个场景的核心组件
自动配置的触发原理
自动配置通过 @EnableAutoConfiguration
注解触发,这个注解通常包含在 @SpringBootApplication
注解中。当 Spring Boot 应用启动时,@EnableAutoConfiguration
注解会执行以下操作:
扫描类路径下的
META-INF/spring.factories
文件Spring Boot 在启动时会扫描类路径下所有的
META-INF/spring.factories
文件。这些文件中定义了一系列的自动配置类,它们以键值对的形式存在,其中键为org.springframework.boot.autoconfigure.EnableAutoConfiguration
,值为多个自动配置类的全限定名。例如:1
2
3org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration加载配置类
Spring Boot 会根据
spring.factories
文件中定义的自动配置类,将这些类加载到 Spring 容器中。这些自动配置类使用了 Spring 的@Configuration
注解,本质上就是普通的 Java 配置类。根据条件注解决定是否生效
自动配置类中会使用大量的条件注解,如
@ConditionalOnClass
、@ConditionalOnMissingBean
、@ConditionalOnProperty
等,来决定该配置类是否生效。例如,@ConditionalOnClass
注解会检查类路径中是否存在指定的类,如果存在则该配置类生效;@ConditionalOnMissingBean
注解会检查 Spring 容器中是否已经存在指定类型的 Bean,如果不存在则该配置类生效。
@SpringBootConfiguration
查看该注解的定义,发现其上标有@Configuration
,并且里面有一个唯一的属性即proxyBeanMethods
。这说明被@SpringBootConfiguration
修饰的类也是一个配置类。
@ComponentScan
指定扫描哪些Spring注解。
@EnableAutoConfiguration
这是SpringBoot自动配置的入口
自动配置的工作流程

流程:
导入 starter-web:导入了 web 开发场景
场景启动器导入了相关场景的所有依赖:starter-json、starter-tomcat、springmvc
每个场景启动器都引入了一个
spring - boot - starter
,核心场景启动器。核心场景启动器引入了
spring - boot - autoconfigure
包。spring - boot - autoconfigure
里面囊括了所有场景的所有配置。只要这个包下的所有类都能生效,那么相当于 Spring Boot 官方写好的整合功能就能生效了。
Spring Boot 默认扫描不到
spring - boot - autoconfigure
下写好的所有配置类。(这些配置类给我们做了整合操作
主程序:
@SpringBootApplication
@SpringBootApplication
由三个注解构成@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
- Spring Boot
默认只能扫描自己主程序及其所在的下面的子包,扫描不到
spring-boot-autoconfigure
包中官方写好的配置类 @EnableAutoConfiguration
:Spring Boot 开启自动配置的核心- 是由
@Import(AutoConfigurationImportSelector.class)
提供功能:批量给容器中导入组件 - Spring Boot启动会默认加载 142 个配置类
- 这 142 个配置类来自于
spring-boot-autoconfigure
下META-INF/spring/org.springframework.boot.autoconfigurate.AutoConfiguration.imports
文件指定的 - 项目启动的时候利用
@Import
批量导入组件机制,把autoconfigure
包下的142个xxxAutoConfiguration
类导入进来(自动配置类) - 虽然导入了 142 个配置类,但是并不是全部生效
- 是由
- 按需生效
- 并不是这142个自动配置类都能生效
- 每一个自动配置类,都有条件注解
@ConditionalOnXxx
,条件成立才能生效
xxxAutoConfiguration
类导入进来(自动配置类)- 给容器中使用
@Bean
放一堆组件 - 每个自动配置类都可能有这个注解
@EnableConfigurationProperties(xxxProperties.class)
,用来把配置文件中配的指定前缀的属性值封装到xxxProperties
属性类中 - 以 Tomcat 为例子,把服务器所有配置都是以 server 开头的,配置都封装到了属性类中
- 给容器中放的所有组件的一些核心参数,都来自于
xxxProperties
,xxxProperties
都是和配置文件绑定 - 只需要改配置文件的值,核心组件的底层参数都能修改,这样就实现了导入了 starter,所有的配置都能生效
- 给容器中使用
写业务,全程无需关心各种整合(底层这些整合写好了,而且也生效了)
核心流程:
- 导入 starter,就会导入 autoconfigure 包。
autoconfigure
包里面有一个文件META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
,里面指定的所有启动要加载的自动配置类。@EnableAutoConfiguration
会自动的把上面文件里面写的所有自动配置类都导入进来。xxxAutoConfiguration
是有条件注解进行按需加载xxxAutoConfiguration
给容器中导入一堆组件,组件都是从xxxProperties
中提取属性值- xxxProperties 又是和配置文件进行了绑定
效果:导入 starter、修改配置文件,就能修改底层行为
容器功能
在深入了解 Spring Boot 的自动配置功能之前,我们需要先了解 Spring Boot 的容器管理功能。在学习 Spring Framework 时,我们知道 Spring Framework 有两大核心机制:IOC(控制反转)和 AOP(面向切面编程)。
IOC 容器的主要作用是帮助我们存放对象,并管理对象的创建、装配和销毁过程。这样,原本由程序手动完成的对象管理工作就交给了 Spring Framework 来处理。在 Spring Boot 中,我们学习的核心在于如何将对象注册到 Spring 容器中,以及如何从 Spring 容器中获取对象。
Spring Boot 的默认包扫描路径
在Spring Boot 的自动配置中,我们不需要像Spring MVC 中一定要配置扫描包 。Spring Boot 有默认的扫描包结构。这使得我们在没有指定任何包扫描路径的情况下,注册到容器中的对象也能被正常获取。这是因为 Spring Boot 默认的包扫描路径下的目标对象,都会被注册进容器中。
默认的扫描路径是 Main Application Class 所在的目录以及子目录。
@SpringBootApplication
标注的类就是主程序类,Spring Boot
只会扫描主程序所在的包及其下面的子包
配置默认值
配置文件所有配置项是和某个类的对象值是一一对应的
绑定了配置文件中的每一项值的类:配置属性类
比如
ServerProperties
绑定了所有 Tomcat 配置值相关的所有配置
如果需要改变默认的扫描路径,可以通过在启动类上配置
scanBasePackages
属性来实现:
1 | import org.springframework.boot.SpringApplication; |
该属性是一个字符串数组,可以指定多个包路径,用逗号隔开。
实际上,scanBasePackages
属性和
@ComponentScan
注解的 basePackages
属性是绑定的,因此使用 @ComponentScan
注解直接指定包扫描的路径也能达到同样的效果:
1 | import org.springframework.boot.SpringApplication; |
自动配置遵循的原则
自动配置遵守按需加载原则:也就是说,引入了哪个场景
starter启动器
就会加载该场景关联,的 jar 包,没有引入的
starter 则不会加载其关联 jar 。
SpringBoot 所有的自动配置功能都在
spring-boot-autoconfigure
包里面;
在Spring Boot 中的自动配置包,一般是 XXxAutoConfiguration.java 对应 XXxProperties.java

组件详解
@SpringBoorConfiguration
@SpringBootConfiguration
是 Spring Boot 中的一个类级注解
,用于指示标注的类提供应用程序配置。被它标注的类,意味着其中可以包含
@Bean
定义方法,Spring 容器会处理该配置类,进而实例化和配置
bean。
它本质上是 Spring 标准 @Configuration
注解的替代方法,功能基本相同。二者唯一区别在于,@SpringBootConfiguration
允许自动找到配置
通常开发中更常用的 @SpringBootApplication
注解,实际上自动继承了 @SpringBootConfiguration
注解。@SpringBootApplication
是一个组合注解,整合了
@SpringBootConfiguration
、@EnableAutoConfiguration
和 @ComponentScan
等功能。所以一般项目中使用
@SpringBootApplication
标注主应用类,就无需再单独使用
@SpringBootConfiguration
。并且建议一个应用程序中仅使用一个
@SpringBootConfiguration
或
@SpringBootApplication
批注。
@Configuration和@Bean
@Configuration
注解表示这个类是个配置类,@Bean
注解往容器中注册实例。
@Configuration
把 Spring Framework 中的 xml 改成了 java
config
配置类,配置类本身也是容器中的组件,组件默认都是单实例的,可以用@scope
注解改,跟用<scope>
标签一样。
而 @Bean
注解替代了以前的 bean
标签,组件在容器中的名字默认就是方法名,可以修改
@Bean
注解的值
1 | import com.codeliu.entity.User; |
然后在启动类中进行测试,可以发现容器中的实例都是单例的,即多次拿到的都是同一个对象。
1 |
|
@Configuration
注解中的proxyBeanMethods
属性即代理bean的方法,决定是否是单例模式,默认为
true 。Full模式(proxyBeanMethods = true)
和
Lite(proxyBeanMethods = false)
模式,Full 模式保证每个
@Bean
方法被调用多少次返回的组件都是单实例的,而 Lite 模式每个 @Bean
方法被调用多少次返回的组件都是新创建的。组件依赖必须使用 Full
模式默认,其他默认 Lite 模式
@Component、@Controller、@Service、@Repository
不多说了,四大护法,使用在pojo、mapper、service、controller类上的注解。
@Import
第三方的任意类,都可以导入到你的配置类中作为组件,给容器中放指定类型的组件,名字默认全类名
该注解定义如下,只有一个value
属性,你可以传入一个Class数组,在启动过程中,会自动帮你把类注册进容器。
1 |
|
1 |
|
可以看到,默认组件的名字是全类名。
@Conditional条件装配
意思就是满足@Conditional
指定的条件,才进行组件注入。
总之就是@ConditionalOnXxx
,指定的条件成立,才触发指定行为
条件注解详解
注解名称 | 触发条件 | 典型应用场景 |
---|---|---|
@ConditionalOnClass | 类路径存在指定类时生效 | 自动配置数据源 |
@ConditionalOnMissingBean | 容器中不存在指定Bean时生效 | 覆盖默认配置 |
@ConditionalOnProperty | 配置文件中存在指定属性时生效 | 功能开关控制 |
@ConditionalOnWebApplication | 当前是Web应用时生效 | Web相关配置 |
@ConditionalOnResource | 存在指定资源文件时生效 | 特定配置文件存在时加载 |
属性绑定类注解@ConfigurationProperties
和@EnableConfigurationProperties
@ConfigurationProperties
声明组件的属性和配置文件中的哪些前缀开始进行绑定
在 Spring Boot 里,@ConfigurationProperties
能把外部配置(像application.properties
或
application.yml
里的属性 )绑定到 Java
对象上,让配置管理更简便,配置变更更灵活动态。
这两个组件都是将容器中任意组件的属性值和配置文件的配置项进行绑定
- 给容器中注册组件
(
@Component
,@Bean
) - 使用
@ConfigurationProperties
声明组件和配置文件中的哪些配置项进行绑定 - 可以绑定到类上,可以绑定到方法上
举例
定义配置类:创建一个类,用
@ConfigurationProperties
注解标注它,并指定prefix
属性,该属性值是配置文件中相关属性的前缀。类中定义字段来对应配置属性,同时需提供这些字段对应的getter
和setter
方法 。比如:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
public class MyAppProperties {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}@ConfigurationProperties(prefix = "myapp")
表示会找配置文件中以myapp
开头的属性,像myapp.name
会绑定到name
字段 ,myapp.age
会绑定到age
字段。同时通过@Component
注解将该类注册为 Spring 容器中的组件,这样容器启动时就能处理这个配置类。配置文件配置:在
application.properties
或application.yml
里写对应属性,例如在application.properties
中指定其中的 name 和 age 字段1
2myapp.name=test
myapp.age=18使用配置:在其他组件中,可通过依赖注入使用这个配置类,获取配置属性值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
public class MyService {
private final MyAppProperties myAppProperties;
public MyService(MyAppProperties myAppProperties) {
this.myAppProperties = myAppProperties;
}
public void doSomething() {
System.out.println("Name: " + myAppProperties.getName() + ", Age: " + myAppProperties.getAge());
}
}
所以说,@ConfigurationProperties
就是将配置文件(如
application.properties
)中的属性值,绑定到 Java
类的字段上。在类上标注
@ConfigurationProperties(prefix = "xxx")
,指定配置文件中的属性前缀。但是注意,类需提供字段的
getter/setter
方法,并且需将该类注册为 Bean。
@EnableConfigurationProperties
这个一般是用于导入第三方写好的组件,进行属性绑定,即使第三方导入了并且标注了
@Component
和
@ConfigurationProperties
注解,也不行,因为默认只扫描自己主程序所在的包。
用于显式开启对 @ConfigurationProperties
注解类的支持。告知 Spring Boot 框架,项目里有用
@ConfigurationProperties
注解的类,要自动加载配置文件属性并绑定到这些类的字段上
,还能自动注册这些类为 Spring 容器中的 Bean。从 Spring Boot 2.2
起,若配置属性类已用 @Component
等注解注册为组件,可不显式用此注解,Spring Boot 会自动配置 。
使用方式:在主类或者配置类上使用该注解,并在
value
属性指定一个或多个
@ConfigurationProperties
注解的类。示例如下:
1 | import org.springframework.boot.SpringApplication; |
这里
@EnableConfigurationProperties(MyAppProperties.class)
让
Spring Boot 把配置文件属性绑定到 MyAppProperties
类实例上,并将其实例注册为 Spring 容器中的 Bean。
所以,@EnableConfigurationProperties
的功能就是启用
@ConfigurationProperties
功能,在主类或配置类上标注
@EnableConfigurationProperties(MyConfig.class)
,将指定类注册为
Bean。若配置类已用 @Component
标注,则无需显式使用此注解
Spring Boot 自动配置都配置了什么
按需加载自动配置
导入场景
场景启动器除了会导入相关功能依赖,导入一个 spring-boot-starter ,是所有 starter 的 starter
这里面还导入了一个
spring-boot-autoconfigure
包,都是各种场景的自动配置AutoConfig
类,虽然里面有全场景的,但是是导入哪个场景就启用哪个自动配置
当我们导入某个场景启动器,就会触发
spring-boot-autoconfigure
的自动配置生效,容器中就会具有相关场景的功能
自动配置 Tomcat
Spring Boot 默认会自动配置嵌入式的 Tomcat 服务器。当我们引入
spring-boot-starter-web
依赖时,Spring Boot
会自动检测到并为我们配置好 Tomcat 服务器。我们无需手动配置 Tomcat
的启动参数、端口号等信息,Spring Boot 会使用默认的配置启动 Tomcat
服务器。如果需要修改 Tomcat 的配置,例如修改端口号,可以在
application.properties
或 application.yml
文件中进行配置:server.port=8081

自动配置了 Spring MVC
Spring Boot 会自动配置 Spring MVC 的核心组件,如
DispatcherServlet、HandlerMapping、ViewResolver
等。它会根据类路径中的依赖和配置文件中的信息,自动配置合适的视图解析器、消息转换器等。例如,当我们引入
spring-boot-starter-thymeleaf
依赖时,Spring Boot
会自动配置 Thymeleaf 视图解析器,让我们可以方便地使用 Thymeleaf
模板引擎进行视图渲染。

自动配置 Web 常用功能
Spring Boot 还会自动配置 Web 开发中常用的功能,如字符过滤器、静态资源映射等。
例如,它会自动配置一个字符编码过滤器,确保请求和响应的字符编码一致。默认情况下,字符编码为 UTF-8。我们可以通过配置文件修改字符编码:
1 | spring.http.encoding.charset=UTF-8 |
我们可以通过 Debug 的方式,在 ioc 打上断点,从而查看 ioc 容器中有哪些 Bean 对象被创建了。






自定义自动配置
自定义自动配置过程
虽然 Spring Boot 的自动配置功能非常强大,但在某些情况下,我们可能需要自定义自动配置。自定义自动配置的步骤如下:
创建自动配置类:创建一个带有
@Configuration
注解的 Java 类,作为自动配置类。1
2
3
4
5
6
7
8
9
10
11
public class MyServiceAutoConfiguration {
public MyService myService(MyServiceProperties properties) {
return new MyService(properties.getPrefix());
}
}创建
META-INF/spring.factories
文件:在src/main/resources
目录下创建META-INF/spring.factories
文件,并在文件中指定自动配置类的全限定名:1
2org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.demo.MyAutoConfiguration定义配置:为了让自动配置更加灵活,可以在自动配置类中使用条件注解,根据不同的条件决定是否生效。
1
2
3
4
5
6
7
8
9
10
11
12import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
public class MyAutoConfiguration {
public MyService myService() {
return new MyService();
}
}
调试自动配置
我们可以通过 Debug 的方式,在 IOC
容器初始化的过程中打上断点,从而查看 IOC 容器中有哪些 Bean
对象被创建了。此外,Spring Boot 还提供了 --debug
启动参数,当我们在启动应用时添加该参数,Spring Boot
会输出详细的自动配置报告,帮助我们了解自动配置的过程和结果。例如,在命令行中启动应用时添加
--debug
参数:
1 | java -jar myapp.jar --debug |
查看生效配置
1 | # 启用自动配置报告 |
Spring Framework原生配置文件引入
@ImportResource
注解可以导入 Spring
的配置文件,让配置文件里的内容生效。因为有些项目 bean 定义在 xml
文件里,但你必须知道 xml 文件的路径,这样在项目启动的时候 Spring
才会加载配置文件。那对于 Spring Boot 项目来说,所有的 bean 都是通过 java
配置实现,xml 没有用武之地了吗?
@Configuration
搭配@ImportResource
可以实现xml配置的装载。
1 | import org.springframework.context.annotation.Configuration; |
Spring Boot 中的 application.properties
自定义 application.properties 中的配置
SpringBoot 项目最重要也是最核心的配置文件就是 application.properties,所有的框架配置都可以在这个配置文件中说明
在Spring Boot中各种配置都有默认,当然可以自定义
特别注意:该文件名必须是
application.properties
,后缀也不可以修改。强烈建议将其放到 类的根路径下(也就是resources
目录下 )其次是,注意:在
.properties
后缀的配置文件,当中编写,不要有空格,尽量不要有空格。
在 Spring Boot 里,我们可以借助 .properties
文件进行自定义配置,并且利用 @Value("${}")
注解来获取这些配置的属性值。这样做能让我们更灵活地管理应用的配置信息,而不需要将这些信息硬编码在代码里。
在需要使用这些配置信息的 Java 类里,我们可以通过 @Value
注解来注入配置属性值。下面是一个示例
1 | # 自定义数据库连接信息 |
1 | import org.springframework.beans.factory.annotation.Value; |
我们可以在服务类或者控制器里注入 CustomConfig
类的实例,然后使用其中的配置信息。示例如下:
1 | import org.springframework.beans.factory.annotation.Autowired; |
默认值设置:如果
.properties
文件中没有定义某个属性,而我们又使用了@Value
注解去获取该属性值,应用启动时会抛出异常。为了避免这种情况,我们可以给@Value
注解设置默认值,示例如下:1
2
private int dbPort;上述代码中,如果
custom.db.port
属性没有在.properties
文件中定义,dbPort
会被赋予默认值3306
。
配置文件的优先级
Spring Boot 支持多种配置文件,如
application.properties
、application.yml
以及不同环境的配置文件(如
application-dev.properties
、application-prod.properties
)。这些配置文件有不同的优先级,需要注意它们之间的覆盖关系。
Spring Boot 中在哪里配置读取 application.properties 配置文件
打开 ConfigFileApplicationListener.java , 看一下源码

1 | // 指明: application.properties 可以存放的位置在哪里,Spring Boot 可以成功读取到 |