我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Spring中BeanFactory FactoryBean和ObjectFactory的三种的区别

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Spring中BeanFactory FactoryBean和ObjectFactory的三种的区别

Spring中BeanFactory FactoryBean和ObjectFactory的三种的区别

引言

关于FactoryBean 和 BeanFactory的对比文章比较多,但是对ObjectFactory的描述就比较少,今天我们对比下这三种的区别。

结论

BeanFactory就是对象工厂,Spring的底层容器,用于实例化和保存对象。
FactoryBean是一个工厂对象,用于实例化创建过程比较复杂的对象,对象的创建过程是由用户自己控制的。
ObjectFactory是某个特定的工厂,用于在项目启动时,延迟实例化对象,解决循环依赖问题,也就是三级缓存那里会用到,以及结合Scope,灵活方便的实现是否需要创建对象。

BeanFactory

Spring最最核心的接口,Bean工厂,从名字上就能看出这是一个工厂。它是Spring最底层的容器,负责实例化和保存Spring中的Bean。

public interface BeanFactory {

	String FACTORY_BEAN_PREFIX = "&";
	
	Object getBean(String name) throws BeansException;
	
	<T> T getBean(String name, Class<T> requiredType) throws BeansException;
	
	Object getBean(String name, Object... args) throws BeansException;
	
	<T> T getBean(Class<T> requiredType) throws BeansException;

	<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
	
	<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);

	<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
	
	boolean containsBean(String name);
	
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
	
	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

	## 方法很多,不再赘述
}

FactoryBean

public interface FactoryBean<T> {

    //返回的对象实例
    T getObject() throws Exception;
    //Bean的类型
    Class<?> getObjectType();
    //true是单例,false是非单例  在Spring5.0中此方法利用了JDK1.8的新特性变成了default方法,返回true
    boolean isSingleton();
}

我们观察到FactoryBean接口有三个方法。
getObject用来返回实例化后的对象。
getObjectType用来返回对象的类型。
isSingleton用来标识对象是否为单例的,这里默认为true,Spring会将实例化后的对象放入BeanFactory容器中。

从方法上,能推测出,这个凡是实现了FactoryBean接口的类,负责返回这个java类的实例化对象。
从设计模式的角度来看这就是典型的工厂方法模式。由一个特定的工厂来生产特定的java类的实例化对象。

那么这种写法有哪些好处呢?
正常情况下,Spring中在实例化对象的时候,都是由BeanFactory从上下文中获取BeanDefinition信息,然后通过反射,调用这个java类的构造方法进行实例化。而现在这种形式,我们相当于将实例化的功能交给了FactoryBean去实现。这种方式主要使用在一些比较复杂的实例化过程中,并非简单地设置一些参数或者设置的参数过多,过程中可能需要做一些复杂的解析、判断和逻辑处理,这个时候交由Spring去通过反射进行实例化可能就不太灵活了,

Spring容器中有两种Bean,一种是普通的Bean对象,一种是实现了FactoryBean的工厂Bean对象。如果从BeanFactory中getBean的时候,获取到的Bean对象是工厂Bean,会自动的调用它的getObject方法返回真实实例化对象。
如果就是需要获取FactoryBean对象,需要在getBean的时候加上前缀’&'。

Spring自身就对FactoryBean有70多种实现,比较常见的就是Proxy,Jndi等场景。

AOP中使用的ProxyFactoryBean。
Dubbo中使用的ReferenceBean。
Mybatis中使用的SqlSessionFactoryBean。

FactoryBean的着重于自定义创建对象过程,由BeanFactory通过FactoryBean来获取目标对象,而如果是isSingleton返回true的话spring会利用单例缓存来缓存通过FactoryBean创建的对象。

ObjectFactory

public interface ObjectFactory<T> {

    //返回的对象实例
    T getObject() throws BeansException;
}

这用于延迟查找的场景,它就是一个普通工厂,当得到 ObjectFactory 对象时,相当于 Bean 没有被创建,只有当 getObject() 方法时,才会触发 Bean 实例化等生命周期。

一方面在循环依赖的时候,用于延迟初始化,见org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean中调用addSingletonFactory方法,会把ObjectFactory的Lambda表达式放入三级缓存。

另一方面,在AbstractBeanFacotry在doGetBean处的使用时,将创建对象的步骤封装到ObjectFactory中 交给自定义的Scope来选择是否需要创建对象来灵活的实现scope。除此之外ObjectFactory就是一个普通的接口

简单来说就是通过FactoryBean你可以控制对象如何创建,而ObjectFactory借助Scope接口自定义scope你可以控制对象的创建时机也可以用来延迟初始化来解决循环依赖问题。

参考

BeanFactory和FactoryBean对比

补充介绍spring中关于FactoryBean 和 ObjectFactory的认识和区别

FactoryBean:

这个接口使你可以提供一个复杂的逻辑来生成 Bean。它本质是一个 Bean,但这个 Bean 不是用来注 入到其它地方像 Service、Dao 一样使用的,它是用来生成其它 Bean 使用的。实现了这个接口后, Spring 在容器初始化时,把实现这个接口的 Bean 取出来,使用接口的 getObject()方法来生成我们 要想的 Bean。当然,那些生成 Bean 的业务逻辑也要写 getObject()方法中。 其返回的对象不是指定类的一个实例,其返回的是该工厂 Bean 的 getObject 方法所返回的对象。创 建出来的对象是否属于单例由 isSingleton 中的返回决定。

