深度解析Spring IOC容器工作机制
控制反转(IOC,Inversion of Control)是Spring框架的核心设计理念,它深刻影响了Java企业级应用的开发方式。
IOC与DI的概念解析
控制权的转移:传统开发模式下,对象通过new关键字主动创建依赖对象,这种方式导致对象之间高度耦合。IOC容器接管了对象的创建权,控制权从应用代码转移到容器。
依赖注入的实现:依赖注入(DI,Dependency Injection)是IOC思想的具体实现方式。容器在运行时动态地将依赖对象注入到目标对象中,实现解耦。

在Spring框架中,由IOC容器管理的对象称为Spring Bean。
Spring IOC容器类型
Spring框架提供了两种类型的IOC容器:
- BeanFactory:基础容器接口,提供配置框架和基本功能,支持管理任意类型的对象
- ApplicationContext:BeanFactory的子接口,在基础上增强了消息资源处理(国际化支持)、事件发布机制、资源访问等企业级功能

IOC容器初始化流程
以XML配置文件为例,分析Spring IOC容器的初始化过程。定义一个简单的Bean配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dataService" class="com.example.service.DataService" scope="singleton">
</bean>
</beans>
启动容器的典型代码:
public class ApplicationBootstrap {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("dataService.xml");
DataService service = ctx.getBean("dataService", DataService.class);
service.process();
}
}
通过ClassPathXmlApplicationContext构造方法创建容器,其核心逻辑如下:
public ClassPathXmlApplicationContext(
String[] configPaths, boolean shouldRefresh, ApplicationContext parentCtx)
throws BeansException {
super(parentCtx);
setConfigLocations(configPaths);
if (shouldRefresh) {
refresh();
}
}
核心方法refresh()完成了容器的完整初始化:
public void refresh() throws BeansException, IllegalStateException {
synchronized (this startupMonitor) {
StartupStep refreshStep = this.appStartup.start("spring.context.refresh");
// 第一步:准备容器刷新
prepareRefresh();
// 第二步:获取新鲜的BeanFactory
ConfigurableListableBeanFactory factory = obtainFreshBeanFactory();
// 第三步:配置BeanFactory
prepareBeanFactory(factory);
try {
// 第四步:子类扩展处理
postProcessBeanFactory(factory);
StartupStep postProcessStep = this.appStartup.start("spring.context.beans.post-process");
// 第五步:执行BeanFactory后置处理器
invokeBeanFactoryPostProcessors(factory);
// 第六步:注册Bean后置处理器
registerBeanPostProcessors(factory);
postProcessStep.end();
// 第七步:初始化消息源
initMessageSource();
// 第八步:初始化事件广播器
initApplicationEventMulticaster();
// 第九步:刷新特定Bean
onRefresh();
// 第十步:注册监听器
registerListeners();
// 第十一步:实例化非延迟加载的Bean
finishBeanFactoryInitialization(factory);
// 第十二步:完成刷新
finishRefresh();
}
catch (BeansException e) {
destroyBeans();
cancelRefresh(e);
throw e;
}
finally {
resetCommonCaches();
refreshStep.end();
}
}
}
BeanFactory初始化详解
obtainFreshBeanFactory()方法负责BeanFactory的创建:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory factory = createBeanFactory();
factory.setSerializationId(getId());
customizeBeanFactory(factory);
loadBeanDefinitions(factory);
this.beanFactory = factory;
}
catch (IOException e) {
throw new ApplicationContextException("解析Bean定义文件失败", e);
}
}
资源定位与加载
XmlBeanDefinitionReader负责加载XML配置:
protected void loadBeanDefinitions(DefaultListableBeanFactory factory)
throws BeansException, IOException {
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.setEnvironment(getEnvironment());
reader.setResourceLoader(this);
reader.setEntityResolver(new ResourceEntityResolver(this));
initBeanDefinitionReader(reader);
loadBeanDefinitions(reader);
}
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader)
throws BeansException, IOException {
Resource[] resources = getConfigResources();
if (resources != null) {
reader.loadBeanDefinitions(resources);
}
String[] locations = getConfigLocations();
if (locations != null) {
reader.loadBeanDefinitions(locations);
}
}
Bean定义解析与注册
解析XML并生成Document对象后,BeanDefinitionDocumentReader负责解析:
public int registerBeanDefinitions(Document doc, Resource resource)
throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
int countBefore = getRegistry().getBeanDefinitionCount();
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
protected void doRegisterBeanDefinitions(Element root) {
preProcessXml(root);
parseBeanDefinitions(root, this.delegate);
postProcessXml(root);
}
protected void processBeanDefinition(Element element, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder holder = delegate.parseBeanDefinitionElement(element);
if (holder != null) {
holder = delegate.decorateBeanDefinitionIfRequired(element, holder);
try {
BeanDefinitionReaderUtils.registerBeanDefinition(holder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException e) {
getReaderContext().error("注册Bean定义失败: " + holder.getBeanName(), element, e);
}
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(holder));
}
}
最终通过DefaultListableBeanFactory的registerBeanDefinition方法将BeanDefinition保存到容器中:
public void registerBeanDefinition(String beanName, BeanDefinition bd)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean名称不能为空");
Assert.notNull(bd, "BeanDefinition不能为空");
if (bd instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) bd).validate();
}
catch (BeanDefinitionValidationException e) {
throw new BeanDefinitionStoreException("Bean定义校验失败", e);
}
}
BeanDefinition existingBd = this.beanDefinitionMap.get(beanName);
if (existingBd != null) {
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, bd, existingBd);
}
this.beanDefinitionMap.put(beanName, bd);
}
else {
if (hasBeanCreationStarted()) {
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, bd);
this.beanDefinitionNames.add(beanName);
}
}
else {
this.beanDefinitionMap.put(beanName, bd);
this.beanDefinitionNames.add(beanName);
}
}
if (existingBd != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
IOC容器初始化总结
Spring IOC容器初始化包含三个核心环节:
- 资源定位:通过ResourceLoader定位配置文件
- Bean定义加载:通过BeanDefinitionReader解析资源生成BeanDefinition
- Bean注册:通过BeanDefinitionRegistry将BeanDefinition存入ConcurrentHashMap
IOC容器通过ConcurrentHashMap保存所有BeanDefinition信息,实现了Bean对象的统一管理,有效降低了应用组件之间的耦合度。