spring5源码解析—Bean的获取流程
Bean的获取分为是否在Bean中加了@lazy注解
正常加载的流程
调用getBean()后第一步会进入AbstractApplicationContext中的getBean方法,此方法会返回一个getBeanFactory().getBean(name),其中name是getBean时传入的
@Override
public Object getBean(String name) throws BeansException {
assertBeanFactoryActive();
return getBeanFactory().getBean(name);
}
接下来进入getBeanFactory().getBean(name)中,我们可以发现此方法是调用了AbstractBeanFactory中的getBean方法,并返回一个doGetBean方法
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
继续进入这个doGetBean,可以发现该方法也是在AbstractBeanFactory中,这个方法非常长,我们先看一部分。
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
......
第一步会执行一个 transformedBeanName(name),这个方法是判断传入的Bean的name是否以&开头,如果不是就使用当前的name,如果是就会返回一个BeanFactory的beanName
public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null");
//BeanFactory.FACTORY_BEAN_PREFIX == &
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
return name;
}
return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
do {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
return beanName;
});
}
第二步会执行DefaultSingletonBeanRegisty类中的getSingleton(beanName),该方法是为了判断这个bean是否已经有缓存了
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
我们具体来看这个方法是如何实现的
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//根据beanName得到一个单例对象
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;
}
如果是正常情况,singletonObject 是不会为空的,所以会创建出singletonObject对象并返回,所以我们回到doGetBean方法
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
......
也就是说在有缓存的情况下doGetBean方法中getSingleton(beanName)会返回一个单例对象,并赋值给sharedInstance
接着会判断sharedInstance != null && args == null,其中args就是判断你除了给bean的name之外还有没有带其他参数,不在我们讨论范围内,因此会直接跳到getObjectForBeanInstance方法
这个方法在AbstractAutowireCapableBeanFactory类下
@Override
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
String currentlyCreatedBean = this.currentlyCreatedBean.get();
if (currentlyCreatedBean != null) {
registerDependentBean(beanName, currentlyCreatedBean);
}
return super.getObjectForBeanInstance(beanInstance, name, beanName, mbd);
}
他在return中继续调用了AbstractBeanFactory中的getObjectForBeanInstance方法,在这里会判断这个实例到底是哪个对象的实例,最后返回一个object,就是我们调用getBean方法最终得到的结果。
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
if (mbd != null) {
mbd.isFactoryBean = true;
}
return beanInstance;
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
}
else {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
懒加载的流程
懒加载的流程直到getSingleton获取缓存之前都一样,所以直接从这里开始
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {//这里是false,没有缓存了
}
else {
//判断这个bean是否正在创建
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//判断当前BeanFactory是否为空
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
//.....
}
if (!typeCheckOnly) {
//为bean标记为已经创建
markBeanAsCreated(beanName);
}
}
首先会判断这个bean是否正在创建,如果是正在创建的话会抛出BeanCurrentlyInCreationException异常
然后判断BeanFactory是否为空,是为了判断这个bean是否已经在BeanFactory中定义了,只是还没生产出来,这是为了防止多线程的问题。
接着要为bean做一个标记,来看一下这个markBeanAsCreated方法
protected void markBeanAsCreated(String beanName) {
if (!this.alreadyCreated.contains(beanName)) {
synchronized (this.mergedBeanDefinitions) {
if (!this.alreadyCreated.contains(beanName)) {
// Let the bean definition get re-merged now that we're actually creating
// the bean... just in case some of its metadata changed in the meantime.
clearMergedBeanDefinition(beanName);
this.alreadyCreated.add(beanName);
}
}
}
}
Spring在这里会进行了加锁的双重验证(double Check)判断这个bean是否已经被标记为创建了,如果没有还会再清空一次
clearMergedBeanDefinition(beanName),不得不说,真是相当保险,然后才会标记为已经创建。
接下来是这个else中的下半部分。
try {
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
}
}
}
在这里首先执行getMergedLocalBeanDefinition(beanName)方法获取这个bean中所有的定义,例如是否懒加载、是否多例、是否自动注入等等
接下来分别是判断这个bean有无依赖、单例还是多例,因为这里是单例的,所以进入到这个方法中
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
在这里他再次调用DefaultSingletonBeanRegisty另一个getSingleton方法,
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 (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
调用其中的addSingleton方法,将bean和singletonObejct的放入map中,然后注册。
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);
}
}
然后返回一个singletonObject,并赋值给外层的sharedInstance
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
最后又调用了我们熟悉的AbstractBeanFactory中的getObjectForBeanInstance方法,在这里会判断这个实例到底是哪个对象的实例,最后返回一个object,就是我们调用getBean方法最终得到的结果。
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
if (mbd != null) {
mbd.isFactoryBean = true;
}
return beanInstance;
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
}
else {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
本文地址:https://blog.csdn.net/qq_42341656/article/details/107896328
上一篇: PHP分页详细讲解(有实例)
推荐阅读
-
spring5源码解析—Bean的获取流程
-
解析Java中如何获取Spring中配置的bean
-
spring5 源码深度解析----- 事务的回滚和提交(100%理解事务)
-
spring5 源码深度解析----- AOP代理的生成
-
spring5 源码深度解析----- 被面试官给虐懵了,竟然是因为我不懂@Configuration配置类及@Bean的原理
-
Spring 的 Bean 生命周期,11 张高清流程图及代码,深度解析
-
使用OkHttp获取本地服务器目录下的json数据并解析为Bean对象
-
spring源码深度解析— IOC 之 开启 bean 的加载
-
Spring源码解析六 (Bean的初始化)
-
解析spring加载bean流程的方法