Interpretation of Spring 5.x source Tour fourteen isFactoryBean method
- isFactoryBean (String name) to determine whether the name is based on FactoryBean
- After conversion the name of transformedBeanName
- getSingleton (String beanName, boolean allowEarlyReference) Example acquisition unit
- isFactoryBean (String beanName, RootBeanDefinition mbd) The name and determines whether the bean definition FactoryBean
- Get FactoryBean
- to sum up
isFactoryBean (String name) to determine whether the name is based on FactoryBean
We continue to Part I, Part I talked about getMergedLocalBeanDefinition
, and why should this, in terms of the latter Benpian isFactoryBean
methods, how to judge a beanName
whether it is FactoryBean
type. getBean
More complex, talk back together temporarily to know that you can get an object like herein, this talk about this part:
@Override
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
String beanName = transformedBeanName(name);//获取转换后的名字
Object beanInstance = getSingleton(beanName, false);
if (beanInstance != null) {//如果已经是单例了,就判断是否是FactoryBean类型
return (beanInstance instanceof FactoryBean);
}
// 没有单例,看是否有bean定义,没有就看父类bean工厂
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
}
return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}
After conversion the name of transformedBeanName
We look at this conversion name, in fact, to keep up with papers say FactoryBean
the name of the relevant, we look at the source of it:
protected String transformedBeanName(String name) {
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
BeanFactoryUtils的transformedBeanName
First, judgment is not a &
prefix, there is no direct return, indicating not FactoryBean
name, otherwise they are taken from the cache, and then the prefix &
removed to return.
public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null");
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;
});
}
canonicalName remove the original name
Standardization for name, in fact, remove the original name, if the original name is an alias he took from the map, it is the original name of the direct return.
public String canonicalName(String name) {
String canonicalName = name;
// Handle aliasing...
String resolvedName;
do {
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
return canonicalName;
}
getSingleton (String beanName, boolean allowEarlyReference) Example acquisition unit
This method is passed a name and whether to allow early references, this is a circular dependency in order to solve the problem, this will speak later, now on the line is ignored. singletonObjects
Is a ConcurrentHashMap
, put already created a single case, if found to have created, direct return, or to determine whether you are creating isSingletonCurrentlyInCreation
, earlySingletonObjects
is HashMap
used to create a single case cited save the run early, in order to resolve circular dependencies. We may wonder why earlySingletonObjects
not ConcurrentHashMap
, in fact, because of all his operations are in synchronized
sync block, so do not need, and singletonObjects
can be used where there is no sync block. Went on to say that if earlySingletonObjects
did not find, but also allow early referenced from singleton to singletonFactories
get a factory plant, in fact, can obtain a factory object, as long as there is, we can through getObject()
acquisition, and then into earlySingletonObjects
, delete the factory, in fact, there are circular references when you can put to use, it goes on to say.
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
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;
}
Are isSingletonCurrentlyInCreation being created
singletonsCurrentlyInCreation
This is the name of a single case set storage being created, it can be judged whether being created.
public boolean isSingletonCurrentlyInCreation(String beanName) {
return this.singletonsCurrentlyInCreation.contains(beanName);
}
isFactoryBean (String beanName, RootBeanDefinition mbd) The name and determines whether the bean definition FactoryBean
If FactoryBean
singleton did not get to this time only by name and bean
define whether it is to see FactoryBean
the. If the definition itself is defined isFactoryBean
, it returns the result directly, or need to be the type of prediction, he will reflect, to see if the name of the corresponding class is the FactoryBean
type if the type is predicted FactoryBean
, then returned true
, and otherwise false
.
protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
Boolean result = mbd.isFactoryBean;
if (result == null) {
Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
result = (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
mbd.isFactoryBean = result;
}
return result;
}
Get FactoryBean
If you find the name of FactoryBean
the type, you would add the prefix before the name &
, then go get, get over to determine whether FactoryBean type, that is the case then determine whether you need to understand to create FactoryBean
objects, and if so directly obtain the name, this time name is no & prefix, also direct access to FactoryBean
the getObject()
object method creates. Of course, if the name is not a FactoryBean
type, then it direct access to the object.
to sum up
This part is to create a single case, if found to be FactoryBean
type, then get FactoryBean, and then determine whether you need immediate getObject()
object methods created, if required, will be created. If this is not FactoryBean
the type, then it direct access to create objects.
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.