spring ioc容器启动核心是refresh()方法,它按12步完成:准备刷新→获取beanfactory→注册beandefinition→执行beanfactorypostprocessor→注册beanpostprocessor→预实例化非懒加载单例bean,实现从配置到对象的全生命周期管理。

面试中讲清楚 Spring IoC 容器的底层源码,关键不是堆砌类名和方法,而是用一条主线串起“容器怎么启动→Bean 怎么定义→依赖怎么注入→对象怎么活过来”,同时突出设计意图和关键细节。下面分四个核心环节展开,每部分都紧扣面试高频点。
一、容器启动入口:refresh() 是整个流程的总开关
无论用 AnnotationConfigApplicationContext 还是 ClassPathXmlApplicationContext,最终都会调用父类 AbstractApplicationContext.refresh()。这个方法是 12 步标准流程的中枢,面试时只需聚焦最核心的几步:
- obtainFreshBeanFactory():创建或刷新 BeanFactory(通常是 DefaultListableBeanFactory),这是所有 Bean 存储和操作的底层载体
- invokeBeanFactoryPostProcessors():执行 BeanFactoryPostProcessor(如 ConfigurationClassPostProcessor),它负责把 @Configuration 类、@Component 扫描结果解析成 BeanDefinition 并注册进工厂
- finishBeanFactoryInitialization():真正触发非懒加载单例 Bean 的实例化、属性填充、初始化——也就是你写的 @PostConstruct、InitializingBean.afterPropertiesSet() 都在这里发生
二、Bean 的“蓝图”:BeanDefinition 是一切配置的源头
Spring 不直接操作 Java 对象,而是先用 BeanDefinition 描述它。它就像一张施工图,包含:
- 类全名(getBeanClassName())、作用域(singleton 或 prototype)
- 是否懒加载、是否抽象、是否允许循环依赖
- 构造器参数值(ConstructorArgumentValues)、属性值(MutablePropertyValues,对应 @Value 和 @Autowired 字段)
- 初始化/销毁方法名、是否是工厂方法(@Bean 方法会生成 ConfigurationClassBeanDefinition)
面试时可强调:XML 中的
三、依赖注入靠反射,但时机和方式有讲究
DI 不是简单地 set 属性。Spring 在 populateBean() 阶段完成注入,具体策略由 InstantiationStrategy 和 AutowiredAnnotationBeanPostProcessor 协同完成:
- 字段注入:找到所有加了 @Autowired 的 Field,通过 ReflectionUtils.setField() 赋值
- 构造器注入:在实例化阶段就通过反射调用匹配的构造器,传入已准备好的依赖对象
- Setter 注入:调用对应的 Method.invoke()
注意:循环依赖能解决,是因为 Spring 提前暴露“半成品”对象(三级缓存中的 ObjectFactory),但仅对 singleton + setter/字段注入有效;构造器注入的循环依赖会直接报错。
四、生命周期管理:从 new 到 destroy 全链路可控
一个 Bean 的完整生命周期,面试官常考节点顺序。以 singleton 为例:
- 实例化(instantiateBean())→ 属性填充(populateBean())→ 初始化前(applyBeanPostProcessorsBeforeInitialization())
- 调用 @PostConstruct → afterPropertiesSet() → 自定义 init-method
- 初始化后(applyBeanPostProcessorsAfterInitialization()),AOP 代理就在这步生成
- 容器关闭时,按相反顺序执行销毁逻辑
其中 BeanPostProcessor 是扩展关键点:它能在初始化前后插入自定义逻辑,比如日志增强、属性校验、甚至替换原始 bean 实例(返回新对象)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











