Spring 知识 -- BeanFactory 和 FactoryBean

本文最后更新于:4 个月前

先说结论,他们的区别是:

FactoryBean 是一个接口,可以用于解决使用第三方依赖时,用户需要配置过多依赖的问题。
具体来说,它主要是第三方为了向使用方提供 Bean,然后使用方再去生成并配置好这个 FactoryBean 实例交给 Spring 管理,然后通过这个工厂 Bean 就能生成这个第三方需要使用的真正的 Bean 并交给 Spring 去管理了。

BeanFactory 是 Spring 容器产生 Bean 的顶层工厂接口,Spring IOC 容器中的 Bean 都由这个 BeanFactory 产生。

对于 FactoryBean,具体来说就是:如果你是第三方提供了某些功能能够让其他人使用你写的 jar 包,但是这些功能可能需要用户配置,例如 MyBatis 的数据库连接配置等。而且,配置好之后还需要去交给 Spring 去管理,那么用户就需要提供一个配置类来去定制他自己的功能或者使这个 jar 包真正产生作用。但是,用户需要去生成这个配置类,而这个配置类可能依赖了很多成员变量,它们可能是字符串,各种数组,甚至你写的配置类,你提供的功能依赖的第三方配置类等等,这样全都交给用户来去配置就会非常麻烦。那么,更好的办法是,你自己维护这个配置类并封装成一个 FactoryBean,用户只需要手动生成这个 FactoryBean,再自己制定一些必须的配置,然后可以用这个配置类注入到那个 FactoryBean 实例里面,就完成了功能的定制,最后用户只需要在这个函数上面加上 @Bean 注解即可把这个 FactoryBean 交给 Spring IOC 容器,而 Spring 就可以根据 FactoryBean 的特性来去真正生产出第三方需要的 Bean。

例如:

MyBatis 需要一个 SqlSessionFactory,而这个类有一些数据源的配置,但是,要生成这个配置类不仅仅需要配置数据源,还有一些其他的配置,如果都交给用户来去手动管理就会变得非常麻烦。

而 MyBatis 提供了一个 SqlSessionFactoryBean 的类,在这个类里面已经做了相关配置的设置,使用者只需要生成这个 SqlSessionFactoryBean 的实例,在注入配置实例就可以完成这个 FactoryBean 的生成,进而交给 Spring 管理从而真正生成 SqlSessionFactory。

@Bean
public SqlSessionFactory sqlSessionFactory() {
  SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
  factoryBean.setDataSource(dataSource());
  return factoryBean.getObject();
}

注意:

  1. 根据 FactoryBean 的名称从 BeanFactory 中获取的实际上是 FactoryBean 的 getObject() 返回的对象,而不是 FactoryBean 本身,如果要获取 FactoryBean 对象,请使用 &BeanName 来获取。

  2. FactoryBean 的第三方实现类生成时必须足够简单,因为如果过于复杂那就还不如用户自己手动直接生成第三方所需 Bean 对象了。