BeanFactory和FactoryBean的区别

BeanFactory

简介

BeanFactory是Spring容器的Root Interface,提供了 IOC 容器最基本的功能。
BeanFactory只是一个接口,没有具体的实现,但是它的实现类如XmlBeanFactory,ApplicationContext在其基础之上附加了其他的功能。

源码


public interface BeanFactory {

    /**
     *
     */
    String FACTORY_BEAN_PREFIX = "&";


    /**
     *  这个方法是BeanFactory的主要方法,通过指定名字可以取得IOC容器中相应的Bean对象
   *  这种方法使得Spring BeanFactory代替单例或原型设计模式来获取Bean对象
     */
    Object getBean(String name) throws BeansException;

    /**
     * 也是获取Bean对象的方法,但是增加了Class类型的安全验证机制
   * 如果类型不符,则跑出BeanNotOfRequiredTypeException异常
     */
    <T> T getBean(String name, Class<T> requiredType) throws BeansException;

    /**
     * 通过Bean类型获取bean实例
     */
    <T> T getBean(Class<T> requiredType) throws BeansException;

    /**
     * 传入的参数什么用途 暂时不清楚
     */
    Object getBean(String name, Object... args) throws BeansException;

    /**
     *
     */
    <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;


    /**
     * 判断是否含有指定名字的bean对象
     */
    boolean containsBean(String name);

    /**
     *判断指定名称的bean对象是否是单例,如果是,则永远返回同一个对象
   * 可以在 BeanDefinition中设置
     */
    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

    /**
     * 判断Bean是不是prototype的bean,是的话 返回独立的实例
     */
    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

    /**
     *
     */
    boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

    /**
     * 判断指定名称的bean对象的Class类型是否是特定的Class类型。
     */
    boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

    /**
     * 获取指定名称bean对象的Class类型
     */
    Class<?> getType(String name) throws NoSuchBeanDefinitionException;

    /**
     *查询指定了名字的bean的所有别名,这些别名都是在BeanDefinition中定义的
     */
    String[] getAliases(String name);

}

FactoryBean

简介

FactoryBean是一个接口,当在IOC容器中的Bean实现了FactoryBean后,通过getBean(String BeanName)获取到的Bean对象并不是FactoryBean的实现类对象,而是这个实现类中的getObject()方法返回的对象。如果要获取FactoryBean对象,在beanName前面加一个&符号来获取,如:getBean(&BeanName)。

源码

getBean

protected <T> T doGetBean(
        final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
        throws BeansException {

    final String beanName = transformedBeanName(name);
    Object bean;

    // Eagerly check singleton cache for manually registered singletons.
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        //。。。。
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    else {

        // 。。。。。
        if (mbd.isSingleton()) {
            //。。。。。
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
        }

        else if (mbd.isPrototype()) {
            // 。。。。
            bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
        }

        else {
                //scope获取Bean。。。。
                bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);

        }


    }

    // ......
    return (T) bean;
}

我们在获取Bean的过程中会发现,不管是从单例缓存还是新创建Bean过程中单例、原型或者Scope获取Bean之后都会调用getObjectForBeanInstance()方法。

getObjectForBeanInstance

protected Object getObjectForBeanInstance(
        Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {

    //  要获取的Bean是带有&符号,并且beanInstance不是FactoryBean则抛出异常
    if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
        throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
    }

    // beanInstance不是FactoryBean或者要获取的Bean不带有&符号,直接返回beanInstance
    if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
        return beanInstance;
    }

    Object object = null;
    if (mbd == null) {
        //尝试从FactoryBean的缓存中获取
        object = getCachedObjectForFactoryBean(beanName);
    }
    if (object == null) {
        // Return bean instance from factory.
        FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
        // Caches object obtained from FactoryBean if it is a singleton.
        if (mbd == null && containsBeanDefinition(beanName)) {
            mbd = getMergedLocalBeanDefinition(beanName);
        }
        boolean synthetic = (mbd != null && mbd.isSynthetic());
        //通过FactoryBean#getObject()方法获取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) {
                    //实际调用getObject方法的地方
                    object = doGetObjectFromFactoryBean(factory, beanName);
                    Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                    if (alreadyThere != null) {
                        object = alreadyThere;
                    }
                    else {
                        if (object != null && shouldPostProcess) {
                            try {
                                object = postProcessObjectFromFactoryBean(object, beanName);
                            }
                            catch (Throwable ex) {
                                throw new BeanCreationException(beanName,
                                        "Post-processing of FactoryBean's singleton object failed", ex);
                            }
                        }
                        this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
                    }
                }
                return (object != NULL_OBJECT ? object : null);
            }
        }
        else {
            Object object = doGetObjectFromFactoryBean(factory, beanName);
            if (object != null && shouldPostProcess) {
                try {
                    object = postProcessObjectFromFactoryBean(object, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
                }
            }
            return object;
        }
}

应用

Spring的Aop的工厂ProxyFactoryBean就是一个FactoryBean,具体可以参考Sring源码分析——AOP

总结

除了名字很相似外,其他没有任何可比性,只要充分了解彼此间的特性,就不会有任何混淆了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值