当前位置: 移动技术网 > IT编程>开发语言>Java > spring5源码解析—Bean的获取流程

spring5源码解析—Bean的获取流程

2020年08月10日  | 移动技术网IT编程  | 我要评论
Bean的获取分为是否在Bean中加了@lazy注解正常加载的流程调用getBean()后第一步会进入AbstractApplicationContext中的getBean方法,此方法会返回一个getBeanFactory().getBean(name),其中name是getBean时传入的@Overridepublic Object getBean(String name) throws BeansException {assertBeanFactoryActive();r

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

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网