BeanFactory和FactoryBean
简单来说,BeanFactory与FactoryBean都是Spring的Bean工厂。BeanFactory使用getBean()生成Bean,FactoryBean使用getObject()生成Bean。 其中,BeanFactory生成的Bean需要严格遵循Spring中Bean的创建和销毁流程,例如实例化、注入、初始化、BPP等;而FactoryBean生成的Bean是自定义的,不遵循Spring中Bean的创建和销毁流程。 此外,FactoryBean也是BeanFactory生成的Bean。
FactoryBean接口定义
public interface FactoryBean<T> {
// 工厂方法,获取对象
T getObject() throws Exception;
// 获取对象类型
Class<?> getObjectType();
// 对象是否是单例的
boolean isSingleton();
}
执行流程
源码分析
doGetBean
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
// 将输入的name转换成singletonObjects(一级缓存)中的key,具体逻辑如下
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// 这里,我们直接从singletonObjects(一级缓存)中获取beanFactory对象
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 获取最终的bean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
...
}
public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null");
String beanName = name;
// 判name断是否包含FACTORY_BEAN_PREFIX(&),如果包含,去掉
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
// 返回处理后的beanName
return beanName;
}
举个例子:
<bean id="factoryBean" class="xxx"> </bean>
beanFactory.getBean("factoryBean")
:获取factoryBean生成的对象beanFactory.getBean("&factoryBean")
:获取factoryBean本身
其中,&
就是上文的FACTORY_BEAN_PREFIX
getObjectForBeanInstance
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
// 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.
// 如果当前的beanInstance不是FactoryBean,或者name以&开头(获取factoryBean本身)
// 则返回beanInstance
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
Object object = null;
if (mbd == null) {
// 首先尝试从缓存中获取,注意这里的缓存不是singletonObjects,
// 而是factoryBeanObjectCache
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
......
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
getObjectFromFactoryBean
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
// 如果FactoryBean是单例的,并且已经完成创建了
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
// 尝试从缓存中取
Object object = this.factoryBeanObjectCache.get(beanName);
// 如果缓存中没有,调用factoryBean的getObject方法
if (object == null) {
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
......
// 将创建完成的object放到factoryBeanObjectCache中
if (containsSingleton(beanName)) {
this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
}
}
}
return (object != NULL_OBJECT ? object : null);
}
}
// 如果FactoryBean是原型的,则不使用缓存
else {
Object object = doGetObjectFromFactoryBean(factory, beanName);
......
return object;
}
}