首页 > spring > BeanFactory和FactoryBean区别

BeanFactory和FactoryBean区别

作者:bin

先上图,看下图中beanFactory和FactoryBean各在哪

实际上都是2各接口,一个提供了bean的管理能力,另一个提供了bean自定义的创建模式。

AbstractBeanFactory这个抽象类同时实现了这两个接口。

FactoryBean接口的源码

public interface FactoryBean {
   //获取对象实例的方法
   T getObject() throws Exception;
   //获取对象类型
   Class<?> getObjectType();
   //对象是否是单例模式
   boolean isSingleton();
}

spring在加载FactoryBean时的源码,我们查看AbstractBeanFactory的getObjectForBeanInstance()方法:

protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
    ...
    //如果不是FactoryBean,或者是要找FactoryBean的原bean(即实现FactoryBean接口的那个bean),就直接返回
    if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
        return beanInstance;
    }

    Object object = null;
    if (mbd == null) {
        //从缓存中找
        object = getCachedObjectForFactoryBean(beanName);
    }
    if (object == null) {
        ...
        //获取bean实体
        object = getObjectFromFactoryBean(factory, beanName, !synthetic);
    }
    return object;
}

我们查看getObjectFromFactoryBean的源码:

 
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) {
                //从FactoryBean中取
                object = doGetObjectFromFactoryBean(factory, beanName);
                ...
            }
        }
    ...
}

我们继续深入doGetObjectFromFactoryBean方法,可以清楚的看到,调用FactoryBean的接口,获取bean实体:

  
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
        throws BeanCreationException {
    Object object;
    try {
        if (System.getSecurityManager() != null) {
          ...
        }
        else {
            //调用FactoryBean的接口,获取bean实体
            object = factory.getObject();
        }
    }
    ...
    return object;
}

您必须 [ 登录 ] 才能发表留言!