总要再读一次Spring IOC代码吧
参考地址:https://javadoop.com
1.环境准备
java
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.11.RELEASE</version>
</dependency>
然后包被引入:

java
ApplicationContext context = new ClassPathXmlApplicationContext("");

使用具体实现为ClassPathXmlApplicationContext,继承于ApplicationContext,父类引用指向子类。
首先,定义一个接口:
java
public interface MessageService {
String getMessage();
}
定义接口实现类:
java
public class MessageServiceImpl implements MessageService {
public String getMessage() {
return "hello world";
}
}
接下来,我们在 resources 目录新建一个配置文件,文件名随意,通常叫 application.xml 或 application-xxx.xml 就可以了:
xml
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-autowire="byName">
<bean id="messageService" class="com.javadoop.example.MessageServiceImpl"/>
</beans>
这样,我们就可以跑起来了:
java
public class App {
public static void main(String[] args) {
// 用我们的配置文件来启动一个 ApplicationContext
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:application.xml");
System.out.println("context 启动成功");
// 从 context 中取出我们的 Bean,而不是用 new MessageServiceImpl() 这种方式
MessageService messageService = context.getBean(MessageService.class);
// 这句将输出: hello world
System.out.println(messageService.getMessage());
}
}
2.BeanFactory
核心职责:
- 根据 name
- 或根据 type
- 去"取一个 Bean"


1.ListableBeanFactory
ApplicationContext 继承了 ListableBeanFactory,这个 Listable 的意思就是,通过这个接口,我们可以获取多个 Bean,大家看源码会发现,最顶层 BeanFactory 接口的方法都是获取单个 Bean 的。
-
getBeansOfType(...):拿到某个类型的所有 Bean
-
getBeanDefinitionNames():拿到所有 Bean 名称
-
getBeanNamesForType(...):拿到某种类型对应的所有 Bean 名称

Spring 能拿到"某种类型对应的所有 Bean 名称",本质上是因为容器内部保存了全部 Bean 的定义信息,然后在 DefaultListableBeanFactory 中遍历这些定义,逐个做类型匹配,最后把符合条
件的 beanName 收集起来。

