0%

BeanFactory和FactoryBean的区别

简介

  • BeanFactory:Spring Bean 容器的根接口
  • FactoryBean:各个对象的工厂接口,如果bean实现了这个接口,它将被用作对象的工厂,而不是直接作为bean实例。

1、BeanFactory

  • BeanFacotry 是 Spring 中比较原始的 Factory 。XMLBeanFactory 就是一种典型的 BeanFactory 。原始的 BeanFactory 无法支持 Spring 的许多插件,如 AOP 功能、 Web 应用等。

  • ApplicationContext 接口,它由 BeanFactory 接口派生而来。 ApplicationContext 包含BeanFactory 的所有功能。

1.1 源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public interface BeanFactory {

//对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象,
//如果需要得到工厂本身,需要转义
String FACTORY_BEAN_PREFIX = "&";

//根据bean的名字,获取在IOC容器中得到bean实例
Object getBean(String name) throws BeansException;

//根据bean的名字和Class类型来得到bean实例,增加了类型安全验证机制。
<T> T getBean(String name, @Nullable 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;

//提供对bean的检索,看看是否在IOC容器有这个名字的bean
boolean containsBean(String name);

//根据bean名字得到bean实例,并同时判断这个bean是不是单例
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

//得到bean实例的Class类型
@Nullable
Class<?> getType(String name) throws NoSuchBeanDefinitionException;

//得到bean的别名,如果根据别名检索,那么其原名也会被检索出来
String[] getAliases(String name);
}

1.2 使用场景

  • 从 IoC 容器中获取 Bean ( byName or byType )
  • 检索 IoC 容器中是否包含指定的 Bean
  • 判断 Bean 是否为单例

2、FactoryBean

2.1源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public interface FactoryBean<T> {

//从工厂中获取bean
@Nullable
T getObject() throws Exception;

//获取Bean工厂创建的对象的类型
@Nullable
Class<?> getObjectType();

//Bean工厂创建的对象是否是单例模式
default boolean isSingleton() {
return true;
}
}

​ 从它定义的接口可以看出,FactoryBean 表现的是一个工厂的职责。 即一个 Bean A 如果实现了FactoryBean 接口,那么 A 就变成了一个工厂,根据 A 的名称获取到的实际上是工厂调用 getObject() 返回的对象,而不是 A 本身,如果要获取工厂 A 自身的实例,那么需要在名称前面加上 ‘&’ 符号。

  • getObject(‘name’)返回工厂中的实例
  • getObject(‘&name’)返回工厂本身的实例

通常情况下,bean 无须自己实现工厂模式,Spring 容器担任了工厂的 角色;但少数情况下,容器中的 bean 本身就是工厂,作用是产生其他 bean 实例。由工厂 bean 产生的其他 bean 实例,不再由 Spring 容器产生,因此与普通 bean 的配置不同,不再需要提供 class 元素。

2.2、使用场景

说了这么多,为什么要有 FactoryBean 这个东西呢,有什么具体的作用吗?
FactoryBean 在 Spring 中最为典型的一个应用就是用来创建AOP的代理对象

我们知道 AOP 实际上是 Spring 在运行时创建了一个代理对象,也就是说这个对象,是我们在运行时创建的,而不是一开始就定义好的,这很符合工厂方法模式。更形象地说, AOP 代理对象通过 Java 的反射机制,在运行时创建了一个代理对象,在代理对象的目标方法中根据业务要求织入了相应的方法。这个对象在 Spring 中就是——ProxyFactoryBean。所以, FactoryBean 为我们实例化 Bean 提供了一个更为灵活的方式,我们可以通过 FactoryBean 创建出更为复杂的 Bean 实例。

3、区别

BeanFactory 是接口,提供了 IoC 容器最基本的形式,给具体的 IoC 容器的实现提供了规范,

FactoryBean 也是接口,为 IoC 容器中 Bean 的实现提供了更加灵活的方式, FactoryBean 在 IoC 容器的基础上给 Bean 的实现加上了一个简单工厂模式装饰模式(如果想了解装饰模式参考:修饰者模式(装饰者模式, Decoration ) 我们可以在 getObject() 方法中灵活配置。其实在 Spring 源码中有很多 FactoryBean 的实现类.

区别: BeanFactory 是个 Factory ,也就是 IoC 容器或对象工厂, FactoryBean 是个 Bean 。在 Spring 中,所有的 Bean 都是由 BeanFactory (也就是 IoC 容器)来进行管理的。

对 FactoryBean 而言,这个 Bean 不是简单的 Bean ,而是一个能生产或者修饰对象生成的工厂 Bean ,它的实现与设计模式中的工厂模式和修饰器模式类似

  • BeanFactory 是 Spring 容器的顶层接口, FactoryBean 更类似于用户自定义的工厂接口。
  • 他们两个都是个工厂,但 FactoryBean 本质上还是一个 Bean,也归 BeanFactory 管理

参考:

https://juejin.cn/post/6844903967600836621

https://juejin.cn/post/6844904099662544903


----------- 本文结束啦感谢您阅读 -----------