Spring源码追问入口图#
一句话答案#
Spring 源码追问三条主线:Bean 生命周期(实例化→属性注入→初始化→销毁,关键类 BeanFactory/BeanPostProcessor)、AOP 代理生成(AbstractAutoProxyCreator 在 BeanPostProcessor 中织入)、事务拦截器(TransactionInterceptor 通过 AOP 拦截 @Transactional 方法调用 PlatformTransactionManager)。
核心要点
一、Bean 生命周期调用链
1. BeanDefinition 加载 (XML/注解/Java Config)
└─ ConfigurationClassPostProcessor 解析 @Configuration/@ComponentScan/@Import
2. BeanFactory 准备
└─ registerBeanPostProcessors() 注册所有 BPP
3. 实例化 (createBeanInstance)
└─ 构造器注入 or 无参构造 + 反射
└─ 关键:此时 bean 是"早期对象",还没注入属性
4. 属性注入 (populateBean)
└─ @Autowired → AutowiredAnnotationBeanPostProcessor
└─ @Value → PropertySourcesPlaceholderConfigurer
└─ 循环依赖在这里通过三级缓存解决
5. 初始化 (initializeBean)
├─ BeanPostProcessor.postProcessBeforeInitialization()
│ └─ @PostConstruct → CommonAnnotationBeanPostProcessor
├─ InitializingBean.afterPropertiesSet()
├─ 自定义 init-method
└─ BeanPostProcessor.postProcessAfterInitialization()
└─ AOP 代理在这里创建!→ AbstractAutoProxyCreator
6. 使用 Bean
7. 销毁
├─ @PreDestroy
├─ DisposableBean.destroy()
└─ 自定义 destroy-methodplaintext核心类速查:
| 类 | 职责 |
|---|---|
| DefaultListableBeanFactory | IoC 容器核心,管理 BeanDefinition 和 Bean 实例 |
| AbstractAutowireCapableBeanFactory | createBean/doCreateBean 入口 |
| AutowiredAnnotationBeanPostProcessor | 处理 @Autowired/@Value 注入 |
| CommonAnnotationBeanPostProcessor | 处理 @PostConstruct/@PreDestroy/@Resource |
| ConfigurationClassPostProcessor | 解析 @Configuration 类 |
| AbstractAutoProxyCreator | AOP 代理创建入口 |
二、AOP 代理生成链路
@EnableAspectJAutoProxy
→ 注册 AnnotationAwareAspectJAutoProxyCreator (是一个 BeanPostProcessor)
→ postProcessAfterInitialization() 中:
1. getAdvicesAndAdvisorsForBean() 找匹配的切面
2. 有匹配 → createProxy()
├─ 目标类实现了接口 → JDK 动态代理
└─ 目标类未实现接口 → CGLIB 代理
3. 返回代理对象替换原始 BeanplaintextJDK vs CGLIB 代理:
| 维度 | JDK 动态代理 | CGLIB |
|---|---|---|
| 条件 | 目标类实现了接口 | 无接口要求 |
| 原理 | Proxy.newProxyInstance + InvocationHandler | 生成子类 + MethodInterceptor |
| 限制 | 只能代理接口方法 | 不能代理 final 类/方法 |
| Spring Boot 默认 | 2.0 前默认 JDK | 2.0+ 默认 CGLIB (proxyTargetClass=true) |
三、事务拦截器链路
@Transactional 方法被调用
→ CGLIB/JDK 代理拦截
→ TransactionInterceptor.invoke()
→ TransactionAspectSupport.invokeWithinTransaction()
1. getTransaction() → 从 PlatformTransactionManager 获取/创建事务
└─ DataSourceTransactionManager → 从 DataSource 获取 Connection
└─ 设置 autocommit=false
└─ 绑定 Connection 到 ThreadLocal (TransactionSynchronizationManager)
2. 执行目标方法
3. 成功 → commitTransactionAfterReturning() → commit
4. 异常 → completeTransactionAfterThrowing()
└─ 检查 rollbackFor/noRollbackFor 配置
└─ 匹配 → rollback
└─ 不匹配 → commit(这是事务失效的常见原因!)plaintext事务失效场景→源码根因:
| 场景 | 源码根因 |
|---|---|
| 同类方法调用 | 不经过代理,直接 this 调用不触发 TransactionInterceptor |
| private/final 方法 | CGLIB 无法生成子类覆盖方法 |
| 异常被 catch | completeTransactionAfterThrowing 没收到异常 |
| 抛 checked 异常 | 默认只回滚 RuntimeException/Error |
| 非 Spring 管理的类 | 没有代理对象,不走拦截器 |
四、循环依赖三级缓存→源码
// DefaultSingletonBeanRegistry 中:
Map<String, Object> singletonObjects; // 一级:成品 Bean
Map<String, Object> earlySingletonObjects; // 二级:早期引用(可能是代理)
Map<String, ObjectFactory<?>> singletonFactories; // 三级:创建早期引用的工厂
// getSingleton() 查找顺序:一级 → 二级 → 三级(调用工厂方法后放入二级)
// 三级缓存存工厂而非对象:为了在需要时才决定是否返回代理对象(AOP场景)java为什么不能解决构造器注入循环依赖?→ 三级缓存是在实例化后属性注入前放入的,构造器注入时实例都没创建完。
面试回答(2分钟版)
Spring 源码我准备了三条主线。第一条是 Bean 生命周期:从 BeanDefinition 加载开始,经过实例化、属性注入、初始化三个阶段。属性注入由 AutowiredAnnotationBeanPostProcessor 处理 @Autowired,初始化阶段的 postProcessAfterInitialization 是 AOP 代理创建的时机。第二条是 AOP 代理生成:AnnotationAwareAspectJAutoProxyCreator 作为 BeanPostProcessor,在初始化后检查是否有匹配的切面,有就创建代理。Spring Boot 2.0 后默认用 CGLIB 生成子类代理。第三条是事务拦截器:@Transactional 通过 AOP 织入 TransactionInterceptor,调用时先从 DataSourceTransactionManager 获取连接设为非自动提交,绑定到 ThreadLocal,方法成功就 commit,异常就检查 rollbackFor 配置决定是否回滚。这也解释了事务失效场景:同类方法调用不走代理所以不触发拦截器,checked 异常默认不回滚因为只匹配 RuntimeException。循环依赖靠三级缓存解决,三级存的是 ObjectFactory 而非对象,是为了延迟决定是否返回代理。
追问与易错
追问方向:
- “BeanFactoryPostProcessor 和 BeanPostProcessor 区别?”→ BFPP 在 Bean 实例化之前执行,修改 BeanDefinition 元数据(如 PropertyPlaceholderConfigurer 替换占位符);BPP 在 Bean 初始化前后执行,修改或替换 Bean 实例(如 AOP 代理创建)
- “为什么三级缓存不能合并成两级?”→ 如果只用两级直接存代理对象,则所有 Bean 都要提前创建代理,违反 AOP 只在需要时(有循环依赖引用时)才创建代理的原则;三级缓存存 ObjectFactory 实现延迟代理创建
- “@Transactional(propagation=REQUIRES_NEW) 怎么实现的?”→ 挂起当前事务(将当前连接从 ThreadLocal 解绑保存到 SuspendedResourcesHolder)、从连接池获取新连接创建独立事务、执行完独立 commit/rollback、最后恢复挂起的外层事务
- “Spring Boot 自动配置原理?”→ @EnableAutoConfiguration 通过 AutoConfigurationImportSelector 加载候选配置类(Boot 3 用 AutoConfiguration.imports),@Conditional 系列注解条件过滤,按需注册 Bean
易错点:
- ❌ “AOP 在属性注入时创建代理”——是在初始化的 postProcessAfterInitialization 中
- ❌ “三级缓存是为了解决循环依赖”——两级就能解决,三级是为了延迟代理创建
- ❌ “事务失效是因为没有 @Transactional”——更常见的是同类调用/异常被吞/异常类型不对
- ✅ 三条主线记清楚:Bean 生命周期(BPP)、AOP(代理创建时机)、事务(拦截器+回滚规则)