前言
前面两篇文章 Spring基础容器BeanFactory 和 Spring FactoryBean 源码分析 已经详细的介绍了BeanFactory
和FactoryBean
,Spring中还存在一个ObjectFactory
,它们之间不仅名称非常相似,事实上功能也有一些区别和联系。初学Spring的小伙伴可能很难区分它们之间有什么区别,这篇文章将简单对它们加以区分。
ObjectFactory源码浅析
ObjectFactory
源码相对简单,我们先从源码入手对ObjectFactory
做一个简单的认识。
/**
* 定义一个工厂,该工厂在调用时可以返回对象实例(可能是共享的或独立的)。
* 此接口通常用于封装一个通用工厂,该工厂在每次调用时返回某个目标对象的新实例(原型)。
* 这个接口类似于FactoryBean,但是后者的实现通常被定义为BeanFactory中的SPI实例,
* 而这个类的实现通常是作为API提供给其他bean的(通过注入)。因此,getObject()方法具有不同的异常处理行为。
* @param <T> the object type
* @author Colin Sampaleanu
* @see FactoryBean
* @since 1.0.2
*/
@FunctionalInterface
public interface ObjectFactory<T> {
/**
* 返回此工厂管理的对象的实例(可能是共享的或独立的)。
*
* @return the resulting instance
* @throws BeansException in case of creation errors
*/
T getObject() throws BeansException;
}
通过源码的注释我们可以大概了解到,ObjectFactory
是一个工厂,在调用时可以返回对象的一个实例。
BeanFactory、FactoryBean、ObjectFactory的联系与区别
联系
BeanFactory
、FactoryBean
、ObjectFactory
都是工厂,负责对象的创建与获取。
区别
BeanFactory
作为bean工厂,是spring的基础容器,它可以管理单例bean对象从创建到销毁的整个生命周期。FactoryBean
可以作为BeanFactory
管理的bean对象,同时BeanFactory
对FactoryBean
会做出特殊处理。如果FactoryBean
被定义为spring的bean,则获取该bean时需要在beanName前面加上&符号,否则获取的bean是FactoryBean
创建的对象。ObjectFactory
则只是作为一个普通的对象工厂,也不作为spring管理的bean使用,BeanFactory
不会对ObjectFactory
做特殊处理。它主要是用作BeanFactory
子类的内部类或者使用lambda表达式封装bean的创建过程。
Spring中是如何使用ObjectFactory的?
BeanFactory
和FactoryBean
在前面的文章中已经进行了详细的分析,在此不加赘述,主要分析BeanFactory
对ObjectFactory
的使用。
BeanFactory
中有两个和ObjectFactory
相关的方法,如下:
<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
这两个方法就是用于bean的延迟依赖查找,返回值类型ObjectProvider
就是ObjectFactory
的子接口。ObjectProvider
相对ObjectFactory
,主要是可以同时获取管理的对象的stream流或者迭代器、根据参数获取对象、如果唯一才获取等,实现类为DefaultListableBeanFactory
的内部类DependencyObjectProvider
,实现主要是封装了BeanFactory
创建bean的逻辑,感兴趣的小伙伴可自行阅读源码。
AbstractBeanFactory#doGetBean
方法中还存在如下的代码使用到了ObjectFactory
,部分代码已省略。
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
...省略部分代码
if (mbd.isSingleton()) {
//获取singleton bean
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
} catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
...省略部分代码
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
} finally {
afterPrototypeCreation(beanName);
}
});
...省略部分代码
}
可以看到,获取单例bean及从自定义作用域中获取bean均使用ObjectFactory
调用createBean
方法封装了bean的创建。
总结
本文首先通过源码对ObjectFactory
做一个简单的认识,然后对BeanFactory
、FactoryBean
、ObjectFactory
的区别与联系做出总结,最后还分析了spring对ObjectFactory
的使用,希望对大家有所帮助。