[面试题] AnnotationConfigApplicationContext 的 register 和 refresh 做了什么?
📖 版块 A:知识讲解版 (温故知新)
-
register的作用:- 把配置类注册到容器体系里。
- 通常是将传入的配置类先转换成对应的 BeanDefinition。
- 此时更多是“登记”,还没有完成整个容器启动。
-
refresh的作用:- 是 Spring 容器真正启动的核心总开关。
- 它会驱动整个 ApplicationContext 从“只有定义”走向“真正可用”。
-
refresh里最关键的几步:- 准备 BeanFactory。
- 执行
BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor。 - 注册
BeanPostProcessor。 - 初始化事件广播器、消息源等基础设施。
- 实例化所有非懒加载单例 Bean。
- 发布容器刷新完成事件。
-
一个典型角色:
ConfigurationClassPostProcessor会在这个阶段解析@Configuration、@ComponentScan、@Bean、@Import等注解,并继续向容器中补充 BeanDefinition。
🎤 版块 B:面试实战版 (高手逐字稿)
Q:AnnotationConfigApplicationContext 的 register 和 refresh 做了什么?
💬 高手逐字稿:
如果我们用的是 AnnotationConfigApplicationContext,那容器启动过程里最核心的两个动作就是 register 和 refresh。
register 本质上是在做一件事:把配置类先注册进容器。你可以把它理解成“先把候选者名单录进去”。这一步主要还是围绕 BeanDefinition 展开,它会把配置类本身转换成定义信息,让容器后面有东西可处理。
真正的大头在 refresh。refresh 可以说是 Spring ApplicationContext 最核心的方法,几乎整个容器启动流程都串在这里面。它不是简单地“刷新一下”,而是把 IOC 容器从半成品推到可用状态。
我一般会把 refresh 里的关键动作概括成六步:
- 先准备好 BeanFactory;
- 执行各种 BeanFactory 级别的后置处理器;
- 注册 BeanPostProcessor;
- 初始化容器级基础设施,比如事件广播器;
- 实例化所有非懒加载单例 Bean;
- 最后发布容器刷新完成事件。
这里最值得展开的细节,是 ConfigurationClassPostProcessor。它在 refresh 过程中会被执行,然后真正去解析 @Configuration、@ComponentScan、@Bean、@Import 这些注解,并不断往容器里追加新的 BeanDefinition。也就是说,Spring 的注解驱动能力,其实就是在这个阶段被正式跑起来的。
所以一句话总结:register 是把配置先报上来,refresh 是把整个容器真正跑起来。
最后更新于: