文章详情

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

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2023-01-17 12:01

关注

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

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