标签:部分 exp enable manager resolved beans 分析 def 逻辑
读完这篇文章你将会收获到
Spring
何时将 bean
加入到第三级缓存和第一级缓存中Spring
何时回调各种 Aware
接口、BeanPostProcessor
、InitializingBean
等相关文章
上两篇文章 Spring 获取单例流程(一) 和 Spring 获取单例流程(二) 介绍了 getBean
前面的流程,今天最后的收尾,把后面的流程继续一起学习下
// 我依赖的大哥都好了
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
} catch (BeansException ex) {
// 从三级缓存中移除这个 beanName 因为它可能被放进去了 因为放进去三级缓存可以解决 setter 的循环依赖
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
如果我们要创建的 bean
是一个单例,
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
// 看看第一级缓存中有没有
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 将 beanName 加入到 singletonsCurrentlyInCreation 中,代表它正在创建中
beforeSingletonCreation(beanName);
boolean newSingleton = false;
try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
} catch (IllegalStateException ex) {
throw ex;
} catch (BeanCreationException ex) {
throw ex;
} finally {
// singletonsCurrentlyInCreation 从这里面移除掉
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 加入缓存中
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
删减了部分不重要的代码,我们大致来看看其流程
bean
了beanName
加入到 singletonsCurrentlyInCreation
中,代表它正在创建中ObjectFactory
的 getObject
方法获得一个 bean
singletonsCurrentlyInCreation
中移除、代表其已经创建完成了全篇完结.终 !!!
其实真正的秘密藏身在参数的 ObjectFactory
中,从上面的流程中可以宏观的知道 Spring
创建 bean
的一个流程
现在我们在看看参数的 ObjectFactory
究竟干啥子了
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
...........
...........
try {
// 真正 处理逻辑
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean ‘" + beanName + "‘");
}
return beanInstance;
} catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
throw ex;
} catch (Throwable ex) {
throw new BeanCreationException(xxxx);
}
}
干活的还是 do
开头的大佬
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 根据指定 bean 使用对应的策略创建新的实例、如工厂方法、构造函数自动注入、简单初始化
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
..........
.........
// 是否需要提前曝光、用来解决循环依赖的问题
// 是单例&允许循环依赖&正在创建中
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// 为了避免后期循环依赖、可以在 bean 初始化前将创建实例的ObjectFactory 加入工厂
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) {
.........
}
........
.......
return exposedObject;
}
上面的流程大致就是
createBeanInstance
这个方法根据你的配置以及你的 bean
的情况选择出一种创建 bean
的方法、可能是工厂方法、可能是某个构造函数、可能是默认的构造函数。这里包含了当一个构造函数的参数是另一个 bean
的时候、它会通过 getBean
的方法获取这个参数的 bean
然后将创建好的 bean
加入到第三级缓存中,默认设置我们是允许循环依赖的
populateBean
方法就是我们填充属性了、如果你依赖的其他 Spring
的其他 bean
是通过这种方式注入的话(autowireByName
autowireByType
)、就是在这一步注入的了,他获取其他 bean
也是通过 getBean
的方式获取
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
.........
.........
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
.........
.........
}
initializeBean
则是调用我们的各种回调接口、Aware
类型的、BeanPostProcessor
、InitializingBean
、自定义初始化函数
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {。
// 调用各种 Aware 接口
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
} else {
// 调用各种 Aware 接口
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 调用 BeanPostProcessor postProcessBeforeInitialization
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 调用 InitializingBean 、自定义的初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 调用 BeanPostProcessor postProcessAfterInitialization
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
其实整体的流程就差不多了
name
找出对应的 beanName
、无论这个 name
是别名或者是一个 factoryBean
的 beanName
beanName
对象
singletonObjects
中看看有没有earlySingletonObjects
singletonFactories
中看看有没有bean
、那么我们还是需要处理一下这个 bean
Spring
缓存中返回的 bean
是 factoryBean
、而用户也想要的是一个 beanFactory
(参数 name
中的前缀是 &
)、那么我们直接返回Spring
缓存中返回的 bean
是普通的 bean
、而用户也想要的是一个普通的 bean
、那么就直接返回Spring
缓存中返回的 bean
是一个 factoryBean
、而用户想要的是一个普通的 bean
、那么我们就要从 factoryBean
中获取这个 bean
factoryBean
中获取这个 bean
的过程中、需要调用到前置处理、后置处理和我们常用的接口回调 BeanPostProcessor
bean
、则判断是否是 prototype
类型并且循环依赖bean
beanName
对应的 beanDefinition
找出其依赖的 beanName
beanName
与 依赖的 beanName
是否循环依赖、没有则注册其依赖关系并调用 getBean
方法去创建依赖的 beanName
beanName
加入到 singletonsCurrentlyInCreation
中singletonsCurrentlyInCreation
中移除、代表其已经创建完成了bean
给调用方其实总体的流程还是不算复杂把、我们也可以从中收获到一些东西。其实我们最关心也是面试最常问的一个问题就是、Spring 如何解决循环依赖的问题、感兴趣的可以看看这篇文章公众号内的 Spring 循环依赖
这篇文章
标签:部分 exp enable manager resolved beans 分析 def 逻辑
原文地址:https://www.cnblogs.com/-coder-li/p/13049384.html