目录
一、Java内存模型(JMM)核心原理
🔥 问题8:happens-before原则全景解析
JMM内存架构图
happens-before八大规则
线程安全验证案例
🔥 问题9:JMM解决可见性的三大武器
可见性保障机制
volatile双重检测单例模式
🔥 问题10:volatile的三大特性与局限
volatile适用场景矩阵
volatile内存语义
二、Spring自动装配全景解析
🌟 自动装配五种模式详解
装配方式对比表
XML配置示例
🌟 @Autowired装配流程深度解析
自动装配流程图
常见异常及解决
三、高频面试题强化训练
1. volatile能否保证原子性?
2. Spring自动装配的局限性?
3. 如何选择装配方式?
一、Java内存模型(JMM)核心原理
🔥 问题8:happens-before原则全景解析
JMM内存架构图
happens-before八大规则
规则名称 | 规则描述 | 典型场景 |
---|---|---|
程序次序规则 | 同一线程内代码顺序决定执行顺序 | 方法内部代码执行 |
管程锁定规则 | unlock操作先于后续lock操作 | synchronized块 |
volatile规则 | volatile写先于后续读 | volatile变量操作 |
线程启动规则 | start()先于线程任何操作 | Thread启动 |
线程终止规则 | 线程所有操作先于终止检测 | Thread.join() |
线程中断规则 | interrupt()先于中断检测 | isInterrupted() |
对象终结规则 | 构造方法先于finalize() | 对象回收 |
传递性规则 | A先于B,B先于C ⇒ A先于C | 复合操作 |
线程安全验证案例
public class VisibilityDemo {
private /*volatile*/ boolean flag = false; // 去掉volatile将破坏可见性
public void updateFlag() {
flag = true; // 写操作
}
public void checkFlag() {
while (!flag) {
// 可能永远循环
}
System.out.println("Flag状态已更新");
}
}
🔥 问题9:JMM解决可见性的三大武器
可见性保障机制
volatile双重检测单例模式
public class Singleton {
private static volatile Singleton instance;
public static Singleton getInstance() {
if (instance == null) { // 第一次检查
synchronized (Singleton.class) {
if (instance == null) { // 第二次检查
instance = new Singleton(); // volatile禁止指令重排序
}
}
}
return instance;
}
}
🔥 问题10:volatile的三大特性与局限
volatile适用场景矩阵
场景 | 是否适用 | 说明 |
---|---|---|
状态标志位 | ✅ | 简单可见性控制 |
一次性发布 | ✅ | 防止对象初始化重排序 |
独立观察 | ✅ | 统计计数器等场景 |
复合操作 | ❌ | 需要原子性保障 |
多变量依赖 | ❌ | 需要同步块保证原子性 |
volatile内存语义
public class VolatileExample {
volatile boolean shutdown;
public void shutdown() {
shutdown = true; // StoreStore屏障
}
public void doWork() {
while (!shutdown) { // LoadLoad屏障
// 工作逻辑
}
}
}
二、Spring自动装配全景解析
🌟 自动装配五种模式详解
装配方式对比表
模式 | 配置方式 | 行为描述 | 适用场景 |
---|---|---|---|
no | 默认值 | 需要显式ref引用 | 精确控制依赖 |
byName | autowire="byName" | 根据setter方法名匹配bean名称 | 命名规范统一 |
byType | autowire="byType" | 根据属性类型匹配唯一bean | 类型唯一场景 |
constructor | autowire="constructor" | 按构造器参数类型装配 | 强不变性对象 |
default | @Autowired | 智能推导(优先byType再byName) | 现代Spring应用 |
XML配置示例
<bean id="userService" class="com.example.UserService" autowire="byType"/>
<bean id="userDao" class="com.example.UserDaoImpl"/>
运行 HTML
🌟 @Autowired装配流程深度解析
自动装配流程图
常见异常及解决
// 1. 解决NoUniqueBeanDefinitionException
@Autowired
@Qualifier("mainDataSource")
private DataSource dataSource;
// 2. 解决可能为null的情况
@Autowired(required = false)
private Optional<SecondaryService> secondaryService;
// 3. 集合类型注入
@Autowired
private List<Plugin> plugins; // 注入所有Plugin实现
三、高频面试题强化训练
1. volatile能否保证原子性?
-
基本类型读写:对于long/double等64位操作能保证单次读写的原子性
-
复合操作:如i++这类"读-改-写"操作不能保证原子性
-
解决方案:需要配合synchronized或Atomic类
2. Spring自动装配的局限性?
局限性 | 解决方案 |
---|---|
歧义性依赖 | @Qualifier指定名称 |
原型bean循环依赖 | @Lazy延迟初始化 |
静态字段注入 | setter方法+@Autowired |
第三方库组件 | @Bean显式配置 |
3. 如何选择装配方式?
实战建议:
-
使用
@Autowired
时优先选择构造器注入 -
复杂依赖关系使用
@Configuration
显式配置 -
多实现类场景使用
@Qualifier
精确指定
💬 你在项目中如何平衡自动装配与显式配置?遇到过哪些有趣的依赖问题?
🎁 关注+转发,查询更新《Spring揭秘》