著作权归作者所有。 商业转载请联系作者获得授权,非商业转载请注明出处。 作者:西柚dzh 链接:https://cloud.tencent.com/developer/article/2019359 来源:https://www.dcmickey.cn/
本文是以源码断点方式提取出核心方法点,方便大家理解以及调试时不走弯路。
整个Bean的创建过程相当复杂,并且容易绕脑子。最好还是结合源码来看
有机会画点图,文字太多了
A引用B ,B引用A。
Spring如何帮我们创建A和B对象
缓存其实就是三个Map
想看整个spring源码核心方法的过程的请看本文最下方<对象创建步骤详尽版>
spring解决循环依赖是通过对象的实例化和初始化分开的步骤来实现的,如果是构造函数注入的话,对象实例化就卡住了
实例化时申请出对象的空间,初始化给对象填充属性
思考为啥要在三级缓存中方函数式接口创建方法(匿名内部类)?
在于为了创建代理对象,三级缓存中放入的是生成该对象的一个匿名内部类,可能是生成代理类,也可能是普通对象。
以下摘自网络博客 Spring 为何需要三级缓存解决循环依赖,而不是二级缓存 我们会发现再执行一遍singleFactory.getObject()方法又是一个新的代理对象,这就会有问题了,因为AService是单例的,每次执行singleFactory.getObject()方法又会产生新的代理对象,假设这里只有一级和三级缓存的话,我每次从三级缓存中拿到singleFactory对象,执行getObject()方法又会产生新的代理对象,这是不行的,因为AService是单例的,所有这里我们要借助二级缓存来解决这个问题,将执行了singleFactory.getObject()产生的对象放到二级缓存中去,后面去二级缓存中拿,没必要再执行一遍singletonFactory.getObject()方法再产生一个新的代理对象,保证始终只有一个代理对象。还有一个注意的点 既然singleFactory.getObject()返回的是代理对象,那么注入的也应该是代理对象,我们可以看到注入的确实是经过CGLIB代理的AService对象。所以如果没有AOP的话确实可以两级缓存就可以解决循环依赖的问题,如果加上AOP,两级缓存是无法解决的,不可能每次执行singleFactory.getObject()方法都给我产生一个新的代理对象,所以还要借助另外一个缓存来保存产生的代理对象
refresh();
// Instantiate all remaining (non-lazy-init) singletons. 完成所有单例非懒加载的对象实例化
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
....
try {
.....
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
throw ex;
}
finally {
}
}
}
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
// 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)) {
}
else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
......
}
具体实现者doGetBean(name, null, null, false);方法,调用getSingleton(beanName);
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
String beanName = transformedBeanName(name);
Object beanInstance;
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
...
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
return adaptBeanInstance(name, beanInstance, requiredType);
}
1.从一级缓存singletonObjects获取对象A,发现不存在 2.对象不存在并且不在初始化中(isSingletonCurrentlyInCreation) 3.直接返回null出去
@Override
@Nullable
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
@Nullable
protected Object getSingleton(Sjatring beanName, boolean allowEarlyReference) {
// Quick check for existing instance without full singleton lock
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
synchronized (this.singletonObjects) {
// Consistent creation of early reference within full singleton lock
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
将一个函数式方法传递进去!!!! 记住这个!!!
else {
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
...
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
在这次的getSingleton方法中 1.同样尝试从一级缓存中获取对象A,不存在 2.执行singletonFactory.getObject(); 也就是传进来的函数式方法createBean(beanName, mbd, args); 3.执行到了Object beanInstance = doCreateBean(beanName, mbdToUse, args);
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
.....
try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
}
finally {
...
afterSingletonCreation(beanName);
}
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
这一步就实例化完成了,申请到了地址
1.执行到instanceWrapper = createBeanInstance(beanName, mbd, args); 2.instantiateBean(beanName, mbd); 3.beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this); 4.BeanUtils.instantiateClass(constructorToUse); 5.return ctor.newInstance(argsWithDefaultValues); 6.一直return到doCreateBean里,然后向下执行addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
.....
// 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);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
==但是存的只是一个函数式方法() -> getEarlyBeanReference(beanName, mbd, bean)==
1.判断一级缓存没有 2.写入三级缓存singletonFactories,并删除二级缓存 3.标记当前对象A注册了。
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
populateBean(beanName, mbd, instanceWrapper);
populateBean中的核心代码
// populateBean中的核心代码
applyPropertyValues(beanName, mbd, bw, pvs);
applyPropertyValues核心代码
// applyPropertyValues核心代码
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
resolveValueIfNecessary核心代码
return resolveReference(argName, ref);
resolveReference核心代码
bean = this.beanFactory.getBean(resolvedName);
这时候已经开始走A那时候的getBean的一套流程了
重复4到8的过程,将对象B和对象B的函数式方法一起写入三级缓存
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// Quick check for existing instance without full singleton lock
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
synchronized (this.singletonObjects) {
// Consistent creation of early reference within full singleton lock
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
和第9步对应,填充属性A,通过第5.1步的getSingletion获取对象A,但是这次走向不同,A的状态已经变为初始化过程中了,可以进入if条件 1.双重锁DCL,从一级缓存singletionObject中获取,不存在 2.从二级缓存earlySingletonObject中获取,不存在 3.上锁synchronize一级缓存 4.再次确认一级缓存和二级缓存中有没有 5.从三级缓存singletonFactories中取到了对象A 6.并且将对象A的匿名内部类给执行了,得到具体对象转移到二级缓存中去了,三级缓存移除掉A 7.将A对象地址给到B对象的A属性上,完成初始化动作
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
并且这个二级缓存的A不是三级缓存的A,而是通过三级缓存存的那个方法执行后的对象
这里注意下执行到getSingleton时,因为传的是false。所以里面方法执行不到,B对象也就不会从三级缓存到二级缓存中
Object earlySingletonReference = getSingleton(beanName, false);
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
这里getsingleton 会从二级缓存中得到对象A
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
..............
}
}
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
版权属于:dingzhenhua
本文链接:https://cloud.tencent.com/developer/article/2019359
转载时须注明出处及本声明
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有