Spring 5.x source getBean explain a tour of fifteen

getBean(String name)

Yesterday we talked about the singleton instantiation will first determine whether the FactoryBeantype that is the case will be dealt with accordingly, but did not say the most critical getBean, and now we started to talk about this, you may need lots of space, which involves a lot of things . Ado, here we go. These are our to instantiate the singleton:
Here Insert Picture Description
But in front of some have been created, you can directly get:
Here Insert Picture Description
In fact, as long as we care about our custom two objects:
Here Insert Picture Description
Here we go:
Here Insert Picture Description
Here Insert Picture Description

doGetBean start getting bean

We look at the argument of this method:

name 就是bean名字
requiredType 表示需要的类型,如果有类型,创建后会进行类型转换
args 表示参数,也就是构造方法的参数
typeCheckOnly 表示只是做检查,并不是真的要用,这个会影响一些逻辑

Because the code is longer, we segmented to analyze better, and to retain the core code:

doGetBean segment 1

First, determine the existence of a single case, and there is no argument, this time not directly return, we need to do some processing, because the name may be passed in FactoryBeanitself, that is name=&beanName.

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
		//获取规范的名字
		final String beanName = transformedBeanName(name);
		Object bean;
		//检查是否手动注册了单例
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {//存在单例了
			...
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

AbstractAutowireCapableBeanFactory的getObjectForBeanInstance

This approach has two important parameters nameand beanName, nameis passed in the name refers, may be FactoryBeanits own name, there is &a prefix, it may be a general beanname, beanNameis the name of the specification, remove the &prefix, so to be processed. For example, this:
Here Insert Picture Description

	@Override
	protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
		//如果有正在创建的bean要建立以来关系,后面讲
		String currentlyCreatedBean = this.currentlyCreatedBean.get();
		if (currentlyCreatedBean != null) {
			registerDependentBean(beanName, currentlyCreatedBean);
		}

		return super.getObjectForBeanInstance(beanInstance, name, beanName, mbd);
	}

AbstractBeanFactory的getObjectForBeanInstance

Processing method of the parent class last call, it will be the next judge nameis not FactoryBeantheir name, and if so, to determine beanInstanceis not the FactoryBeantype is then return directly, that is to say, is looking for FactoryBeanitself, rather than his created bean. If it is not FactoryBeantheir name, the type is not FactoryBean, it is normal singleton, direct return. Otherwise, it is explained should have obtained is FactoryBeancreated bean. If RootBeanDefinitionnot empty, then set up FactoryBean=true, otherwise it from the FactoryBeancache acquisition, if acquired direct return, or we need to create, and then return.

protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

		if (BeanFactoryUtils.isFactoryDereference(name)) {//是否是FactoryBean名字的前缀
			if (beanInstance instanceof NullBean) {
				return beanInstance;
			}
			if (!(beanInstance instanceof FactoryBean)) {//不是FactoryBean的话名字有&会报异常
				throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
			}
			if (mbd != null) {
				mbd.isFactoryBean = true;
			}
			return beanInstance;
		}

		if (!(beanInstance instanceof FactoryBean)) {//不是FactoryBean就直接返回
			return beanInstance;
		}
		//创建FactoryBean中的bean
		Object object = null;
		if (mbd != null) {
			mbd.isFactoryBean = true;
		}
		else {//从FactoryBean的缓存中获取
			object = getCachedObjectForFactoryBean(beanName);
		}
		if (object == null) {

			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;

			if (mbd == null && containsBeanDefinition(beanName)) {//mbd没定义,但是FactoryBean是有定义的,获取mbd
				mbd = getMergedLocalBeanDefinition(beanName);
			}
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	}

getCachedObjectForFactoryBean acquired from the cache

factoryBeanObjectCacheIs the FactoryBeancreation of beancache, will be created once the cache, take the next directly.

	@Nullable
	protected Object getCachedObjectForFactoryBean(String beanName) {
		return this.factoryBeanObjectCache.get(beanName);
	}

getObjectFromFactoryBean create the bean

