spring源码--08--IOC高级特性--FactoryBean创建实例

spring源码–08–IOC高级特性–FactoryBean创建实例

1、介绍

1.1、BeanFactory介绍

  1. Bean工厂,是一个工厂(Factory)
  2. Spring IoC容器的最顶层接口就是BeanFactory
  3. 作用就是管理Bean
    1. bean实例化
    2. bean定位
    3. 配置应用程序中的对象及建立这些对象间的依赖。

1.2、FactoryBean介绍

  1. 工厂Bean,是一个Bean

  2. 作用是产生其他bean实例。

    1. 通常情况下,这种bean没有什么特别的要求,仅需要提供一个工厂方法,该方法用来返回其他bean实例。
    2. 通常情况下,bean无须自己实现工厂模式,Spring容器担任工厂角色,但少数情况下,容器中的bean本身就是工厂,其作用是产生其它bean实例。
  3. 当用户使用容器本身时,可以使用转义字符"&"来得到FactoryBean本身,以区别通过FactoryBean产生的实例对象和FactoryBean对象本身。

  4. 在BeanFactory中通过如下代码定义了该转义字符:

     StringFACTORY_BEAN_PREFIX = "&";
    
  5. 举例:

     如果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;
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值