Spring 为什么会有 FactoryBean?

简介: 常说 spring 的核心是 ioc,ioc 的核心是 BeanFactory。然而在 spring 中还有一个很容易让人混淆的词FactoryBean。本文通过一些 mybatis 源码来讲述其区别,请大家参考。另外,关注公众号Java技术栈,在后台回复:面试,可以获取我整理的 Java、Spring 系列面试题和答案,非常齐全。

前言

常说 spring 的核心是 ioc,ioc 的核心是 BeanFactory。然而在 spring 中还有一个很容易让人混淆的词FactoryBean。


本文通过一些 mybatis 源码来讲述其区别,请大家参考。另外,关注公众号Java技术栈,在后台回复:面试,可以获取我整理的 Java、Spring 系列面试题和答案,非常齐全。


一、为什么会有FactoryBean?

BeanFactory是在学习 IOC 第一课的时候就遇到的,它是生产 bean 的工厂,在此工厂中,我们可以生产出我们想要的 bean,并且通过getBean接口进行获取。


但是在通过getBean获取 bean 之前,我们需要事先定义这个 bean 长什么样子,或者说它由哪些组件组成。


定义的方式有很多,可以通过xml进行定义,或者在代码中通过注解(@Bean、@Service)进行定义。


就好比一个 Controller,在最原始的 xml 配置 bean 的时候,我们需要定义它是由哪些service组成,然后一点点的配置好,xml要与 Controller 的service一一对应起来。


image.png


这种方式的弊端是所有的bean都需要事先定义好,但是有时候,有的一些bean,我们只知道它大概的样子,但是无法事先定义出其具体的功能。就好比,我们知道它是一只鸟,但是不知道是什么种类的鸟,只有在代码执行的时候,我才知道是什么种类的鸟。


如此表达可能不太直观,这里可以直接联想出mybatis中的mapper,例如UserMapper。

image.png

在定义UserMapper的时候,我们知道其最后执行的xml的sql语句。而且这样的mapper又很多,可能还会有更多的OrderMapper、GoodsMapper等等。 如果每一个都一一定义的话,会非常的麻烦。


但是,我们发现mapper中的功能都是与数据库交互的代码。因此规范其写法,通过定义一些标准的写法,就可以简化其定义过程。这样便出现了@Select注解和@Update注解(还有xml的标签),这样我们只需要在注解中写入对应的sql,在代码执行时候,执行对应的sql。


这样一想可以认为是所有的mapper就是鸟,但是不知道它是什么鸟,或者这个鸟是做什么的(不知道每个mapper的功能),在真正创建它的时候,才去关注它具体的内容。


这样FactoryBean的就有了其意义,它可以定义出一种类型的Bean,并且在创建的时候再去实现其具体的功能。


里面有三个方法:


getObject 获取bean方法,在此方法中,我们可以自己定义一个对象,然后自行修改其创建过程。通过这个方法,我们可以在mapper创建的时候再实现其具体的功能。

getObjectType 获取这类的类型。

isSingleton 是否单例。

public interface FactoryBean<T> {
    String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
    @Nullable
    T getObject() throws Exception;
    @Nullable
    Class<?> getObjectType();
    default boolean isSingleton() {
        return true;
    }
}

二、通过源码深入学习FactoryBean

如果还没有理解FactoryBean,我们可以通过学习mybatis源码,来更加深入的了解FactoryBean。


这里带领大家了解下Mybatis的MapperFactoryBean,这个是生成Mapper的FactoryBean。


image.png


大家可以自行打开源码查看,通过上图的流程即可发现,每一个mapper是通过MapperFactoryBean的getObject方法进行创建,最后生成一个代理类。


相信跟一下mybatis的源码之后,对FactoryBean会有更加深入的理解。


虽然在开发时用FactoryBean的机会并不多,但是源码中会经常遇到,例如spring cloud的feign组件,里面肯定也会看到FactoryBean的身影。


对于 mybatis 和 feign,可以很轻松的发现其共同点:


