spring源码–08–IOC高级特性–FactoryBean创建实例
1、介绍
1.1、BeanFactory介绍
- Bean工厂,是一个工厂(Factory)
- Spring IoC容器的最顶层接口就是BeanFactory
- 作用就是管理Bean
- bean实例化
- bean定位
- 配置应用程序中的对象及建立这些对象间的依赖。
1.2、FactoryBean介绍
-
工厂Bean,是一个Bean
-
作用是产生其他bean实例。
- 通常情况下,这种bean没有什么特别的要求,仅需要提供一个工厂方法,该方法用来返回其他bean实例。
- 通常情况下,bean无须自己实现工厂模式,Spring容器担任工厂角色,但少数情况下,容器中的bean本身就是工厂,其作用是产生其它bean实例。
-
当用户使用容器本身时,可以使用转义字符"&"来得到FactoryBean本身,以区别通过FactoryBean产生的实例对象和FactoryBean对象本身。
-
在BeanFactory中通过如下代码定义了该转义字符:
StringFACTORY_BEAN_PREFIX = "&";
-
举例:
如果myJndiObject是一个FactoryBean,则使用&myJndiObject得到的是myJndiObject对象,而不是myJndiObject产生出来的对象。
1.2.1、FactoryBean的源码
//工厂Bean,用于产生其他对象
public interface FactoryBean<T> {
//获取容器管理的对象实例
T getObject() throws Exception;
//获取Bean工厂创建的对象的类型
Class<?> getObjectType();
//Bean工厂创建的对象是否是单态模式,如果是单态模式,则整个容器中只有一个实例对象,每次请求都返回同一个实例对象
boolean isSingleton();
}
1.2.2、AbstractBeanFactory的getBean方法调用FactoryBean
在前面我们讲过AbstractBeanFactory.doGetBean方法来进行实例化的过程,源码如下:
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
// 真正实现向IOC容器获取Bean的功能,也是触发依赖注入功能的地方
@SuppressWarnings("unchecked")
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args,
boolean typeCheckOnly) throws BeansException {
·
·
·
·
·
·
// 获取给定bean实例的对象,可以是bean实例本身,也可以是FactoryBean中创建的对象。
// 注意:BeanFactory是Bean的工厂,而FactoryBean是工厂的Bean,两者之间有区别
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
·
·
·
·
·
·
}
}
1.2.3、getObjectForBeanInstance 源码
//获取给定Bean的实例对象,主要是完成FactoryBean的相关处理
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// 如果bean是工厂的引用。即&beanname
if (BeanFactoryUtils.isFactoryDereference(name)) {
//如果是NullBean
if (beanInstance instanceof NullBean) {
return beanInstance;
}
//如果beanInstance 不是 FactoryBean类型,抛异常
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
if (mbd != null) {
//设置是FactoryBean类型
mbd.isFactoryBean = true;
}
// 直接返回当前的Bean实例
return beanInstance;
}
// 现在我们有了bean实例,它可以是普通bean或FactoryBean。
// 如果它是FactoryBean,我们将使用它来创建一个bean实例,除非调用者确实需要对工厂的引用。
if (!(beanInstance instanceof FactoryBean)) {
// 直接返回当前的Bean实例
return beanInstance;
}
//指定名称不是容器的解引用(FactoryDereference),或者beanInstance是一个FactoryBean
//使用FactoryBean创建一个Bean的实例对象
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
}
else {
//从Bean工厂缓存中获取给定名称的Bean实例对象
object = getCachedObjectForFactoryBean(beanName);
}
//让Bean工厂生产给定名称的Bean对象实例
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
//如果从Bean工厂生产的Bean是单例模式的,则缓存
if (mbd == null && containsBeanDefinition(beanName)) {
//从容器中获取指定名称的Bean定义,如果继承基类,则合并基类相关属性
mbd = getMergedLocalBeanDefinition(beanName);
}
//如果从容器得到Bean定义信息,并且Bean定义信息不是虚构的,则让工厂Bean生产Bean实例对象
// synthetic:是否合成
boolean synthetic = (mbd != null && mbd.isSynthetic());
//调用FactoryBeanRegistrySupport类的getObjectFromFactoryBean方法,实现工厂Bean生产Bean对象实例的过程
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
在上面getObjectForBeanInstance方法中,会调用FactoryBeanRegistrySupport.getObjectFromFactoryBean方法,该方法实现了Bean工厂生产Bean实例对象。
Dereference(解引用)
一个在C/C++中应用比较多的术语,在C++中,"*“是解引用符号,而”&"是引用符号,解引用是指变量指向的是所引用对象的本身数据,而不是引用对象的内存地址。
1.2.4、FactoryBeanRegistrySupport.getObjectFromFactoryBean 源码
public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {
//Bean工厂生产Bean实例对象
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
//Bean工厂是单态模式,并且Bean工厂缓存中存在指定名称的Bean实例对象
if (factory.isSingleton() && containsSingleton(beanName)) {
//多线程同步,以防止数据不一致
synchronized (getSingletonMutex()) {
//直接从Bean工厂缓存中获取指定名称的Bean实例对象
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
//调用Bean工厂的getObject方法生产指定Bean的实例对象
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
// Bean实例对象是否已经存在了
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
//存在,将内容返回
object = alreadyThere;
}
else {
//是否执行后置处理程序
if (shouldPostProcess) {
//当前实例正在创建中,返回object
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
//单例创建前动作
beforeSingletonCreation(beanName);
try {
//为创建出来的Bean实例对象添加BeanPostProcessor后置处理器
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
//单例创建胡动作
afterSingletonCreation(beanName);
}
}
if (containsSingleton(beanName)) {
//将生产的实例对象添加到Bean工厂缓存中
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
else {
//调用Bean工厂的getObject方法生产指定Bean的实例对象
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
//为创建出来的Bean实例对象添加BeanPostProcessor后置处理器
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
//调用Bean工厂的getObject方法生产指定Bean的实例对象
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
//实现PrivilegedExceptionAction接口的匿名内置类
//根据JVM检查权限,然后决定BeanFactory创建实例对象
// factory::getObject 调用BeanFactory接口实现类的创建对象方法
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
//调用BeanFactory接口实现类的创建对象方法
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
// Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
if (object == null) {
//创建出来的实例对象为null,或者因为单态对象正在创建而返回null
if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
object = new NullBean();
}
return object;
}
}
小结
从上面可以看出,Bean实例对象由FactoryBean.getObject方法创建
1.2.5、FactoryBean的实现类创建Bean实例对象
FactoryBean的实现类有非常多,ListFactoryBean就是其中一个
ListFactoryBean 继承关系
FactoryBean.getObject的实现,由抽象类AbstractFactoryBean完成
public abstract class AbstractFactoryBean<T>
implements FactoryBean<T>, BeanClassLoaderAware, BeanFactoryAware, InitializingBean, DisposableBean {
//是否初始化
private boolean initialized = false;
//单例对象
@Nullable
private T singletonInstance;
@Override
public final T getObject() throws Exception {
//是否单例
if (isSingleton()) {
//如果初始化了就返回单例对象,否则构建一个单例
return (this.initialized ? this.singletonInstance : getEarlySingletonInstance());
}
else {
//子类ListFactoryBean实现
return createInstance();
}
}
}
ListFactoryBean.createInstance 方法
public class ListFactoryBean extends AbstractFactoryBean<List<Object>> {
@Nullable
//原List
private List<?> sourceList;
@SuppressWarnings("rawtypes")
@Nullable
//目标List类型
private Class<? extends List> targetListClass;
@Override
@SuppressWarnings("unchecked")
protected List<Object> createInstance() {
//原List不能为空格
if (this.sourceList == null) {
throw new IllegalArgumentException("'sourceList' is required");
}
//构建list实例对象
List<Object> result = null;
//如果targetListClass存在,就使用targetListClass,构建result
if (this.targetListClass != null) {
result = BeanUtils.instantiateClass(this.targetListClass);
}
else {
//如果targetListClass不存在, 构建ArrayList作为result,大小为sourceList的大小
result = new ArrayList<>(this.sourceList.size());
}
Class<?> valueType = null;
//目标元素类型
if (this.targetListClass != null) {
valueType = ResolvableType.forClass(this.targetListClass).asCollection().resolveGeneric();
}
if (valueType != null) {
TypeConverter converter = getBeanTypeConverter();
for (Object elem : this.sourceList) {
//添加元素
result.add(converter.convertIfNecessary(elem, valueType));
}
}
else {
//目标元素类型为null,就将sourceList已ArrayList类型返回
result.addAll(this.sourceList);
}
//返回list实例对象
return result;
}
}