1. 引言
Spring Framework 是 Java 生态中最核心、最基础的企业级应用开发框架。它通过**控制反转(IoC)与面向切面编程(AOP)**两大核心理念,极大地简化了 Java 应用的开发与维护。无论是传统的 SSM 架构,还是当下流行的 Spring Boot、Spring Cloud 微服务体系,其底层都构建在 Spring Framework 之上。
本文将深入剖析 Spring Framework 的四大核心机制:IoC 容器与 Bean 生命周期 、AOP 动态代理 、事件驱动模型 ,以及面试高频考点------循环依赖的解决原理。通过源码级别的分析,帮助读者真正理解 Spring 的设计哲学,而不仅仅是停留在 API 的使用层面。
2. 核心概念:IoC 与 AOP
2.1 控制反转(IoC)
控制反转(Inversion of Control) 是一种设计原则,它将对象的创建、装配和管理的控制权从程序员手中转移到容器(Spring IoC Container)手中。传统开发中,我们通过 new 关键字主动创建对象并维护依赖关系;而在 Spring 中,我们只需声明依赖,容器负责在合适的时机创建 Bean 并注入依赖。
java
// 传统方式:主动创建
public class UserService {
private UserDao userDao = new UserDao();
}
// Spring 方式:声明式依赖注入
@Service
public class UserService {
@Autowired
private UserDao userDao;
}
2.2 面向切面编程(AOP)
面向切面编程(Aspect Oriented Programming) 允许我们将日志记录、事务管理、权限校验等横切关注点(Cross-cutting Concerns)从业务逻辑中剥离出来,通过动态代理在运行时织入。Spring AOP 默认基于 JDK 动态代理(接口代理)或 CGLIB(子类代理)实现。
java
@Aspect
@Component
public class LogAspect {
@Around("execution(* com.example.service.*.*(..))")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object result = joinPoint.proceed();
System.out.println(joinPoint.getSignature().getName() + " 耗时: " + (System.currentTimeMillis() - start) + "ms");
return result;
}
}
3. IoC 容器与 Bean 生命周期源码解析
3.1 容器启动核心流程
Spring IoC 容器的核心入口是 ApplicationContext,其最经典的实现是 ClassPathXmlApplicationContext(XML 时代)和 AnnotationConfigApplicationContext(注解时代)。容器启动的核心方法为 refresh(),它定义了整个容器的初始化骨架:
java
// AbstractApplicationContext.refresh()
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 1. 准备刷新上下文
prepareRefresh();
// 2. 获取 BeanFactory(默认 DefaultListableBeanFactory)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3. 准备 BeanFactory,设置类加载器、SpEL 解析器等
prepareBeanFactory(beanFactory);
// 4. 子类扩展点(如 Web 容器注册 Scope)
postProcessBeanFactory(beanFactory);
// 5. 执行 BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// 6. 注册 BeanPostProcessor
registerBeanPostProcessors(beanFactory);
// 7. 初始化消息源(国际化)
initMessageSource();
// 8. 初始化事件广播器
initApplicationEventMulticaster();
// 9. 子类扩展点(如 Spring MVC 的 onRefresh)
onRefresh();
// 10. 注册监听器
registerListeners();
// 11. 实例化所有非懒加载的单例 Bean
finishBeanFactoryInitialization(beanFactory);
// 12. 完成刷新,发布 ContextRefreshedEvent
finishRefresh();
}
}
3.2 Bean 的完整生命周期
一个 Bean 从创建到销毁,会经历一系列回调。理解这一过程对排查问题至关重要:

