主干流程
beanFactory.preInstantiateSingletons();
@Overridepublic void preInstantiateSingletons() throws BeansException {if (logger.isTraceEnabled()) {logger.trace("Pre-instantiating singletons in " + this);}// Iterate over a copy to allow for init methods which in turn register new bean definitions.// While this may not be part of the regular factory bootstrap, it does otherwise work fine.// 拷贝一份beanList<String> beanNames = new ArrayList<>(this.beanDefinitionNames);// Trigger initialization of all non-lazy singleton beans...for (String beanName : beanNames) {// 取bean的元数据,这里有个合并的动作RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);// 处理非抽象,并且是单例,非懒加载的beanif (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {if (isFactoryBean(beanName)) {// 工厂beanObject bean = getBean(FACTORY_BEAN_PREFIX + beanName);if (bean instanceof FactoryBean) {FactoryBean<?> factory = (FactoryBean<?>) bean;boolean isEagerInit;// 如果是SmartFactoryBean的实例if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {// 安全检查isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean<?>) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}}else {// 其他的beangetBean(beanName);}}}// bean 创建后的回调// Trigger post-initialization callback for all applicable beans...for (String beanName : beanNames) {Object singletonInstance = getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton) {SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {smartSingleton.afterSingletonsInstantiated();return null;}, getAccessControlContext());}else {smartSingleton.afterSingletonsInstantiated();}}}}
片段:合并 bean 定义
getMergedLocalBeanDefinition 合并操作。将 BeanDefinition转换成 RootBeanDefinition。
- 如果 Abean extends Object ,那么 RootBeanDefinition 就是 Abean 本身的 BeanDefinition;
 - 如果 Abean extends Bbean,那么就需要合并 Abean 和 Bean 的BeanDefinition。
 
spring-context | org.springframework.beans.factory.support.AbstractBeanFactory#getMergedLocalBeanDefinition
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {// Quick check on the concurrent map first, with minimal locking.// 检查下缓存,有的话,并且不需要合并的直接返回RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);if (mbd != null && !mbd.stale) {return mbd;}return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));}
调用 getMergedBeanDefinition
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)throws BeanDefinitionStoreException {return getMergedBeanDefinition(beanName, bd, null);}
重载的方法
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)throws BeanDefinitionStoreException {// ConcurrentHashMap 内部是线程安全的,但是把单个操作组合起来不一定是安全的。比如 map.put(key,value++)。synchronized (this.mergedBeanDefinitions) {RootBeanDefinition mbd = null;RootBeanDefinition previous = null;// Check with full lock now in order to enforce the same merged instance.if (containingBd == null) {mbd = this.mergedBeanDefinitions.get(beanName);}if (mbd == null || mbd.stale) {previous = mbd;if (bd.getParentName() == null) {// Use copy of given root bean definition.if (bd instanceof RootBeanDefinition) {mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();}else {mbd = new RootBeanDefinition(bd);}}else {// Child bean definition: needs to be merged with parent.BeanDefinition pbd;try {String parentBeanName = transformedBeanName(bd.getParentName());if (!beanName.equals(parentBeanName)) {pbd = getMergedBeanDefinition(parentBeanName);}else {BeanFactory parent = getParentBeanFactory();if (parent instanceof ConfigurableBeanFactory) {pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);}else {throw new NoSuchBeanDefinitionException(parentBeanName,"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +"': cannot be resolved without a ConfigurableBeanFactory parent");}}}catch (NoSuchBeanDefinitionException ex) {throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);}// Deep copy with overridden values.mbd = new RootBeanDefinition(pbd);mbd.overrideFrom(bd);}// Set default singleton scope, if not configured before.if (!StringUtils.hasLength(mbd.getScope())) {mbd.setScope(SCOPE_SINGLETON);}// A bean contained in a non-singleton bean cannot be a singleton itself.// Let's correct this on the fly here, since this might be the result of// parent-child merging for the outer bean, in which case the original inner bean// definition will not have inherited the merged outer bean's singleton status.if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {mbd.setScope(containingBd.getScope());}// Cache the merged bean definition for the time being// (it might still get re-merged later on in order to pick up metadata changes)if (containingBd == null && isCacheBeanMetadata()) {this.mergedBeanDefinitions.put(beanName, mbd);}}if (previous != null) {copyRelevantMergedBeanDefinitionCaches(previous, mbd);}return mbd;}}
合并操作有不同的情况
这里分两种情况去看代码:
- 实例化普通的 bean ,比如 Sbean
 - 实例化有很多父类的 bean,比如 Abean extends Bbean,Bbean extends Cbean …
情况1:单个bean
首先进入方法:getMergedLocalBeanDefinition(String beanName)protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {// Quick check on the concurrent map first, with minimal locking.// 检查下缓存,有的话,并且不需要合并的直接返回RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);if (mbd != null && !mbd.stale) {return mbd;}return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));}
 
这里肯定没有缓存,所以进入下一个方法:
getMergedBeanDefinition(String beanName, BeanDefinition bd)
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)throws BeanDefinitionStoreException {return getMergedBeanDefinition(beanName, bd, null);}
直接进入重载方法:getMergedBeanDefinition(String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd) 。如下代码,删除了不会走的分支。
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)throws BeanDefinitionStoreException {// ConcurrentHashMap 内部是线程安全的,但是把单个操作组合起来不一定是安全的。比如 map.put(key,value++)。synchronized (this.mergedBeanDefinitions) {RootBeanDefinition mbd = null;RootBeanDefinition previous = null;// 这个操作后,mbd==nullif (containingBd == null) {mbd = this.mergedBeanDefinitions.get(beanName);}if (mbd == null || mbd.stale) {previous = mbd; // nullif (bd.getParentName() == null) {// Use copy of given root bean definition.// 不是if (bd instanceof RootBeanDefinition) {mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();}else {// 直接返回这个mbd = new RootBeanDefinition(bd);}}else {......}// Set default singleton scope, if not configured before.if (!StringUtils.hasLength(mbd.getScope())) {mbd.setScope(SCOPE_SINGLETON);}// 加入缓存if (containingBd == null && isCacheBeanMetadata()) {this.mergedBeanDefinitions.put(beanName, mbd);}}return mbd;}}
情况2:有继承关系的bean
比如 Abean extends Bbean,Bextends Object 。前几步骤都一样,直接进入重载方法:getMergedBeanDefinition(String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd) 
因为 Abean 的 parent 不为空,所以进入分支:
BeanDefinition pbd;try {// 得到父bean的名称String parentBeanName = transformedBeanName(bd.getParentName());if (!beanName.equals(parentBeanName)) {// 如果不是当前bean,取父bean的BeanDefinition,递归pbd = getMergedBeanDefinition(parentBeanName);}else {BeanFactory parent = getParentBeanFactory();if (parent instanceof ConfigurableBeanFactory) {pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);}else {throw new NoSuchBeanDefinitionException(parentBeanName,"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +"': cannot be resolved without a ConfigurableBeanFactory parent");}}}catch (NoSuchBeanDefinitionException ex) {throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);}// Deep copy with overridden values.mbd = new RootBeanDefinition(pbd);mbd.overrideFrom(bd);
在 pbd = getMergedBeanDefinition(parentBeanName); 
方法上会不断查找父bean定义。然后利用方法进行合并。
mbd = new RootBeanDefinition(pbd);mbd.overrideFrom(bd);
测试代码
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "https://www.springframework.org/dtd/spring-beans-2.0.dtd"><beans><bean id="dog" class="cn.lichenghao.entity.Dog" lazy-init="false"><property name="name"><value>Dog11</value></property><property name="age"><value>31</value></property></bean><bean id="cat" class="cn.lichenghao.entity.Cat" parent="animal"><property name="name"><value>Cat123</value></property><property name="age"><value>3</value></property></bean><bean id="animal" class="cn.lichenghao.entity.Animal"><property name="canRun"><value>true</value></property></bean></beans>
3个 bean ```java package cn.lichenghao.entity;
public class Animal {
private boolean canRun;public Animal() {}public boolean isCanRun() {return canRun;}public void setCanRun(boolean canRun) {this.canRun = canRun;}
}
```javapackage cn.lichenghao.entity;public class Dog {private String name;private Integer age;public Dog() {System.out.println("Dog init!!");}public Dog(String name, Integer age) {System.out.println("Dog init!!");this.name = name;this.age = age;}public void say(){System.out.println("wwwwwwwww");}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}}
package cn.lichenghao.entity;public class Cat extends Animal {private String name;private Integer age;public Cat() {}public Cat(String name, Integer age) {super();this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}}
启动 IOC 测试
public class AppDog {public static void main(String[] args) {// 根据配置文件加载beanClassPathXmlApplicationContext classPathXmlApplicationContext= new ClassPathXmlApplicationContext("dog.xml");}}
片段:判断 Bean 是否为 FactoryBean
通过代码可以看出,分为两种情况的 Bean ,一种是 FactoryBean,一种是其他的 Bean。
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {String beanName = transformedBeanName(name);Object beanInstance = getSingleton(beanName, false);if (beanInstance != null) {return (beanInstance instanceof FactoryBean);}// No singleton instance found -> check bean definition.if (!containsBeanDefinition(beanName)&& getParentBeanFactory() instanceof ConfigurableBeanFactory) {// No bean definition found in this factory -> delegate to parent.return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);}return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));}
然后再过安全检查,特权处理。
if (isFactoryBean(beanName)) {// 工厂beanObject bean = getBean(FACTORY_BEAN_PREFIX + beanName);if (bean instanceof FactoryBean) {FactoryBean<?> factory = (FactoryBean<?>) bean;boolean isEagerInit;// 如果是SmartFactoryBean的实例if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {// 安全检查isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean<?>) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}}
准备完毕
所有的准备工作已经完毕,接下来就是实例化 bean 的大流程。
