简介
FactoryBean 也是spring 所管理的bean,允许用户自定义返回的bean对象
spring获取bean核心方法就是doGetBean,那么就从这里为入口开始分析
以下代码为了控制篇幅,有可能会进行删减
doGetBean
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
final String beanName = transformedBeanName(name);
Object sharedInstance = getSingleton(beanName);//从单例池里里面获取FactoryBean对象
if (sharedInstance != null && args == null) {
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
...
}
transformedBeanName(name)
String FACTORY_BEAN_PREFIX = "&";
public static String transformedBeanName(String name) {
String beanName = name;
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
return beanName;
}
可以看到,这里判读是否为&开头,如果是以&开头,就会截掉&,然后返回beanName
这个&的作用就是用于判断用户是想获取FactoryBean本身还是想获取FactoryBean返回的Bean
public String canonicalName(String name) {
String canonicalName = name;
String resolvedName;
do {
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
return canonicalName;
}
对返回的BeanName进行判断是否存在,这里可以看到aliasMap,很明显和这个map和别名相关,这里也这是进行别名转换的逻辑了
getObjectForBeanInstance
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;// !!!
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
return object;
}
这里可以看到对刚才从单例池里获取bean 进行了强转
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
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 {
object = postProcessObjectFromFactoryBean(object, beanName);
this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
}
}
return (object != NULL_OBJECT ? object : null);
}
}
这里的factoryBeanObjectCache 是一个缓存,第一次获取一般是没有的,真正获取bean的逻辑在doGetObjectFromFactoryBean
这个方法比较简单就不贴代码了,能在方法里面清楚的看到调用FactoryBean的getObject 方法
这里再关注一下postProcessObjectFromFactoryBean(…) 这个方法,这里会回调后置处理器,不过默认这些逻辑没有做任何处理
最后就是将这个对象添加到缓存,下次获取的时候直接从缓存获取,然后就返回了
总结
1.对beanName进行转换
2.转换后先从缓存里面尝试获取
3.获取不到就调用getObject方法
4.调用后置处理器的postProcessAfterInitialization
5.添加缓存,结果返回