首先是ioc的创建流程简图
image
image.gif
初始化对象时的循环依赖问题
这个问题出现在上图applicationContext.refresh()方法中,再生成Bean对象时出现的
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
//准备BeanFactory的前置工作
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
//生产BeanFactoryPostProcess对象
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
//执行BeanFactoryPostProcess对象的方法处理BeanDefintion的信息
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
//准备BeanPostProcessor对象
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
//国际化
initMessageSource();
// Initialize event multicaster for this context.
//准备事件监听
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
//注册监听器
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//生产Bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
...
}
}
image.gif
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
...
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
image.gif
然后循环BeanDefintion的信息getBean(创建Bean)
@Override
public void preInstantiateSingletons() throws BeansException {
...
// Trigger initialization of all non-lazy singleton beans...
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) {
final FactoryBean factory = (FactoryBean) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction)
((SmartFactoryBean) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
...
}
image.gif
doGetBean是核心
protected T doGetBean(final String name, @Nullable final Class requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
...
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
...
}
image.gif
createBean包含了核心doCreateBean方法
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
...
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
...
}
image.gif
此时完成对a的实例化,开始进行a的初始化
此时{
一级缓存:null
二级缓存:null
三级缓存:{A的beanName:获取A对象二级缓存对象的方法}
})
addSingletonFactory将数据放到三级缓存中
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
...
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
...
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));//将获取二级缓存方法的匿名内部类放入三级缓存
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper); //初始化Bean 非常重要!!!
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
...
// Register bean as disposable.
...
return exposedObject;
}
image.gif
populateBean对A实例化的过程中发现没有B对象 所以开始对B进行doCreateBean
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
...
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
...
// Create a deep copy, resolving any references for values.
List deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
for (PropertyValue pv : original) {
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);//处理数据
...
}
public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
// We must check each value to see whether it requires a runtime reference
// to another bean to be resolved.
if (value instanceof RuntimeBeanReference) {
RuntimeBeanReference ref = (RuntimeBeanReference) value;
return resolveReference(argName, ref);
}
...
}
private Object resolveReference(Object argName, RuntimeBeanReference ref) {
try {
Object bean;
String refName = ref.getBeanName();
refName = String.valueOf(doEvaluate(refName));
if (ref.isToParent()) {
if (this.beanFactory.getParentBeanFactory() == null) {
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Can't resolve reference to bean '" + refName +
"' in parent factory: no parent factory available");
}
bean = this.beanFactory.getParentBeanFactory().getBean(refName);
}
else {
bean = this.beanFactory.getBean(refName);//通过getBean创建BeanB
this.beanFactory.registerDependentBean(refName, this.beanName);
}
if (bean instanceof NullBean) {
bean = null;
}
return bean;
}
catch (BeansException ex) {
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);
}
}
image.gif
再次回到doCreateBean方法将B实例化
此时{
一级缓存:null
二级缓存:null
三级缓存:{A的beanName:获取A对象二级缓存对象的方法} {B的beanName:获取B对象二级缓存对象的方法}
})
再次回到B的初始化中 此时已经可以获取到A的实例了 将此RuntimeBeanReference分配给B的实例
private Object resolveReference(Object argName, RuntimeBeanReference ref) {
try {
Object bean;
String refName = ref.getBeanName();
refName = String.valueOf(doEvaluate(refName));
if (ref.isToParent()) {
...
}
else {
bean = this.beanFactory.getBean(refName); //此时再getBean时,getSingleton已经能拿到A实例了
this.beanFactory.registerDependentBean(refName, this.beanName);
}
if (bean instanceof NullBean) {
bean = null;
}
return bean;
}
...
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName); //先找一级缓存有没有A
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);//再找二级缓存有没有A
if (singletonObject == null && allowEarlyReference) { //此时这里A对象正在创建中
ObjectFactory singletonFactory = this.singletonFactories.get(beanName);//发现三级缓存中有A
if (singletonFactory != null) { //将A对象放入二级缓存中singletonFactory.getObject()调用匿名方法,即 getEarlyBeanReference()
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
image.gif
此时{
一级缓存:null
二级缓存:{A的beanName:BeanA}
三级缓存:{B的beanName:获取B对象二级缓存对象的方法}
})
doCreateBean结束之后执行addSingleton()将B放到一级缓存中
此时{
一级缓存:{B的beanName:BeanB}
二级缓存:{A的beanName:BeanA}
三级缓存:null
})
此时B完成了createBean的动作最后赋值给了A的实例,此时A也回到这里,执行addSingleton将A实例放到一级缓存中
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;
}
}
image.gif
此时{
一级缓存:{A的beanName:BeanA} {B的beanName:BeanB}
二级缓存:null
三级缓存:null
})
总结:
【第一个doGetBean最初的getSingleton方法用来调用getEarlyBeanReference获取保存二级缓存数据】,【addSingletonFactory负责把数据存到三级缓存】,
【第二个doGetBean的getSingleton方法用来创建Bean,再addSingleton】,
【addSingleton方法是把成品Bean挪到一级缓存】,
【getEarlyBeanReference用来获取二级缓存对象引用】。
总结一句就是,半成品a的初始化创建了b的成品之后a再变成成品。