存在一种类型的bean。mybatis是Mapper,feign是FeignClient。

这种bean功能单一。mapper只跟数据库做交互。FeignClient只是接口调用。

还有我们常用的定时器框架 quartz 框架,里面也有 JobDetailFactoryBean,Redis 中有 RedisClientFactoryBean,security 框架的 UserDetailsManagerResourceFactoryBean。


其实他们都是有一个共同的特点,就是生产的 bean 是一种类型,在创建的过程中在实现其功能。


到这是不是已经理解了FactoryBean呢?


本文来自作者「叁滴水」投稿,谢谢分享,也欢迎爱好技术分享的各位技术朋友向「Java技术栈」投稿,让更多人看到,投稿方式:关注公众号「Java技术栈」在后台回复:投稿


相关文章
|
Java 关系型数据库 MySQL
Spring5深入浅出篇:Spring中的FactoryBean对象
Spring5深入浅出篇:Spring中的FactoryBean对象
|
Java Spring 容器
Spring中BeanFactory和FactoryBean的区别?
一位工作了4年的小伙伴,去京东面试被问到这样一个问题,Spring中的BeanFactory和FactoryBean有什么区别?因为没有看过源码,当时就感觉这是一个文字游戏,感觉没什么区别? 那今天,我就给大家来聊清楚。另外,往期面试题解析中配套的文档我已经准备好,想获得的可以在我的煮叶简介中找到。好了,我们先来看BeanFactory。
189 0
|
XML Java 数据格式
spring中怎么通过静态工厂和动态工厂获取对象以及怎么通过 FactoryBean 获取对象
spring中怎么通过静态工厂和动态工厂获取对象以及怎么通过 FactoryBean 获取对象
209 0
|
缓存 JavaScript Java
Spring之FactoryBean的处理底层源码分析
本文介绍了Spring框架中FactoryBean的重要作用及其使用方法。通过一个简单的示例展示了如何通过FactoryBean返回一个User对象,并解释了在调用`getBean()`方法时,传入名称前添加`&`符号会改变返回对象类型的原因。进一步深入源码分析,详细说明了`getBean()`方法内部对FactoryBean的处理逻辑,解释了为何添加`&`符号会导致不同的行为。最后,通过具体代码片段展示了这一过程的关键步骤。
161 1
Spring之FactoryBean的处理底层源码分析
|
Java 数据库连接 API
【Spring】1、Spring 框架的基本使用【读取配置文件、IoC、依赖注入的几种方式、FactoryBean】
【Spring】1、Spring 框架的基本使用【读取配置文件、IoC、依赖注入的几种方式、FactoryBean】
194 0
|
XML 缓存 Java
Spring FactoryBean 的常见使用场景总结
FactoryBean 是 Spring 框架中的一个重要接口,用于自定义 Bean 的创建逻辑。常见使用场景包括: 1. **复杂 Bean 的创建**:如数据源配置。 2. **延迟实例化**:按需创建资源密集型对象。 3. **动态代理**:为 Bean 创建 AOP 代理。 4. **自定义配置**:根据特定配置创建 Bean。 5. **第三方库集成**:利用 FactoryBean 封装外部库的创建过程。
312 0
聊聊Spring中两种创建Bean的方式:BeanDefinition.setInstanceSupplier() 和 FactoryBean
聊聊Spring中两种创建Bean的方式:BeanDefinition.setInstanceSupplier() 和 FactoryBean
|
XML Java 数据格式
Spring中BeanFactory和FactoryBean详解
Spring中BeanFactory和FactoryBean详解
768 1
|
XML Java 数据格式
Spring5源码(8)-BeanFactory和FactoryBean的区别
Spring5源码(8)-BeanFactory和FactoryBean的区别
156 0
|
XML Java 数据格式
③【Spring】整合第三框架的常用机制:FactoryBean
③【Spring】整合第三框架的常用机制:FactoryBean
178 0

热门文章

最新文章