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 FactoryBean
type 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:
But in front of some have been created, you can directly get:
In fact, as long as we care about our custom two objects:
Here we go:
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 FactoryBean
itself, 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 name
and beanName
, name
is passed in the name refers, may be FactoryBean
its own name, there is &
a prefix, it may be a general bean
name, beanName
is the name of the specification, remove the &
prefix, so to be processed. For example, this:
@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 name
is not FactoryBean
their name, and if so, to determine beanInstance
is not the FactoryBean
type is then return directly, that is to say, is looking for FactoryBean
itself, rather than his created bean
. If it is not FactoryBean
their name, the type is not FactoryBean
, it is normal singleton, direct return. Otherwise, it is explained should have obtained is FactoryBean
created bean
. If RootBeanDefinition
not empty, then set up FactoryBean=true
, otherwise it from the FactoryBean
cache 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
factoryBeanObjectCache
Is the FactoryBean
creation of bean
cache, 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 FactoryBean
creation bean
process. If you FactoryBean
are 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 doGetObjectFromFactoryBean
created, 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 factoryBeanObjectCache
set 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 AOP
the advice
notification 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 BeanPostProcessor
the postProcessAfterInitialization
process, 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:
Not Set Prototype:
Setting a prototype:
Visible in FactoryBean
the 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.