一、配置优先级
Spring Boot 支持多种方式配置属性,其优先级从高到低如下:
-
命令行参数(最高)
bash--server.port=10010 -
Java系统属性
bash-Dserver.port=9000 -
application.properties
-
application.yml
-
application.yaml(最低)
✅ 提示 :实际开发中,推荐使用
application.yml或application.properties管理配置;命令行和系统属性常用于测试或部署时临时覆盖。
二、Bean管理
1. Bean的作用域(Scope)
Spring 支持五种作用域,后三种仅在 Web 环境生效:
| 作用域 | 说明 |
|---|---|
| singleton | 容器内同名称的 bean 只有一个实例(默认),项目启动时创建并存入 IOC 容器 |
| prototype | 每次使用该 bean 时都会创建新实例(多例) |
| request | 每个 HTTP 请求创建一个新实例(Web) |
| session | 每个用户会话创建一个新实例(Web) |
| application | 每个 ServletContext 创建一个实例(Web) |
补充:@Lazy 注解
- 用于延迟初始化 singleton bean,直到第一次被使用才创建。
- 对 prototype 无效(因为每次都是新建)。
2. Singleton vs Prototype 应用场景与优缺点
Singleton(单例)
- 应用场景 :
- 无状态的工具类(如:日志记录器、配置管理器、数据库连接池)
- 不保存请求/用户相关数据的 Service、DAO 层组件
- 全局共享资源(如缓存管理器)
- 优点 :
- 节省内存(只创建一次)
- 提高性能(避免重复初始化)
- 易于维护全局状态一致性
Prototype(多例)
- 应用场景 :
- 有状态的组件(如:购物车、用户会话上下文)
- 每次请求需要独立数据隔离的业务对象(如:表单验证器、任务处理器)
- 优点 :
- 避免线程安全问题(每个线程/请求拥有独立实例)
- 数据隔离性好,适合并发处理
💡 面试重点 :绝大部分 Spring Bean 是 singleton,无需显式配置 scope。
3. 常见面试题
Q1:Spring 容器中的 bean 是单例还是多例?单例 bean 何时实例化?
- 答 :默认是 singleton(单例)。
- 单例 bean 在 Spring 容器启动时 就完成实例化(除非加了
@Lazy)。
Q2:Spring 的 bean 是线程安全的吗?
- 答 :取决于 bean 是否有状态。
- 无状态 bean(如 Service、DAO):线程安全 ✅
- 有状态 bean(含可变成员变量):线程不安全 ❌,需自行加锁或改为 prototype。
三、第三方 Bean 管理(@Bean 详解)
什么是"第三方 Bean"?
指不是你自己写的类 ,而是来自外部依赖(如 MyBatis 的 SqlSessionFactory、阿里云 OSS 客户端等)。这类类无法用 @Component 注解。
如何管理?
使用 @Bean + @Configuration:
java
@Configuration
public class ThirdPartyConfig {
@Bean
public AliyunOSSOperator ossOperator() {
return new AliyunOSSOperator("accessKey", "secret");
}
}
关键点:
@Bean方法名默认作为 bean 名称(可用name属性自定义)- 方法参数可自动注入其他 bean(Spring 自动装配)
- 适用场景 :
- 自定义类 → 用
@Component/@Service等 - 第三方类 → 用
@Bean
- 自定义类 → 用
✅ 最佳实践 :将第三方 bean 集中放在一个或多个
@Configuration类中,便于维护。
四、Spring Boot 核心原理
1. 起步依赖(Starter)
- 基于 Maven/Gradle 的 依赖传递,简化依赖引入。
- 例如:
spring-boot-starter-web自动引入 Tomcat、Spring MVC、Jackson 等。
2. 自动配置(Auto Configuration)
- 核心注解 :
@EnableAutoConfiguration(包含在@SpringBootApplication中) - 实现机制 :
- 扫描
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports - 条件化注册 bean(通过
@Conditional*注解)
- 扫描
条件注解常用类型:
@ConditionalOnClass:类路径存在某 class 才生效@ConditionalOnMissingBean:容器中没有该 bean 才创建@ConditionalOnProperty:配置文件中有指定属性才生效
🌰 例如:只有当
spring.datasource.url存在,才会自动配置DataSource。
3. 自定义 Starter 开发步骤
- 创建
xxx-spring-boot-autoconfigure模块(含自动配置逻辑) - 创建
xxx-spring-boot-starter模块(仅依赖 autoconfigure) - 在 autoconfigure 模块中:
- 编写
@Configuration类 - 使用
@Conditional控制 bean 注册 - 在
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports中注册配置类
- 编写
五、补充:Java 单例 vs 多例设计模式
1. 单例模式(Singleton)
- 定义 :确保一个类只有一个实例,并提供全局访问点。
- 实现要点 :
- 构造方法私有(
private) - 静态私有实例(
private static final) - 公共静态获取方法(
getInstance())
- 构造方法私有(
- 常见实现 :
- 饿汉式(线程安全,非懒加载)
- 懒汉式(需加
synchronized或 DCL 保证线程安全) - 静态内部类(推荐)
- 枚举(最安全,防反射/序列化破坏)
- 应用场景 :配置管理、日志记录、线程池、数据库连接池 ty-reference。
2. 多例模式(Multiton)
- 定义 :限制类的实例数量为有限个(如星期7天、性别2种)。
- 实现方式 :
- 预定义固定数量的静态实例(如
MALE,FEMALE) - 或维护一个对象池(List/Map),按需返回 ty-reference。
- 预定义固定数量的静态实例(如
- 应用场景:状态机、缓存池、有限资源管理。
💡 对比:单例 = 1个实例;多例 = N个预定义实例;prototype = 无限新实例。
六、补充:IOC 容器与依赖注入(DI)
1. 什么是 IOC(控制反转)?
- 传统方式 :程序员
new对象,控制权在代码。 - IOC 方式 :对象由 Spring 容器创建和管理 ,控制权"反转"给容器 ty-reference。
2. 什么是 DI(依赖注入)?
- 容器在创建 bean 时,自动将其依赖的其他 bean 注入进来。
- 注入方式 :
- 构造方法注入(推荐)
- Setter 方法注入
- 字段注入(
@Autowired,简洁但不利于单元测试)
3. IOC 容器类型
BeanFactory:基础容器ApplicationContext:高级容器(支持事件、国际化等),实际开发用这个
4. Bean 生命周期
- 实例化
- 属性赋值(DI)
- 初始化(
@PostConstruct/init-method) - 使用
- 销毁(
@PreDestroy/destroy-method)
✅ 理解关键 :Spring 通过 反射 + 配置元数据 自动构建对象图并注入依赖 ty-reference。
总结:面试高频考点
| 主题 | 关键点 |
|---|---|
| 配置优先级 | 命令行 > 系统属性 > properties > yml |
| Bean 作用域 | singleton(默认)、prototype(多例) |
| 线程安全 | 无状态单例安全,有状态需谨慎 |
| 第三方 Bean | 用 @Bean + @Configuration |
| 自动配置 | @EnableAutoConfiguration + @Conditional |
| 单例模式 | 私有构造 + 静态实例 + 全局访问点 |
| IOC/DI | 控制反转 + 依赖注入 = 解耦核心 |
此笔记可作为快速复习手册,建议结合代码实践加深理解。