Spring的FactoryBean

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();

}

执行流程

Spring中FactoryBean的获取流程

源码分析

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;
   }
}
上一篇
下一篇