FactoryBean粗解以及使用案例

本文介绍了Spring中的FactoryBean接口,分析了其与BeanFactory的区别。FactoryBean用于创建对象的工厂,而不是作为直接暴露的bean。文章通过源码解析、方法介绍以及在Mybatis中的扩展应用案例,阐述了FactoryBean的使用和重要性。

在这里插入图片描述

前面文章大致了解了BeanFactory 接口,以及提供的相关能力。看到FactoryBean 这个接口的命名,可能会直接迷糊,这两个接口用到的字母都一样,只是中建的单词对调了一下。是不是功能和能力大致一样?做技术,不能想当然的去判断和猜测,要看证据。

签名分析

每个类以及接口都有自己的唯一签名。FactoryBean 的命名绝对不是因为存在BeanFactory不能重复,而故意颠倒一下。

  • BeanFactory 命名上可以确定是一个工厂,并且是一个bean工厂,提供了bean的一堆访问能力
  • FactoryBean 命名上来说是工厂Bean,是一个Bean,应该提供了生成工厂的方法

差别

接口描述用途
BeanFactory首先是一个工厂,是访问bean的工厂用于访问spring 容器中的bean
FactoryBean首先是一个bean,是生成工厂点的bean用于生成bean的工厂

Factory源码

接口源码,已经删掉了注释;如下:


public interface FactoryBean<T> {

	
	String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";


	@Nullable
	T getObject() throws Exception;

	@Nullable
	Class<?> getObjectType();

	default boolean isSingleton() {
		return true;
	}
}

官方对于这个接口的说明是:

Interface to be implemented by objects used within a BeanFactory which are themselves factories for individual objects. If a bean implements this interface, it is used as a factory for an object to expose, not directly as a bean instance that will be exposed itself.

由 BeanFactory 中使用的对象实现的接口,这些对象本身就是单个对象的工厂。如果 Bean 实现了此接口,那么它将用作要公开的对象的工厂,而不是直接用作将要公开的 Bean 实例。

方法介绍

  • T getObject() 返回工厂生产的一个实例(这个工厂就是通过这个方法生产对象的)
  • Class<?> getObjectType() 生产的对象的实例的类型
  • boolean isSingleton() 是否是单例,默认为true

案例

接口很简单,带来的扩展性很大。这种扩展性可以为开发中的自己的代码设计作为参考。

Mybatis中基于spring的这个接口的扩展

在开发中,为什么mybatis写一个接口,就可以被service层直接当做一个bean去使用的?就是基于这个做了扩展,核心扩展类SqlSessionFactoryBean,签名如下:
在这里插入图片描述
核心实现的方法如下:

 public SqlSessionFactory getObject() throws Exception {
        if (this.sqlSessionFactory == null) {
            this.afterPropertiesSet();
        }

        return this.sqlSessionFactory;
    }

    public Class<? extends SqlSessionFactory> getObjectType() {
        return this.sqlSessionFactory == null ? SqlSessionFactory.class : this.sqlSessionFactory.getClass();
    }

    public boolean isSingleton() {
        return true;
    }

这里的扩展点已经显而易见了。如果在使用spring的时候也这样进行扩展,是不是会非常优雅,非常高大上。

写代码的同时牢记“优雅永不过时”

`FactoryBean` 是 Spring 中非常有用的一个扩展点,它允许我们以更灵活的方式创建 Bean。相比普通的 Bean 创建方式(构造函数或工厂方法),`FactoryBean` 提供了更强大的自定义能力。下面是一些 **FactoryBean 的具体使用场景**: --- ### ✅ 1. **创建复杂对象** 当某个 Bean 的创建过程比较复杂,比如需要多步构造、条件判断、动态代理等,可以使用 `FactoryBean` 封装这些逻辑。 ```java public class ComplexServiceFactoryBean implements FactoryBean<ComplexService> { @Override public ComplexService getObject() throws Exception { // 复杂的构建逻辑 ComplexService service = new ComplexService(); service.init(); service.loadConfig(); return service; } @Override public Class<?> getObjectType() { return ComplexService.class; } @Override public boolean isSingleton() { return true; } } ``` --- ### ✅ 2. **动态代理对象的创建** `FactoryBean` 常用于创建 AOP 代理对象。例如,Spring AOP 内部就使用了 `ProxyFactoryBean` 来生成代理对象。 ```java public class MyProxyFactoryBean implements FactoryBean<Object> { private Object target; private Class<?> interfaceType; public void setTarget(Object target) { this.target = target; } public void setInterfaceType(Class<?> interfaceType) { this.interfaceType = interfaceType; } @Override public Object getObject() { return Proxy.newProxyInstance( getClass().getClassLoader(), new Class[]{interfaceType}, (proxy, method, args) -> method.invoke(target, args) ); } ... } ``` --- ### ✅ 3. **延迟加载某些资源** 有些 Bean 依赖外部资源(如数据库连接、网络服务等),可以通过 `FactoryBean` 实现延迟加载。 --- ### ✅ 4. **整合第三方库** 当整合某些第三方库时,如果它们本身不支持 Spring 的 IOC 容器管理,可以通过 `FactoryBean` 包装其创建过程。 例如:整合 MyBatis 的 `SqlSessionFactory`,Spring使用了 `SqlSessionFactoryBean`。 --- ### ✅ 5. **根据环境动态创建不同实现** 根据不同的配置或环境变量,返回不同的 Bean 实例。 ```java public class EnvAwareServiceFactoryBean implements FactoryBean<MyService> { private String env; public void setEnv(String env) { this.env = env; } @Override public MyService getObject() { if ("prod".equals(env)) { return new ProdServiceImpl(); } else { return new DevServiceImpl(); } } ... } ``` --- ### ✅ 6. **封装单例或原型模式** 虽然 Spring 本身支持单例和原型作用域,但有时我们希望更精细地控制实例的创建方式,`FactoryBean` 可以帮助我们实现这一点。 --- ### 总结: `FactoryBean` 的本质是 **封装 Bean 的创建逻辑**,适用于需要 **自定义创建过程**、**动态生成对象**、**整合外部组件**、**创建代理对象** 等场景。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五之

真实案例以及商业项目技术

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值