使用场景:

1、通过外部对类是否是单例进行控制,该类自己无法感知
2、在创建 Object 对象之前进 行初始化的操作,在 afterPropertiesSet()中完成。(一次性的初始化,保存在成员变量中,并不是 每次 getObject 都会调用 afterPropertiesSet,afterPropertiesSet 只会被调用一次)

ObjectFactory:

它的目的也是作为一个工厂,来生成 Object(这个接口只有一个方法 getObject())。这个接口一般被 用来,包装一个 factory,通过个这工厂来返回一个新实例(prototype 类型)。这个接口和 FactoryBean 有点像,但 FactoryBean 的实现是被当做一个 SPI(Service Provider Interface)实例来使用在 BeanFactory 里面;ObjectFactory 的实现一般被用来注入到其它 Bean 中,作为 API 来使用。就像ObjectFactoryCreatingFactoryBean 的 例 子 , 它 的 返 回 值 就 是 一 个 ObjectFactory , 这 个 ObjectFactory 被注入到了 Bean 中,在 Bean 通过这个接口的实例,来取得我们想要的 Bean。

总的来说,FactoryBean 和 ObjectFactory 都是用来取得 Bean,但使用的方法和地方不同, FactoryBean 被配置好后,Spring 调用 getObject()方法来取得 Bean,ObjectFactory 配置好后, 在 Bean 里面可以取得 ObjectFactory 实例,需要我们手动来调用 getObject()来取得 Bean。

到此这篇关于Spring中BeanFactory FactoryBean和ObjectFactory的三种的区别的文章就介绍到这了,更多相关BeanFactory FactoryBean和ObjectFactory区别内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Spring中BeanFactory FactoryBean和ObjectFactory的三种的区别

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Spring中BeanFactory FactoryBean和ObjectFactory的三种的区别

关于FactoryBean 和 BeanFactory的对比文章比较多,但是对ObjectFactory的描述就比较少,今天我们对比下这三种的区别,感兴趣的朋友跟随小编一起看看吧
2023-01-17

Spring BeanFactory与FactoryBean的区别是什么

这篇文章主要介绍了Spring BeanFactory与FactoryBean的区别是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Spring BeanFactory与FactoryBean的区别是什么文
2023-06-30

BeanFactory和FactoryBean的区别示例详解

这篇文章主要为大家介绍了BeanFactory和FactoryBean的区别示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-13

Access、Truck和Hybrid三种端口模式的区别

  以太网端口有三种链路类型:Access、Truck和Hybrid。这三种链路类型的连接终端有所区别。不是很了解由想学习的朋友,下面就和我们一起来学习吧!  Access端口:  一般连接主机  只允许与该端口的PVID相同的VLAN通过,收到untagged的数据帧,强制打上本端口PVID的标签;  Trunk端口
Access、Truck和Hybrid三种端口模式的区别
2024-04-18

Linux Shell中三种引号的用法及区别

Linux Shell中有三种引号,分别为双引号(" ")、单引号(' ')以及反引号(` `)。 其中双引号对字符串中出现的$、''、`和进行替换;单引号不进行替换,将字符串中所有字符作为普通字符输出,而反引号中字符串作为shell命令执
2022-06-04

VMware中三种网络连接的区别是什么

这篇文章跟大家分析一下“VMware中三种网络连接的区别是什么”。内容详细易懂,对“VMware中三种网络连接的区别是什么”感兴趣的朋友可以跟着小编的思路慢慢深入来阅读一下,希望阅读后能够对大家有所帮助。下面跟着小编一起深入学习“VMwar
2023-06-28

Spring中接口注入的三种方式分别是什么

本篇文章为大家展示了Spring中接口注入的三种方式分别是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Spring中 接口注入的三种方式,上面的代码中,ClassA依赖于InterfaceB的
2023-06-17

Spring Boot中@PathVariable、@RequestParam和@RequestBody的区别和使用

title: springboot中@PathVariable、@RequestParam和@RequestBody的区别和使用 date: 2020-11-02 tags: springspringbootspring注解注解@Requ
2023-08-30

python中np.multiply()、np.dot()和星号(*)三种乘法运算的区别有哪些

这篇文章主要介绍python中np.multiply()、np.dot()和星号(*)三种乘法运算的区别有哪些,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!为了区分三种乘法运算的规则,具体分析如下:import nu
2023-06-14

浅谈Spring框架中@Autowired和@Resource的区别

最近review别人代码的时候,看到了一些@Autowired不一样的用法,觉得有些意思,下面这篇文章主要给大家介绍了关于Spring框架中@Autowired和@Resource区别的相关资料,需要的朋友可以参考下
2022-11-13

Linux Shell中三种引号的用法及区别是什么

这篇文章主要为大家展示了“Linux Shell中三种引号的用法及区别是什么”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Linux Shell中三种引号的用法及区别是什么”这篇文章吧。Linu
2023-06-09

Spring注解中@Configuration和@Component的区别是什么

本文小编为大家详细介绍“Spring注解中@Configuration和@Component的区别是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“Spring注解中@Configuration和@Component的区别是什么”文章能
2023-07-05

spring中@Autowire和@Resource的区别在哪里(推荐)

这篇文章主要介绍了spring中@Autowire和@Resource的区别在哪里?本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
2023-02-17

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录