Spring创建bean的流程如图
beanFactory.preInstantiateSingletons();从这个函数开始创建单例bean对象
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
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 {
getBean(beanName);
}
从这边开始getbean,去尝试获取bean对象。
getBean调用doGetBean方法
doGetBean方法根据不同的作用域来决定怎么调用createBean方法。getSingleton传递了一个lamda表达式用于实现ObjectFactory的getObject方法。
当调用getObject方法后会调用传递进来的lamda表达式,也就是调用了createBean方法
createBean调用了doCreateBean方法
doCreateBean调用了createBeanInstance方法来创建实例 ,通过不同的构造策略来实例化,比如说构造器注入,或者是通过反射创建对象等等。
拿到该实例bean后,在第三重缓存SingletonFactory中放入(beanName,lamda)的元素,接着去进行属性注入populateBean。
会根据你选择的autowired方式来进行属性注入
通过containsBean,去一重缓存找,找不到去BeanDefinition中找,都找不到说明不存在报错
然后调用getBean方法来进行获取bean注入属性。此时会访问三重缓存,询问有没有这个bean(按顺序)
此时的三重缓存如图
并没有和B相关的元素。所以要继续创建B对象。此时已经有了半成品A,但是游离在三重缓存外。
此时B也要经过上面CreateBean,doCreateBean,createBeanInstance,populateBean的流程。到了属性注入时又去getBean寻找A。
此时的BeanFactory如图
此时B再去三重缓存中get A已经可以在三重缓存中拿到A的lamda表达式了
同样的这个lamda表达式调用了getObject
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
实际调用了这个函数把半成品beanA返回了回去。调用完getObject后三重缓存删除A对应的lamda表达式并把半成品A放入二级缓存。
此时的BeanFactory如图
getBean返回了半成品的A,调用applyPropertyValues,获得了完整的B对象。此时getbean方法会返回B对象给A,A也变成了完成品。其实就是A在调用singletonFactory.getObject();去创建单例对象,结束后就放入了一重缓存。
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
然后通过这个方法注册进一重缓存。