ObjectFactory与BeanFactory的区别
ObjectFactory 与BeanFactory 的区别
Spring 体系中有一些跟 Bean获取相关的接口,比如:ObjectFactory
、BeanFactory
、FactoryBean
、ObjectProvider
等。有时候会让人不知道该使用哪一个。下面具体看一下区别。
BeanFactory
该接口是整个Spring容器的顶层接口,定义了从容器中获取Bean的方法。当我们的应用需要从容器中获取Bean的时候用此接口。在这里我们可以将整个容器看成是一个黑盒,不需要关心它是如何获取的,我们只关心结果。
ObjectFactory
此接口定义了一个简单工厂,是一个函数式接口,可以在调用时返回一个对象实例(可能是共享的或独立的)。
这个接口类似于FactoryBean
,但是后者的实现类通常被定义为BeanFactory
中的SPI实例,而该类的实现通常被作为API(通过注入)提供给其他bean。因此,getObject()方法具有不同的异常处理行为。
1 |
|
FactoryBean
这个接口定义了创建单个对象的工厂。如果一个bean 实现了这个接口,那么它将被用作要公开的对象的工厂,而不是直接用作将自己公开的bean 实例。
注意: 实现此接口的bean不能作为普通bean使用。FactoryBean
是以bean形式定义的,但是引用该Bean 时是它创建的对象。
FactoryBean
支持单例和原型对象,可以根据需要创建对象,也可以在启动时创建对象。SmartFactoryBean
接口可以公开更细粒度的元数据。
这个接口在Spring 框架本身中大量使用,例如在AOP模块 org.springframework.aop.framework.ProxyFactoryBean
或org.springframework.jndi.JndiObjectFactoryBean
中。
FactoryBean
是一个编程规范。实现类不应该依赖于注解驱动的注入或其他反射工具。在启动过程中可能会提前调用getObjectType()
和getObject()
方法,甚至比后处理器都要早。如果需要访问其他bean,请实现BeanFactoryAware
接口并通过编程获取,也就是说在FactoryBean
中注解可能还没解析,通过注解注入其他Bean 可能不成功。
最后,FactoryBean
对象会参与bean创建同步过程。通常不需要做内部同步,只需要在FactoryBean
本身中进行延迟初始化。
1 | public interface FactoryBean<T> { |
ObjectProvider
该接口是ObjectFactory
的变体形式,专门为注入点设计,允许编程可选性和宽松的非惟一处理。
从Spring 5.1开始,这个接口扩展了Iterable
并提供了流支持。因此,它可以在for循环中使用,提供forEach迭代并允许流访问。
1 | public interface ObjectProvider<T> extends ObjectFactory<T>, Iterable<T> { |
几者的区别
BeanFactory
与这几个不在一个层面上,名字比较像,所以容易混淆。BeanFactory
是整个大的工厂,有各种各样的生产线,FactoryBean
就好比是生产线。
FactoryBean
与ObjectFactory
相比,FactoryBean
主要强调自定义创建Bean的过程,通过编程的方式去创建我们的Bean,比配置文件的方式更加的灵活。而且FactoryBean
本身也是一个受Spring 容器管理的Bean,只不过我们更注重它创建出来的Bean。FactoryBean
还是Spring提供出来的SPI接口,用于扩展框架。而ObjectFactory
是一个普通的工厂,与Spring 容器Bean的创建关系不大。在Spring 创建Bean的过程中,借助自定义Scope
可以控制创建对象的时机,参见org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean
方法对自定义Scope
的处理,自定义Scope
可以参见org.springframework.web.context.request.AbstractRequestAttributesScope.get
方法。
ObjectProvider
扩展自ObjectFactory
接口,提供了更多关于Bean的信息的方法,比如是否存在,是否唯一,提供和消费Bean,以及遍历Bean。通过这个接口,我们可以根据这些信息做更灵活的控制。