BeanFactory与FactoryBean看似是单词间的简单互换,其意义相差很大,它们分属的功能也有很大的不同。
1 BeanFactory
熟悉IOC容器的朋友对BeanFactory应该不会陌生,BeanFactory其实就是一种IOC容器。BeanFactory是bean工厂,在现实中工厂是用来加工生产我们所需的各种产品,BeanFactory的功能也不例外只不过是生产的产品不同而已。我们代码中的各种bean、bean的实例化以及实例化后对象的依赖关系都是交由BeanFactory来管理的。可以说BeanFactory是Spring的核心功能。
2 FactoryBean
FactoryBean是工厂bean,顾名思义,它是一种bean,但同时又具有工厂的功能,所以它是一种能生产bean的bean。为什么会有这种需求出现呢?下面我们用Mybatis的动态代理机制来分析一下FactoryBean的好处在哪里。我们都知道,Mybatis对外提供的都是mapper接口,这些接口都是没有实现类的,所以就需要动态代理来实现这些功能。Mybatis提供了MapperProxyFactory来生产动态代理:
下面问题来了,Proxy.newProxyInstance()所创建的实例怎么交由Spring来管理呢?怎么将这些实例放入到BeanFactory里呢?Spring是无法自动加载这些实例的,除非改Spring的源码来适配这种需求。这种需求是属于定制化的、可变的需求,针对这种需求Spring给我们提供了FactoryBean。Mybatis就是采用的这种机制
MapperFactoryBean实现了FactoryBean
在getObject()方法里加载动态代理实例。
BeanFactory在加载实例的时候会判断实例是否是FactoryBean类型的,如果是会调用FactoryBean的getObject()方法去加载实例。
总结
BeanFactory是Sring的核心功能,加载bean、实例化以及管理bean之间的依赖关系。而FactoryBean更像是扩展了BeanFactory的能力,加载一些需要定制化的实例。从架构层面来说是变与不变间的分层,不变的是加载、实例化以及管理bean之间的依赖关系,这也是Spring的核心价值。而变化的是外围组件需要定制的需求,Spring通过FactoryBean来扩展了这一能力。