Here is the FactoryBeancreation beanprocess. If you FactoryBeanare single cases, and has been created out, starting with the cache acquisition to see if there is a direct return. If there is to be doGetObjectFromFactoryBeancreated, in fact, called getObject()acquisition target. Where did it again retrieved from the cache, I feel very strange, has already been acquired does not exist, how can there exist, in fact, because getObject()when you create can be customized processor might have, might be factoryBeanObjectCacheset up, so here also a judge, if any, they should get existence, rather than just created, so the processor is considered extended functionality, otherwise the process is also equal to the useless. If there is no cache to determine whether the need for treatment, in fact, here that is not synthetic objects !synthetic, such as AOPthe advicenotification even synthetic objects in general are not synthetic, if need treatment, but is being created in a single case, direct return does not deal with, or to a processor, and finally into the cache. If it is, then the prototype is created every time a new one.

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
		if (factory.isSingleton() && containsSingleton(beanName)) {
			synchronized (getSingletonMutex()) {
				Object object = this.factoryBeanObjectCache.get(beanName);
				if (object == null) {
					object = doGetObjectFromFactoryBean(factory, beanName);
					Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
					if (alreadyThere != null) {
						object = alreadyThere;
					}
					else {
						if (shouldPostProcess) {//需要处理
							if (isSingletonCurrentlyInCreation(beanName)) {//直接返回
								return object;
							}
							beforeSingletonCreation(beanName);
							try {
								object = postProcessObjectFromFactoryBean(object, beanName);//进行后置处理器处理
							}
							catch (Throwable ex) {
								throw new BeanCreationException(beanName,
										"Post-processing of FactoryBean's singleton object failed", ex);
							}
							finally {
								afterSingletonCreation(beanName);
							}
						}
						if (containsSingleton(beanName)) {//如果包含了FactoryBean,就将创建的对象缓存
							this.factoryBeanObjectCache.put(beanName, object);
						}
					}
				}
				return object;
			}
		}
		else {//FactoryBean是原型的话
			Object object = doGetObjectFromFactoryBean(factory, beanName);
			if (shouldPostProcess) {
				try {
					object = postProcessObjectFromFactoryBean(object, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
				}
			}
			return object;
		}
	}
doGetObjectFromFactoryBean

In fact, no other thing that is invoked getObject()to create the object, if it returns null, then it is packaged into one NullBean.

private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
			throws BeanCreationException {

		Object object;
		...
		object = factory.getObject();//调用自定义的FactoryBean的getObject获取对象
		...
		if (object == null) {
			if (isSingletonCurrentlyInCreation(beanName)) {//如果是正在创建的FactoryBean,还没能获得bean,就报异常
				throw new BeanCurrentlyInCreationException(
						beanName, "FactoryBean which is currently in creation returned null from getObject");
			}
			object = new NullBean();
		}
		return object;
	}
beforeSingletonCreation和afterSingletonCreation

This is the mark under, are creating this bean, create a clear mark on the process finished.

	protected void beforeSingletonCreation(String beanName) {
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);//没有在排除范围里内且添加不成功,可能就是循环引用了
		}
	}

	protected void afterSingletonCreation(String beanName) {
	if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
		throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
	}
}

postProcessObjectFromFactoryBean created out of the bean processor

It is to carry out BeanPostProcessorthe postProcessAfterInitializationprocess, that is, the place can be extended.

	@Override
	protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
		return applyBeanPostProcessorsAfterInitialization(object, beanName);
	}
	
	@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

Practical examples

Test case:
Here Insert Picture Description
Not Set Prototype:
Here Insert Picture Description
Here Insert Picture Description
Setting a prototype:
Here Insert Picture Description
Here Insert Picture Description

Visible in FactoryBeanthe set @Scope("prototype")will affect created bean.

Sure enough, a fine not say how many good things to say, but do not speak directly to clear the jump did not mean anything to learn, fly and, in the end still have to delve into the problem encountered, or something a little research to learn the spirit of good. The remaining next to continue it.

Well, here today, we hope to help study and understand, do not spray the Great God see, understand only their own learning, limited capacity, please excuse.

Published 235 original articles · won praise 74 · views 30000 +

Guess you like

Origin blog.csdn.net/wangwei19871103/article/details/105041908