在深入源码之前,必须先澄清一个常见的误解:IoC容器不是那个单例池Map。很多人认为容器就是个ConcurrentHashMap,把Bean创建出来往里面一放就完事了——这种理解过于简化。
准确地说,IoC容器是一组组件和协作流程的集合,包括BeanFactory、单例池(singletonObjects)、BeanPostProcessor、BeanDefinitionRegistry等,以及它们之间的复杂交互。容器管理Bean的完整生命周期,而不仅仅是存储Bean。
核心接口体系
BeanFactory(顶级容器接口)↑ApplicationContext(高级容器接口,继承BeanFactory)↑├── ClassPathXmlApplicationContext(XML配置启动)├── FileSystemXmlApplicationContext(文件系统路径启动)└── AnnotationConfigApplicationContext(纯注解模式启动)
BeanFactory定义了容器的基础规范,ApplicationContext在此基础上增加了国际化、事件传播、资源访问等能力。
二、容器启动的“总指挥”:refresh()方法
所有IoC容器的启动,无论XML还是注解方式,最终都会汇聚到AbstractApplicationContext.refresh()方法。这是整个容器初始化的入口和总控。
@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 1. 刷新前的预处理prepareRefresh();// 2. 获取并刷新BeanFactoryConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// 3. BeanFactory预准备工作prepareBeanFactory(beanFactory);try {// 4. 空方法,留给子类扩展postProcessBeanFactory(beanFactory);// 5. 调用BeanFactoryPostProcessorinvokeBeanFactoryPostProcessors(beanFactory);// 6. 注册BeanPostProcessorregisterBeanPostProcessors(beanFactory);// 7. 初始化消息源initMessageSource();// 8. 初始化事件广播器initApplicationEventMulticaster();// 9. 空方法,子类扩展onRefresh();// 10. 注册事件监听器registerListeners();// 11. 初始化所有非懒加载单例BeanfinishBeanFactoryInitialization(beanFactory);// 12. 完成刷新,发布事件finishRefresh();} catch (BeansException ex) {// 异常处理:销毁已创建的BeandestroyBeans();cancelRefresh(ex);throw ex;} finally {resetCommonCaches();}}}
下面逐一拆解每个步骤的核心逻辑。
三、refresh() 12步源码深度拆解
第1步:prepareRefresh() — 刷新前的预热
这一步做的是“准备工作”性质的初始化:
protected void prepareRefresh() {// 设置启动时间this.startupDate = System.currentTimeMillis();// 设置容器状态:活跃中,未关闭this.closed.set(false);this.active.set(true);// 初始化属性源(空实现,留给子类扩展)initPropertySources();// 校验必要属性是否存在getEnvironment().validateRequiredProperties();// 准备早期事件监听器集合if (this.earlyApplicationListeners == null) {this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);}// 准备早期事件集合this.earlyApplicationEvents = new LinkedHashSet<>();}
关键扩展点:子类可以重写initPropertySources()来添加自定义配置来源(如从网络、数据库加载配置),或通过setRequiredProperties()指定必须存在的属性键,缺失会导致启动失败。
第2步:obtainFreshBeanFactory() — 获取/创建BeanFactory
这一步的核心是获取一个“干净”的BeanFactory实例:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {// 刷新BeanFactory:如果已有则销毁,重新创建refreshBeanFactory();return getBeanFactory();}
对于ClassPathXmlApplicationContext,这里会:
本质:这一步完成了Bean定义的加载和注册,但Bean实例还未创建。
第3步:prepareBeanFactory() — BeanFactory的“装修”
刚创建好的BeanFactory是个“毛坯房”,需要添置一些基础设施:
protectedvoidprepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// 设置类加载器beanFactory.setBeanClassLoader(getClassLoader());// 设置表达式解析器(支持#{...})beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());// 添加属性编辑器注册器beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar());// 添加BeanPostProcessor:ApplicationContextAwareProcessor// 负责处理各种Aware接口的回调beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));// 忽略以下接口的自动装配beanFactory.ignoreDependencyInterface(EnvironmentAware.class);beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);// ...等// 注册一些特殊的依赖beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);beanFactory.registerResolvableDependency(ResourceLoader.class, this);beanFactory.registerResolvableDependency(ApplicationContext.class, this);// 注册一个空的单例Bean用于占位beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());}
这一步让BeanFactory具备了处理Aware回调、表达式解析等能力。
第4步:postProcessBeanFactory() — 子类扩展点
这是一个空方法,留给子类在BeanFactory准备完成后、BeanPostProcessor注册之前进行定制扩展。例如AnnotationConfigWebApplicationContext会在这里注册一些Web相关的组件。
第5步:invokeBeanFactoryPostProcessors() — 执行BeanFactory后置处理器
这是容器启动中第一个重量级阶段:调用所有BeanFactoryPostProcessor。
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {// 委托给专门的代理类处理PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());}
BeanFactoryPostProcessor的作用:在所有Bean实例化之前,修改BeanDefinition元数据。例如修改作用域、添加属性、甚至新增或删除Bean定义。
执行顺序:
特别注意:BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口,它允许直接操作BeanDefinitionRegistry(增删改Bean定义),执行优先级更高。
第6步:registerBeanPostProcessors() — 注册Bean后置处理器
这一步从容器中找出所有BeanPostProcessor类型的Bean,将它们注册到BeanFactory的beanPostProcessors列表中。
publicstaticvoidregisterBeanPostProcessors(ConfigurableListableBeanFactory beanFactory,AbstractApplicationContext applicationContext) {// 找出所有BeanPostProcessor类型的Bean名称String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);// 按优先级分类List priorityOrderedPostProcessors = new ArrayList<>();List orderedPostProcessorNames = new ArrayList<>();List nonOrderedPostProcessorNames = new ArrayList<>();for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {// 先实例化优先级最高的BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);priorityOrderedPostProcessors.add(pp);} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);} else {nonOrderedPostProcessorNames.add(ppName);}}// 按优先级顺序注册sortAndRegister(priorityOrderedPostProcessors, beanFactory);// 注册Ordered的sortAndRegister(orderedPostProcessors, beanFactory);// 注册普通的sortAndRegister(nonOrderedPostProcessors, beanFactory);// 最后注册一个特殊的:ApplicationListenerDetector// 负责检测并注册ApplicationListenerbeanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));}
关键区分:BeanFactoryPostProcessor操作Bean定义(元数据层面),BeanPostProcessor操作Bean实例(对象层面),两者执行时机完全不同。
第7步:initMessageSource() — 初始化国际化消息源
查找容器中是否有名为messageSource的Bean,如果有则使用;否则创建一个空的DelegatingMessageSource作为默认实现,保证getMessage()方法调用不会报错。
第8步:initApplicationEventMulticaster() — 初始化事件广播器
查找容器中是否有名为applicationEventMulticaster的Bean,如果有则使用;否则创建一个SimpleApplicationEventMulticaster作为默认实现。这个广播器负责将容器事件分发给所有注册的监听器。
第9步:onRefresh() — 子类扩展点(Web容器特有)
又是一个空方法,留给子类扩展。在Web环境中,GenericWebApplicationContext会在此处创建Web相关的资源。
第10步:registerListeners() — 注册事件监听器
将容器中所有实现了ApplicationListener接口的Bean注册到事件广播器。同时,如果之前有早期事件(在广播器初始化之前产生的事件),现在会被广播出去。
第11步:finishBeanFactoryInitialization() — 实例化所有非懒加载单例Bean
这是容器启动中最核心、最重量级的步骤。完成所有准备工作后,Spring终于开始创建Bean实例了。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// 1. 初始化类型转换服务beanFactory.setConversionService(...);// 2. 注册默认的嵌入值解析器beanFactory.setEmbeddedValueResolver(...);// 3. 提前初始化LoadTimeWeaverAware(AOP相关)beanFactory.getBean(LOAD_TIME_WEAVER_BEAN_NAME);// 4. 冻结所有BeanDefinition:后续不再允许修改beanFactory.freezeConfiguration();// 5. 实例化所有非懒加载单例BeanbeanFactory.preInstantiateSingletons();}
preInstantiateSingletons()方法会遍历所有BeanDefinition,对于非抽象、非懒加载、单例的Bean,逐个调用getBean()触发实例化。
Bean的完整创建流程(在getBean() → doGetBean() → createBean() → doCreateBean()中完成):
实例化(调用构造函数)↓暴露早期引用到三级缓存(解决循环依赖)↓属性填充(populateBean)- 依赖注入↓Aware接口回调↓BeanPostProcessor.postProcessBeforeInitialization↓执行初始化方法(@PostConstruct / afterPropertiesSet / init-method)↓BeanPostProcessor.postProcessAfterInitialization↓注册到一级缓存(单例池)
循环依赖的解决机制:Spring通过三级缓存来解决单例Bean的循环依赖:
public class DefaultSingletonBeanRegistry {// 一级缓存:完全初始化好的单例Beanprivate final Map singletonObjects = new ConcurrentHashMap<>(256);// 二级缓存:早期暴露的Bean引用(尚未填充属性)private final Map earlySingletonObjects = new HashMap<>(16);// 三级缓存:ObjectFactory,用于生成早期引用(可代理)private final Map> singletonFactories = new HashMap<>(16);}
当A依赖B、B依赖A时:
第12步:finishRefresh() — 完成刷新,发布事件
最后一步,容器启动完毕:
protectedvoidfinishRefresh() {// 1. 清理资源缓存initLifecycleProcessor();getLifecycleProcessor().onRefresh();// 2. 发布ContextRefreshedEvent事件publishEvent(new ContextRefreshedEvent(this));// 3. 注册MBean(JMX相关)registerLiveBeans();}
此时容器已完全就绪,可以对外提供服务了。
四、完整流程速查表
五、写在最后:理解源码的核心价值
理解Spring IoC容器源码,最重要的不是记住每一行代码,而是把握设计思想和扩展点:
掌握了这套流程,当遇到Bean初始化顺序异常、循环依赖报错、扩展点执行不符合预期等问题时,你就不再是盲目搜索,而是可以精准定位到源码的某个环节进行分析。
夜雨聆风