// 1.工厂方法创建
// 2.构造方法的方式注入
// 3.无参构造方法注入
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
// 调用BeanDefinition属性合并完成后的BeanPostProcessor后置处理器
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 被@Autowired、@Value标记的属性在这里获取
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
“Post-processing of merged bean definition failed”, ex);
}
mbd.postProcessed = true;
}
}
// 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) {
if (logger.isTraceEnabled()) {
logger.trace(“Eagerly caching bean '” + beanName +
“’ to allow for resolving potential circular references”);
}
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 (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, “Initialization of bean failed”, 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 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 " +
“‘getBeanNamesOfType’ 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;
}
接上文分析到的位置,接下来执行:
// 向容器中缓存单例模式的Bean对象,以防循环引用
// 判断是否是早期引用的bean,如果是,则允许其提前暴露引用
// 这里判断的逻辑主要有三个:
// 1.是否为单例
// 2.是否允许循环引用
// 3.是否是在创建中的bean
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
之后会来到
// 这里是一个匿名内部类,为了防止循环引用,尽早持有对象的引用
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
进入到addSingletonFactory:
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);
// 消除此Bean在二级缓存里的缓存信息
this.earlySingletonObjects.remove(beanName);
// 这里为了记录注册单例的顺序
this.registeredSingletons.add(beanName);
}
}
}
消除此Bean在二级缓存里的缓存信息,将其包装成singletonFactory实例往三级缓存里添加
这里有一个重点就是Spring解决循环依赖的真相就在这一段源码中:在这里beanFactory被put进了
singletonFactories
,此时的bean只是完成了初始化构造的bean,还没有进行set或者注解注入的bean,是bean的一个中间状态,但是已经能被人认出来了,所以Spring此时将这个对象提前曝光出来让大家认识、使用。
回到doCreateBean,进入到getEarlyBeanReference
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
// 如果是SmartInstantiationAwareBeanPostProcessor类型,就进行处理,
// 如果没有相关处理内容,就返回默认的实例。
// 里面的AbstractAutoProxyCreator类是后续AOP的关键
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
// 对单例进行AOP包装并返回的地方!
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
注意这个方法并不是在doCreateBean的
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
这一行执行的,这里只是将getEarlyBeanReference注册进去,实际执行的地方是前面尝试从缓存里获取bean的地方,即AbstractBeanFactory的doCreateBean方法里。
回到doCreateBean,此时获取到了bean,并且只在三级缓存里面保存。
之后会执行
populateBean(beanName, mbd, instanceWrapper);
来将bean的属性真正注入到里面,然后再调用initializeBean进行彻底的初始化
// Initialize the bean instance.
// Bean对象的初始化,依赖注入在此触发
// 这个exposedObject在初始化完成之后返回作为依赖注入完成后的Bean
Object exposedObject = bean;
try {
// 填充bean实例的属性
populateBean(beanName, mbd, instanceWrapper);
// 初始化bean,过程如下:
// 1. 判断是否实现了BeanNameAware, BeanClassLoaderAware, BeanFactoryAware方法,如果有,则设置相关的属性
// 2. 调用bean初始化的前置(BeanPostProcessor)操作
// 3. 执行初始化的方法
// 如果有initializingBean,则调用afterPropertiesSet
// 如果有InitMethod,则调用初始方法
// 4. 调用bean初始化的后置(BeanPostProcessor)操作
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
之后判断该bean是否允许提前暴露,
if (earlySingletonExposure) {
// 获取指定名称的已注册的单例模式Bean对象
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
// 如果经过initializeBean执行后返回的bean还是同一个(不是代理对象实例,即没有被增强)
if (exposedObject == bean) {
// 确保根据名称获取到的的已注册的Bean和正在实例化的Bean是同一个
exposedObject = earlySingletonReference;
}
…
}
}
if 里面调用了getSingleton方法,进入该方法:
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
最后
我还为大家准备了一套体系化的架构师学习资料包以及BAT面试资料,供大家参考及学习
已经将知识体系整理好(源码,笔记,PPT,学习视频)
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
最后
我还为大家准备了一套体系化的架构师学习资料包以及BAT面试资料,供大家参考及学习
已经将知识体系整理好(源码,笔记,PPT,学习视频)
[外链图片转存中…(img-6MrMQN02-1713420391919)]
[外链图片转存中…(img-Ixm7MrQC-1713420391919)]
[外链图片转存中…(img-Nqjw0ZNJ-1713420391920)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!