主干流程
beanFactory.preInstantiateSingletons();
@Override
public 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.
// 拷贝一份bean
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
// 取bean的元数据,这里有个合并的动作
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 处理非抽象,并且是单例,非懒加载的bean
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
// 工厂bean
Object 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 {
// 其他的bean
getBean(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==null
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}
if (mbd == null || mbd.stale) {
previous = mbd; // null
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 {
......
}
// 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;
}
}
```java
package 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) {
// 根据配置文件加载bean
ClassPathXmlApplicationContext 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)) {
// 工厂bean
Object 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 的大流程。