3.3 三级缓存与循环依赖解决
循环依赖 是指 A 依赖 B,B 又依赖 A 的情况。Spring 通过三级缓存 机制解决了单例 Bean 的循环依赖问题。三级缓存定义在 DefaultSingletonBeanRegistry 中:
java
// 一级缓存:成品 Bean(完全初始化好的单例)
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 二级缓存:早期暴露的 Bean(已实例化但未完成属性填充)
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
// 三级缓存:ObjectFactory 工厂(用于生成早期引用,支持 AOP 提前代理)
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
解决流程(以 A 依赖 B、B 依赖 A 为例):
- 创建 A,实例化后将其
ObjectFactory放入三级缓存singletonFactories; - 填充 A 的属性时发现需要 B,于是去创建 B;
- B 实例化后同样放入三级缓存,填充属性时发现需要 A;
- B 从三级缓存中拿到 A 的
ObjectFactory,调用getObject()得到 A 的早期引用(若 A 需要 AOP,则在此生成代理对象),放入二级缓存,并注入给 B; - B 完成初始化,放入一级缓存;
- 回到 A,从一级缓存拿到 B 并注入,A 完成初始化,放入一级缓存。
java
// DefaultSingletonBeanRegistry.getSingleton() 核心逻辑
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
synchronized (this.singletonObjects) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
注意 :三级缓存只能解决单例 + 非构造器注入 的循环依赖。构造器注入的循环依赖无法解决,会抛出
BeanCurrentlyInCreationException;原型(Prototype)作用域的 Bean 也不支持循环依赖。
4. AOP 动态代理原理
4.1 代理方式选择
Spring AOP 在 DefaultAopProxyFactory 中决定使用 JDK 动态代理还是 CGLIB:
- JDK 动态代理 :目标类实现了接口时默认使用,基于
java.lang.reflect.Proxy,只能代理接口方法; - CGLIB 代理:目标类未实现接口时使用,通过生成目标类的子类来代理,可代理类方法(final 方法除外)。
java
// DefaultAopProxyFactory.createAopProxy()
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
} else {
return new JdkDynamicAopProxy(config);
}
}
4.2 代理创建时机
AOP 代理的创建发生在 Bean 生命周期的**「初始化后」**阶段,即 AbstractAutoProxyCreator.postProcessAfterInitialization() 方法中。这也是为什么三级缓存中需要 ObjectFactory------当循环依赖发生时,AOP 代理需要在 Bean 完全初始化之前就暴露出去。
java
// AbstractAutoProxyCreator.postProcessAfterInitialization()
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
5. 事件驱动模型
Spring 的事件驱动模型基于观察者模式,由事件(ApplicationEvent) 、发布者(ApplicationEventPublisher) 和监听器(ApplicationListener) 三部分组成。它实现了业务模块之间的解耦。
5.1 自定义事件与监听
java
// 1. 定义事件
public class OrderCreatedEvent extends ApplicationEvent {
private final Long orderId;
public OrderCreatedEvent(Object source, Long orderId) {
super(source);
this.orderId = orderId;
}
public Long getOrderId() { return orderId; }
}
// 2. 定义监听器(方式一:实现接口)
@Component
public class OrderEventListener implements ApplicationListener<OrderCreatedEvent> {
@Override
public void onApplicationEvent(OrderCreatedEvent event) {
System.out.println("收到订单创建事件,订单ID: " + event.getOrderId());
// 发送短信、更新库存等
}
}
// 3. 定义监听器(方式二:@EventListener 注解,推荐)
@Component
public class OrderEventAnnotationListener {
@EventListener
@Async // 配合 @EnableAsync 实现异步监听
public void handleOrderCreated(OrderCreatedEvent event) {
System.out.println("异步处理订单事件: " + event.getOrderId());
}
}
// 4. 发布事件
@Service
public class OrderService {
@Autowired
private ApplicationEventPublisher publisher;
public void createOrder(Long orderId) {
// 业务逻辑...
publisher.publishEvent(new OrderCreatedEvent(this, orderId));
}
}
5.2 事件广播机制源码
事件发布的核心是 SimpleApplicationEventMulticaster,它在 refresh() 的 initApplicationEventMulticaster() 阶段被创建。发布事件时,广播器会根据事件类型匹配所有监听器并逐个调用:
java
// SimpleApplicationEventMulticaster.multicastEvent()
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor = getTaskExecutor();
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
// 异步执行
executor.execute(() -> invokeListener(listener, event));
} else {
// 同步执行
invokeListener(listener, event);
}
}
}
6. 常见面试题与总结
6.1 高频面试题
- Spring 如何解决循环依赖? 通过三级缓存,在 Bean 实例化后提前暴露
ObjectFactory,使依赖方能够获取到早期引用。仅支持单例 + setter/字段注入。 - 为什么需要三级缓存,二级不够吗? 二级缓存可以解决循环依赖,但无法处理「循环依赖 + AOP」的场景。三级缓存中的
ObjectFactory允许在 Bean 未完全初始化时就生成 AOP 代理,保证代理对象的唯一性。 - Spring AOP 和 AspectJ 的区别? Spring AOP 是运行时增强(基于代理),只能作用于 Spring 管理的 Bean;AspectJ 是编译期/加载期织入,功能更强大但配置复杂。
@Transactional失效的场景有哪些? 方法非 public、同类内部调用(this调用绕过代理)、异常被捕获未抛出、方法非 final(CGLIB 无法代理 final 方法)等。
6.2 总结
Spring Framework 之所以成为 Java 生态的基石,在于其非侵入式的设计理念:
- IoC 容器 统一管理对象生命周期,降低耦合;
- AOP 将横切逻辑模块化,提升代码复用;
- 事件驱动 实现模块间异步解耦;
- 三级缓存 巧妙解决循环依赖,体现了对 Bean 生命周期的精细控制。
理解这些底层原理,不仅能帮助我们写出更健壮的代码,更是深入 Spring Boot 自动装配、Spring Cloud 微服务治理的必经之路。建议读者结合源码(spring-beans、spring-context、spring-aop 模块)动手调试,才能真正做到融会贯通。