java
List<String> result = new ArrayList<>();
for (String beanName : beanDefinitionNames) {
BeanDefinition bd = beanDefinitionMap.get(beanName);
if (bd.isAbstract()) {
continue;
}
if (isTypeMatch(beanName, targetType)) {
result.add(beanName);
}
// 如果是 FactoryBean,还要额外判断工厂本身/产品对象
}
2.HierarchicalBeanFactory
ApplicationContext 继承了 HierarchicalBeanFactory,Hierarchical 单词本身已经能说明问题了,也就是说我们可以在应用中起多个 BeanFactory,然后可以将各个 BeanFactory 设置为父子关系。
需要父子容器,本质上是为了"分层管理"和"复用 Bean",避免所有 Bean 都堆在一个大容器里。
比如一个大型应用里,不同模块关心的 Bean 不一样:
- 父容器放公共 Bean:service、repository、数据源、事务管理器
- 子容器放局部 Bean:某个 Web 模块自己的 controller、视图解析器、处理器映射器
这样做的好处是:
- 公共能力可以复用
- 不同层的职责更清晰
- 子容器可以访问父容器,父容器不用感知子容器
- 方便模块隔离,避免所有 Bean 混在一起
3.启动过程分析
设置了类配置路径之后
其中最重要的是refresh方法
java
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
//初始化 BeanFactory、加载 Bean、注册 Bean 等等,查看类图,这里是个返回是个beanFactory
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
其中: ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
java
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//刷新BeanFactory 删除旧的 创建新的 BeanFactory
this.refreshBeanFactory();
//获取BeanFactory后进行返回
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
if (this.logger.isDebugEnabled()) {
this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
![[Pasted image 20260331111251.png]]
java
protected final void refreshBeanFactory() throws BeansException {
if (this.hasBeanFactory()) {
this.destroyBeans();
this.closeBeanFactory();
}
try {
//ConfigurableListableBeanFactory 只有一个实现类 DefaultListableBeanFactory,而且实现类 DefaultListableBeanFactory 还通过实现右边的 AbstractAutowireCapableBeanFactory 通吃了右路。
DefaultListableBeanFactory beanFactory = this.createBeanFactory();
beanFactory.setSerializationId(this.getId());
this.customizeBeanFactory(beanFactory);
this.loadBeanDefinitions(beanFactory);
synchronized(this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
} catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), ex);
}
}
继续往下,看到:
java
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
this.initBeanDefinitionReader(beanDefinitionReader);
this.loadBeanDefinitions(beanDefinitionReader);
}
Bean加载时,将 xml 文件转换为 Document 对象
java
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
try {
Document doc = this.doLoadDocument(inputSource, resource);
return this.registerBeanDefinitions(doc, resource);
} catch (BeanDefinitionStoreException ex) {
throw ex;
} catch (SAXParseException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
} catch (SAXException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(), "XML document from " + resource + " is invalid", ex);
} catch (ParserConfigurationException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(), "Parser configuration exception parsing XML from " + resource, ex);
} catch (IOException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(), "IOException parsing XML document from " + resource, ex);
} catch (Throwable ex) {
throw new BeanDefinitionStoreException(resource.getDescription(), "Unexpected exception parsing XML document from " + resource, ex);
}
}
转化为DOM树
java
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
this.logger.debug("Loading bean definitions");
Element root = doc.getDocumentElement();
this.doRegisterBeanDefinitions(root);
}
对Bean文件进行解析:
java
String id = ele.getAttribute("id");
String nameAttr = ele.getAttribute("name");
List<String> aliases = new ArrayList();
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, ",; ");
aliases.addAll(Arrays.asList(nameArr));
}
生成beanDefinition
AbstractBeanDefinition beanDefinition = this.parseBeanDefinitionElement(ele, beanName, containingBean);
java
if (beanDefinition != null) {
if (!StringUtils.hasText(beanName)) {
try {
if (containingBean != null) {
beanName = BeanDefinitionReaderUtils.generateBeanName(beanDefinition, this.readerContext.getRegistry(), true);
} else {
beanName = this.readerContext.generateBeanName(beanDefinition);
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null && beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() && !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
aliases.add(beanClassName);
}
}
if (this.logger.isDebugEnabled()) {
this.logger.debug("Neither XML 'id' nor 'name' specified - using generated bean name [" + beanName + "]");
}
} catch (Exception ex) {
this.error(ex.getMessage(), ele);
return null;
}
}
String[] aliasesArray = StringUtils.toStringArray(aliases);
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
} else {
return null;
}
生成后,进行注册
java
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
//bean进行注册
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
} catch (BeanDefinitionStoreException ex) {
this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, ex);
}
this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
其中bdHolder 只包含了:
BeanDefinition 的实例和它的 beanName、aliases 这三个信息
注册部分代码:
java
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
//这里是要注册所有的别名,这样使用别名可以找回来
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for(String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
注册代码:
java
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
// 将 BeanDefinition 放到这个 map 中,这个 map 保存了所有的 BeanDefinition
this.beanDefinitionMap.put(beanName, beanDefinition);
// 这是个 ArrayList,所以会按照 bean 配置的顺序保存每一个注册的 Bean 的名字
this.beanDefinitionNames.add(beanName);
// 这是个 LinkedHashSet,代表的是手动注册的 singleton bean,
// 注意这里是 remove 方法,到这里的 Bean 当然不是手动注册的
// 手动指的是通过调用以下方法注册的 bean :
// registerSingleton(String beanName, Object singletonObject)
// 这不是重点,解释只是为了不让大家疑惑。Spring 会在后面"手动"注册一些 Bean,
// 如 "environment"、"systemProperties" 等 bean,我们自己也可以在运行时注册 Bean 到容器中的
this.manualSingletonNames.remove(beanName);
以上完成了Bean的注册
继续向下:
java
preInstantiateSingletons:
for(String beanName : beanNames) {
RootBeanDefinition bd = this.getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (this.isFactoryBean(beanName)) {
final FactoryBean<?> factory = (FactoryBean)this.getBean("&" + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = (Boolean)AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
public Boolean run() {
return ((SmartFactoryBean)factory).isEagerInit();
}
}, this.getAccessControlContext());
} else {
isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
}
if (isEagerInit) {
this.getBean(beanName);
}
} else {
this.getBean(beanName);
}
}
}
继续向下则是Bean的创建:
![[Pasted image 20260331160308.png]]
java
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
} else if (mbd.getFactoryMethodName() != null) {
return this.instantiateUsingFactoryMethod(beanName, mbd, args);
} else {
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized(mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
属性注入:
java
// bean 实例的所有属性都在这里了
PropertyValues pvs = mbd.getPropertyValues();
//...
//然后先name 再type
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 通过名字找到所有属性值,如果是 bean 依赖,先初始化依赖的 bean。记录依赖关系
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 通过类型装配。复杂一些
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
然后是initializeBean 初始化,解决各种回调。
区别非常关键:
- populateBean:给 Bean "填属性"
- initializeBean:对 Bean 做"初始化"
它们是 Spring 创建 Bean 过程里的两个不同阶段。
1. populateBean 是属性注入阶段
这一阶段主要做:
- 把 BeanDefinition 里的属性值设置到 Bean 实例上
- 处理 @Autowired
- 处理 @Value
- 处理按名字、按类型自动注入
- 调用 setter/反射完成依赖注入
所以它关心的是:
- 这个对象的成员变量、setter 属性,怎么补齐
比如:
userService.setOrderDao(orderDao);
userService.setName("test");
这些基本属于 populateBean 干的事。
2. initializeBean 是初始化阶段
属性都填完之后,Spring 才开始初始化 Bean。
这一阶段主要做:
- 调用 Aware 接口回调
- 执行 BeanPostProcessor#postProcessBeforeInitialization
- 调用初始化方法
- 执行 BeanPostProcessor#postProcessAfterInitialization
比如:
- BeanNameAware
- BeanFactoryAware
- InitializingBean.afterPropertiesSet()
- 自定义 init-method
- AOP 代理生成,很多时候也发生在这里的后置处理器阶段
所以它关心的是:
- Bean 已经有完整依赖了,现在开始做"增强"和"初始化回调"
3. 顺序上谁先谁后
一般是:
4. 实例化 Bean
5. populateBean
6. initializeBean
也就是:
- 先把对象造出来
- 再把依赖注入进去
- 最后再执行初始化逻辑
4. 举个最直观的例子
假设有个 Bean:
public class UserService implements InitializingBean {
private OrderDao orderDao;
public void setOrderDao(OrderDao orderDao) {
this.orderDao = orderDao;
}
@Override
public void afterPropertiesSet() {
System.out.println(orderDao); // 这里已经有值了
}
}
Spring 会先执行:
setOrderDao(...)
这是 populateBean
然后再执行:
afterPropertiesSet()
这是 initializeBean
所以 afterPropertiesSet() 里看到的属性,通常已经注入完成了。
5. 一句话抓本质
populateBean 解决的是:
- "把这个 Bean 需要的数据和依赖塞进去"
initializeBean 解决的是:
- "Bean 都准备好了,现在执行初始化回调和后置增强"
一句话总结
populateBean 是依赖注入、属性填充;initializeBean 是在属性注入完成之后,执行各种初始化回调和 Bean 后置处理。