• Spring中FactoryBean与BeanFactory的区别


    版本:spring-framework-4.1

    一概述

    BeanFactory 与 FactoryBean的区别, 两个名字很像,面试中也经常遇到,所以容易搞混,现从源码以及示例两方面来分析。

    二、源码

    2.1 BeanFactory

    BeanFactory定义了 IOC 容器的最基本形式,并提供了 IOC 容器应遵守的的最基本的接口,也就是 Spring IOC 所遵守的最底层和最基本的编程规范。

    BeanFactory仅是个接口,并不是IOC容器的具体实现,具体的实现有:如 DefaultListableBeanFactory 、 XmlBeanFactory 、 ApplicationContext 等。

    public interface BeanFactory {
        //FactoryBean前缀
        String FACTORY_BEAN_PREFIX = "&";
    
        //根据名称获取Bean对象
        Object getBean(String name) throws BeansException;
    
        ///根据名称、类型获取Bean对象
        <T> T getBean(String name, Class<T> requiredType) throws BeansException;
    
        //根据类型获取Bean对象
        <T> T getBean(Class<T> requiredType) throws BeansException;
    
        //根据名称获取Bean对象,带参数
        Object getBean(String name, Object... args) throws BeansException;
    
        //根据类型获取Bean对象,带参数
        <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
    
        //是否存在
        boolean containsBean(String name);
    
        //是否为单例
        boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
    
        //是否为原型(多实例)
        boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
    
        //名称、类型是否匹配
        boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;
    
        //获取类型
        Class<?> getType(String name) throws NoSuchBeanDefinitionException;
    
        //根据实例的名字获取实例的别名
        String[] getAliases(String name);
    }
    

    2.1 FactoryBean

    FactoryBean工厂类接口,用户可以通过实现该接口定制实例化 Bean 的逻辑。

    public interface FactoryBean<T> {
    
        //FactoryBean 创建的 Bean 实例
        T getObject() throws Exception;
    
        //返回 FactoryBean 创建的 Bean 类型
        Class<?> getObjectType();
    
        //返回由 FactoryBean 创建的 Bean 实例的作用域是 singleton 还是 prototype
        boolean isSingleton();
    }
    

    三、示例

    3.1 普通bean

    public class Dog {
        private String msg;
    
        public Dog(String msg){
            this.msg=msg;
        }
        public void run(){
            System.out.println(msg);
        }
    }
    

    3.2 实现了FactoryBean的bean

    public class DogFactoryBean implements FactoryBean<Dog>{
    
        public Dog getObject() throws Exception {
            return new Dog("DogFactoryBean.run");
        }
    
        public Class<?> getObjectType() {
            return DogFactoryBean.class;
        }
    
        public boolean isSingleton() {
            return false;
        }
    }
    

    3.3 配置文件

    <bean id="dog" class="com.bean.Dog" >
        <constructor-arg value="Dog.run"/>
    </bean>
    
    <bean id="dogFactoryBean" class="com.bean.DogFactoryBean" />
    

    3.4 测试

    @Test
    public void testBean() throws Exception {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    
        Dog dog1 = (Dog) ctx.getBean("dog");
        dog1.run();
    
        Dog dog2 = (Dog) ctx.getBean("dogFactoryBean");
        dog2.run();
    
        //使用&前缀可以获取FactoryBean本身
        FactoryBean dogFactoryBean = (FactoryBean) ctx.getBean("&dogFactoryBean");
        Dog dog3= (Dog) dogFactoryBean.getObject();
        dog3.run();
    }
    

    结果输出:

    Dog.run
    DogFactoryBean.run
    DogFactoryBean.run
    

    四、总结

    通过以上源码和示例来看,基本上能印证以下结论,也就是二者的区别。

    1. BeanFactory是个Factory,也就是 IOC 容器或对象工厂,所有的 Bean 都是由 BeanFactory( 也就是 IOC 容器 ) 来进行管理。

    2. FactoryBean是一个能生产或者修饰生成对象的工厂Bean,可以在IOC容器中被管理,所以它并不是一个简单的Bean。当使用容器中factory bean的时候,该容器不会返回factory bean本身,而是返回其生成的对象。

      注:文章中难免有不足之处,欢迎评论、互动、指正。

    作者: i-nine
    原创不易,本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    乐视电视修改五大图标
    Google Home Mini配置失败解决办法
    使用FreeHttp任意篡改http报文 (FreeHttp使用及实现说明)
    IDEA和VS快捷键对比
    C# 中的字符串内插
    在线运行.NET代码
    在Windows服务器安装ss服务端用于逃脱公司行为管理
    .NET Core的代码安全分析工具
    用DotNetDetour HOOK .net类库
    C#代码获取另一程序的错误提示,并关闭窗口。
  • 原文地址:https://www.cnblogs.com/ninth/p/6405366.html
Copyright © 2020-2023  润新知