BeanFactory和FactoryBean有什么区别?

2022-06-07 21:35:45 浏览数 (1)

BeanFactory和FactoryBean有什么区别?

此问题考验的是对spring框架的熟悉度,我们知道spring框架的核心点在于IOC容器,IOC容器的功能就是注入bean,生产bean,而生成bean以工厂模式最好,所以sping就搞了个工厂去专门生成bean,这个工厂就是BeanFactory。

那么什么又是FactoryBean呢?

从名字上看,它就是一个bean,你这么理解它也是没错的,因为它本身具备了一个bean的功能,同时它也是一个接口,只不过它具有一些特殊的功能。以下面的编码来说明:

代码语言:javascript复制
/**
 * @className: MyFactoryBean
 * @Description: TODO 自定义FactoryBean
 * @version: v1
 * @author: GONGWENXUE
 * @date: 2022/5/19 11:46
 */
@Component("MyFactoryBean")
public class MyFactoryBean implements FactoryBean {

    /**
     * @Author GONGWENXUE
     * @Description //TODO 此方法返回要注入的bean,也就是@Component("xx"),
     *               外界取值时用"xx" 取到的是getObject()返回的对象
     *               如果想取MyFactoryBean,需要在注入的key值前   &,也就是"&xx"
     * @version: v1
     * @Date 11:48 2022/5/19
     * @Param
     * @return
     **/
    @Override
    public Object getObject() throws Exception {
        System.out.println("返回MyFactoryBean的getObject对象");
        Object o = new Object();
        return o;
    }

    @Override
    public Class<?> getObjectType() {
        return MyFactoryBean.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}

测试:

代码语言:javascript复制
 public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        Object myFactoryBean = context.getBean("myFactoryBean");
        System.out.println(myFactoryBean);
    }

appConfig:

代码语言:javascript复制
@Configuration
public class AppConfig {

    @Bean("myFactoryBean")
    public MyFactoryBean getMyBean() {
        return new MyFactoryBean();
    }
}

结果:

从结果中可以看出取到的对象是getObject()中返回的String对象,而不是MyFactoryBean对象。那么如何取原本的MyFactoryBean对象呢?

在注入key值前面 &

从上图可以看出加了&符号就取出了原本的对象。那么spring为啥这么设计呢?

其实这是spring的作者有意向放权给用户,让用户自定义自己的逻辑,因为在现实的项目开发中,有很多第三方的依赖,他们是没有交给spring去管理的,无法使用spring的规则正常的注入到容器中使用,我们也很难使用xml配置文件,或者注解一个个的将第三方依赖,以及第三方的第三方的N多层级依赖都手动注入到spring容器中。这时候就需要一种方式与spring进行对接,于是就有了FactoryBean就诞生了,比如我们常用的Mybatis也是使用了FactoryBean。这种方式的好处就是让第三方依赖于spring容器接入时,不再需要用户去维护第三方依赖所依赖的众多关系,让接入者维护好这些关系,通过FactoryBean再一次性叫给spring去管理。所以mybatis创建了一个

SqlSessionFactory用于维护好mybatis所需要的各种依赖环境,用户只需要将SqlSessionFactory交给spring管理即可。

除此之外,FactoryBean还有两个方法getObjectType()和isSingleton(),他们分别返回对象的类型字节码,和是否单例,完全由用户决定返回的值。

总结:

1.BeanFactory是spring的bean工程,生产管理bean;

2.FactoryBean是一个spring开放给用户自定义bean的接口,以方便第三方技术的接入和自定义的需要。继承FactoryBean的实现类交给spring管理后,会以懒加载的方式,用到的时候才初始化,并产生两个对象注入给spring,其中getObject()的返回值对象以@Component("key")的方式注入,FactoryBean的实现类以@Component("&key")的方式注入。

0 人点赞