SpringBoot 原理 · 配置优先级 · Bean 管理 · 自动配置 · 重点总结
一、配置文件优先级
1.1 SpringBoot 三种配置文件
| 配置文件 |
格式 |
推荐度 |
application.properties |
key=value |
优先级最高 |
application.yml |
yaml 缩进格式(主流推荐) |
优先级中 |
application.yaml |
同 yml |
优先级最低(与 yml 等价但更少用) |
⚠️ 三种配置文件如果配置同一属性,优先级:properties > yml > yaml;项目开发中统一使用 yml 即可。
1.2 五种配置方式优先级(⭐ 常考)
| 优先级 |
配置方式 |
示例 |
| 最高 |
命令行参数 |
--server.port=10010 |
| 高 |
Java 系统属性 |
-Dserver.port=9000 |
| 中 |
application.properties |
server.port=8081 |
| 低 |
application.yml |
server:\n port: 8082 |
| 最低 |
application.yaml |
同 yml |
优先级公式:命令行参数 > 系统属性参数 > properties > yml > yaml
1.3 打包后运行时指定参数
1 2 3 4 5 6
| mvn package
java -Dserver.port=9000 -jar app.jar --server.port=10010
|
打包必须引入 spring-boot-maven-plugin 插件(基于官方骨架创建项目自动包含)。
二、Bean 管理
2.1 从 IOC 容器获取 Bean 三种方式
前提:先注入 ApplicationContext(IOC 容器对象)
| 方式 |
方法签名 |
示例 |
| 按名称获取 |
Object getBean(String name) |
ctx.getBean("deptController") |
| 按类型获取 |
<T> T getBean(Class<T> type) |
ctx.getBean(DeptController.class) |
| 按名称+类型 |
<T> T getBean(String name, Class<T> type) |
ctx.getBean("deptController", DeptController.class) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @SpringBootTest class ApplicationTests {
@Autowired private ApplicationContext applicationContext;
@Test public void testGetBean() { DeptController b1 = (DeptController) applicationContext.getBean("deptController"); DeptController b2 = applicationContext.getBean(DeptController.class); DeptController b3 = applicationContext.getBean("deptController", DeptController.class);
System.out.println(b1 == b2); } }
|
2.2 Bean 作用域(@Scope)
| 作用域 |
说明 |
singleton |
容器中同名 bean 只有一个实例(默认) |
prototype |
每次获取该 bean 都创建新实例(非单例) |
request |
每个 HTTP 请求范围创建新实例(仅 web) |
session |
每个会话范围创建新实例(仅 web) |
application |
每个应用范围创建新实例(仅 web) |
| 注解 |
作用 |
@Scope("prototype") |
设置 bean 为多例 |
@Lazy |
延迟加载(第一次使用 bean 时才创建,否则启动时创建) |
1 2 3 4 5 6 7 8
| @Scope("prototype") @Lazy @RestController public class DeptController { public DeptController() { System.out.println("DeptController 创建..."); } }
|
⚠️ 实际开发中绝大部分 Bean 都是单例的,无需配置 @Scope。
2.3 第三方 Bean 管理(@Bean)
场景:第三方依赖类无法修改源码加 @Component,需要使用 @Bean 注解将其交给 IOC 容器。
| 方案 |
推荐度 |
在启动类上 @Bean 方法 |
❌ 不推荐(破坏启动类纯粹性) |
单独定义 @Configuration 配置类,使用 @Bean |
✅ 推荐 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @Configuration public class CommonConfig {
@Bean public SAXReader saxReader() { return new SAXReader(); }
@Bean public SomeBean someBean(DeptService deptService) { return new SomeBean(deptService); } }
|
2.4 Bean 来源四类
| 来源 |
注册方式 |
示例 |
| SpringBoot 自动管理 |
自动配置 |
ApplicationContext、HttpServletRequest |
| 第三方起步依赖自动配置 |
starter 自动装配 |
MyBatis 的 Mapper、Druid 连接池 |
| 自定义类 |
@Component/@Controller/@Service/@Repository |
业务类 |
| 第三方普通类 |
@Configuration + @Bean |
SAXReader、Gson |
三、SpringBoot 原理总览
3.1 SpringBoot 简化开发的两大核心
| 核心 |
解决问题 |
原理 |
| 起步依赖 |
解决依赖配置繁琐、版本冲突问题 |
Maven 依赖传递机制 |
| 自动配置 |
解决 bean 声明和配置繁琐问题 |
@EnableAutoConfiguration + ImportSelector + 配置文件 |
四、起步依赖原理
4.1 概念
SpringBoot 提供的起步依赖(命名以 spring-boot-starter- 开头)已包含开发所需的所有依赖。引入一个起步依赖,所有传递依赖会自动引入。
4.2 命名规范
| 类型 |
命名规则 |
| SpringBoot 官方 |
spring-boot-starter-xxx(如 spring-boot-starter-web) |
| 第三方组织 |
xxx-spring-boot-starter(如 mybatis-spring-boot-starter) |
结论:起步依赖原理就是 Maven 依赖传递。
五、自动配置原理(⭐ 核心)
5.1 自动配置的概念
SpringBoot 启动后,一些配置类、bean 对象自动存入 IOC 容器,无需手动声明。
5.2 实现自动配置的四种导入方案对比
| 方案 |
写法 |
评价 |
① @ComponentScan 扫描第三方包 |
@ComponentScan({"com.itheima","com.example"}) |
❌ 繁琐、性能低 |
② @Import 导入普通类 |
@Import(TokenParser.class) |
⚠️ 需知道第三方有哪些类 |
③ @Import 导入配置类 |
@Import(HeaderConfig.class) |
⚠️ 同上 |
④ @Import 导入 ImportSelector 实现类 |
@Import(MyImportSelector.class) |
⚠️ 同上 |
⑤ 第三方提供 @EnableXxx 注解(封装 @Import) |
@EnableHeaderConfig |
✅ SpringBoot 采用方式 |
5.3 @SpringBootApplication 注解结构(⭐ 最重要)
1 2 3 4 5 6 7 8 9
| @SpringBootApplication ├── @SpringBootConfiguration → 启动类即配置类 ├── @ComponentScan → 扫描启动类所在包及子包的组件 └── @EnableAutoConfiguration ⭐ 自动配置核心 └── @Import(AutoConfigurationImportSelector.class) └── selectImports() 方法 └── 读取两个配置文件: 1. META-INF/spring.factories(旧) 2. META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(新)
|
5.4 自动配置完整流程
| 步骤 |
操作 |
① 启动类有 @SpringBootApplication |
内部包含 @EnableAutoConfiguration |
② @EnableAutoConfiguration 含 @Import(AutoConfigurationImportSelector.class) |
— |
③ AutoConfigurationImportSelector 实现 ImportSelector 接口,重写 selectImports() |
— |
④ selectImports() 读取所有 jar 包中的两个文件 |
spring.factories + AutoConfiguration.imports |
⑤ 文件中列出的所有自动配置类被 @Import 加载到 IOC 容器 |
— |
⑥ 配置类中 @Bean 方法的返回值被注册为 bean |
— |
⑦ @Conditional 系列注解决定是否真正注册(按条件装配) |
— |
5.5 @Conditional 系列注解(⭐ 条件装配)
作用:满足条件时才注册 bean 到 IOC 容器,使 SpringBoot 智能装配。
| 注解 |
触发条件 |
@Conditional |
父注解,自定义条件 |
@ConditionalOnClass |
环境中存在指定类的字节码文件才注册 |
@ConditionalOnMissingBean |
IOC 容器中没有指定 bean 才注册 |
@ConditionalOnProperty |
配置文件中存在指定属性和值才注册 |
@ConditionalOnBean |
容器中存在指定 bean 才注册 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| @Configuration public class HeaderConfig {
@Bean @ConditionalOnClass(name = "io.jsonwebtoken.Jwts") public HeaderParser headerParser() { return new HeaderParser(); }
@Bean @ConditionalOnMissingBean(HeaderConfig.class) public HeaderParser headerParser2() { return new HeaderParser(); }
@Bean @ConditionalOnProperty(name = "name", havingValue = "itheima") public HeaderParser headerParser3() { return new HeaderParser(); } }
|
六、自定义 starter
6.1 自定义 starter 标准结构
| 模块 |
职责 |
| xxx-spring-boot-starter 模块 |
仅依赖管理(pom.xml 引入 autoconfigure 模块 + 必需依赖),无代码 |
| xxx-spring-boot-autoconfigure 模块 |
自动配置核心:写配置类 + Properties 类 + 工具类 + 自动配置文件 |
使用方只需引入 starter 即可(autoconfigure 通过依赖传递自动引入)。
6.2 实现步骤(以阿里云 OSS 为例)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 1. 创建 starter 模块 └── pom.xml 引入 autoconfigure 模块依赖
2. 创建 autoconfigure 模块 └── 创建 AliOSSProperties 类(@ConfigurationProperties 读配置) └── 创建 AliOSSUtils 类(业务功能) └── 创建 AliOSSAutoConfiguration 类(@Configuration 配置类,@Bean 方法注册 bean)
3. 在 autoconfigure 模块的 resources 下创建: META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 内容:com.aliyun.oss.AliOSSAutoConfiguration
4. mvn install 到本地仓库
5. 使用方引入 starter,application.yml 配置参数即可使用
|
6.3 关键代码
Properties 类:
1 2 3 4 5 6 7 8
| @Data @ConfigurationProperties(prefix = "aliyun.oss") public class AliOSSProperties { private String endpoint; private String accessKeyId; private String accessKeySecret; private String bucketName; }
|
自动配置类:
1 2 3 4 5 6 7 8 9 10 11
| @Configuration @EnableConfigurationProperties(AliOSSProperties.class) public class AliOSSAutoConfiguration {
@Bean public AliOSSUtils aliOSSUtils(AliOSSProperties props) { AliOSSUtils utils = new AliOSSUtils(); utils.setAliOSSProperties(props); return utils; } }
|
自动配置文件:
1 2
| # resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports com.aliyun.oss.AliOSSAutoConfiguration
|
install 不报错的配置(无 main 方法时):
1 2 3 4 5 6 7 8 9 10 11
| <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <skip>true</skip> </configuration> </plugin> </plugins> </build>
|
七、配置文件相关注解
7.1 注解速查
| 注解 |
作用 |
示例 |
@Value("${key}") |
读取配置文件单个属性 |
@Value("${server.port}") private Integer port; |
@ConfigurationProperties(prefix="前缀") |
批量读取配置文件属性,按属性名自动匹配 |
详见下方代码 |
@PropertySource("classpath:xxx.properties") |
读取自定义配置文件 |
配合 @Value 使用 |
@EnableConfigurationProperties(类.class) |
启用 @ConfigurationProperties 类,注入 IOC |
在 @Configuration 类上使用 |
7.2 @ConfigurationProperties 完整示例
1 2 3 4 5 6 7 8
| jdbc: url: jdbc:mysql://localhost:3306/db username: root password: 1234 driver-class-name: com.mysql.cj.jdbc.Driver initial-size: 5 max-active: 10
|
1 2 3 4 5 6 7 8 9 10 11
| @Data @ConfigurationProperties(prefix = "jdbc") @Component public class MyDruidData { private String url; private String username; private String password; private String driverClassName; private int initialSize; private int maxActive; }
|
7.3 依赖注入注解
| 注解 |
注入方式 |
@Autowired |
按类型注入;类型有多个 bean 时配合 @Qualifier("名称") 使用 |
@Resource |
默认按名称注入;未指定名称时按类型注入 |
八、Web 后端开发技术总结
8.1 三层架构
| 层 |
包 |
职责 |
| 表示层 |
controller |
接收请求、响应数据 |
| 业务层 |
service |
业务逻辑处理 |
| 持久层 |
dao / mapper |
数据库访问 |
8.2 核心技术分类
| 类别 |
技术 |
| 传统 JavaWeb |
Filter 过滤器、Cookie、Session |
| 企业方案 |
JWT 令牌、阿里云 OSS |
| Spring Framework 核心 |
IOC、DI、AOP、事务管理、全局异常处理、拦截器 |
| Spring Web 模块(SpringMVC) |
@Controller、@RequestMapping、参数接收、响应处理 |
| 持久层 |
MyBatis |
8.3 SSM 与 SpringBoot
| 项目 |
说明 |
| SSM |
SpringMVC + Spring Framework + MyBatis |
| SpringBoot 整合 SSM |
主流企业开发方式(基于 SpringBoot 简化整合) |
九、综合速查
自动配置原理一句话
1 2 3 4 5 6 7
| @SpringBootApplication → @EnableAutoConfiguration → @Import(AutoConfigurationImportSelector) → selectImports() 读取 META-INF/spring/...AutoConfiguration.imports → 加载所有自动配置类 → 配置类的 @Bean 方法 + @Conditional 条件装配 → 满足条件的 bean 注册到 IOC 容器
|
配置优先级速记
1
| 命令行 > 系统属性 > properties > yml > yaml
|
Bean 管理三个层次
1 2 3
| 自定义类 → @Component/@Service/@Controller/@Repository 第三方类 → @Configuration + @Bean 依赖注入 → @Autowired(按类型)/ @Resource(按名称)
|
自定义 starter 三步法
1 2 3
| ① 写 autoconfigure 模块(配置类 + Properties + 工具类) ② 写 starter 模块(仅依赖 autoconfigure 模块) ③ 创建 META-INF/spring/...AutoConfiguration.imports 文件,列出配置类全限定名
|