一文给你讲清楚 BeanFactory 和 FactoryBean 的关联与区别
本文分享自华为云社区 《BeanFactory 和 FactoryBean 的关联与区别》,作者:战斧。
一、概括性的回答
两者其实都是 Spring 提供的接口,如下
BeanFactory 就是我们常说的 Spring 容器,其内包含着大量的 Bean,我们可以从 BeanFactory 获取到想要的 Bean,或者查询 Bean 的一些信息。
而 FactoryBean 则是众多 Bean 里的一种,只不过这种 Bean 是一种辅助 Bean 或者说中间人,它的作用是为你提供另一个/一些 Bean。
两者一个比较形象的比喻就是 BeanFactory 就是一家工厂,我们可以通过提供物品名字,从工厂中得到各式各样的物品,比如桌椅板凳,键盘鼠标 等等。而除此之外,我们还能获取一种比较特殊的物品——生产线(FactoryBean),一般情况下,我们获取生产线当然不是为了它本身,而是为了利用生产线生产出产品,所以当你提供生产线的名字,得到的其实是生产线生产的产品。当然,如果你就是想取这个生产线本身,那你提供的名字就得是 “&” + 生产线名。
二、FactoryBean
FactoryBean 示例
我们先来看一下 FactoryBean 的基础用法,简而言之就是实现 FactoryBean 接口,然后重写其中的 getObject 方法,如下:
然后把这个 factoryBean 放入容器中,你可以采用 xml 或者 @Bean 等形式注入。
FactoryBean 的必要性
我们上面介绍过,FactoryBean 其实相当于一个中间人,我们获取它,往往不是需要它本身,而是希望通过它获得另一个 Bean,自然的我们会产生疑问,为什么要多此一举?如果我们通过它是为了获得另一个 Bean,那么为什么不直接实例化另一个 Bean 然后放入 Spring 容器呢?比如在方法上使用 @Bean 注解。
这种想法无可厚非,主要是因为 factoryBean 接口的诞生更早,所以早期很多的结构采用了这种方式。后续有了 @Bean 注解以后,在方法上使用 @Bean 注解也能实现复杂 Bean 的创建了。
那是不是所有情况都能使用 @Bean 来替代 factoryBean 呢?比如我们想每次获取的 Bean 都是实时的,又比如我们需要一个计时器 Bean,但你注入的 Bean 都被固定了,只有通过工厂,才能每次获取都能得到一个实时的新 Bean。同样的,使用 factoryBean 还有一个懒加载的作用,对于某些复杂的 Bean 能在获取时再进行实例化。
三、BeanFactory
BeanFactory 与 ApplicationContext
提及 BeanFactory,自然而然的我们会想到 Spring 的重要特性 IOC,IOC 要求有一个能管理所有 Bean 的管家,而管家需要一个盛放这些 Bean 的容器,这个容器就是 BeanFactory。
尽管我们在日常项目中,使用的容器是具有更全功能的 ApplicationContext,但 ApplicationContext 也是 BeanFactory 的子接口,其除了单纯的容器功能外,还有配置元信息,应用事件机制,资源管理等功能,所以我们可以说 ApplicationContext 是 BeanFactory 的增强版本。
BeanFactory 的使用
在早期的 spring 项目中,我们经常会在代码中指定使用某种 BeanFactory ,并且使用如下方式去加载资源。
顾名思义 XmlBeanFactory 就是能够读取并解析 xml 资源,解析出各种 Bean 后存入自身,而在后期,springboot 的大规模使用后,其内置的工厂可以解析 xml、properties 以及注解等多种配置来源。
当然,其实 Spring 本身就有相当的自动化程度,比如当我们在启动类上使用。
它也能导入内容,并根据资源后缀是否为".groovy"判断是使用 GroovyBeanDefinitionReader.class 还是 XmlBeanDefinitionReader.class,对资源解析完成后,把 Bean 定义注册进 BeanFactory 中。
四、总结
我们应当发现了:BeanFactory 和 FactoryBean 除了名字相似、都能包含一些 Bean 实例之外,其实没有什么相同的地方。前者是 SpringIOC 的核心,是存放一切 Bean 的容器;后者只不过是对复杂 Bean 的一种包装,比如我们常用的 myBatis 组件,针对各个 mapper 级接口生成的 Bean 实例,就是以 FactoryBean 的形式存在 Spring 容器中的。
版权声明: 本文为 InfoQ 作者【华为云开发者联盟】的原创文章。
原文链接:【http://xie.infoq.cn/article/7e48a9c19d187a1827436a118】。文章转载请联系作者。
评论