spring的FactoryBean

一直对spring配置的LocalSessionFactoryBean这个bean感到疑惑,下面是spring的bean配置。
        <beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx" 
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="  
             http://www.springframework.org/schema/beans 
             http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
             http://www.springframework.org/schema/context
        	 http://www.springframework.org/schema/context/spring-context-3.0.xsd
             http://www.springframework.org/schema/aop 
             http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
             http://www.springframework.org/schema/tx 
             http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
		
	<!-- 基于hibernate注解的sessionFactory -->
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
						
	</bean>
	<bean id="txManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>
	
  <tx:annotation-driven transaction-manager="txManager"/>
	
</beans>
  

在hibernate的事物管理器bean txManager(上面xml配置) 中,它的属性sessionFactory是SessionFactory类型的,下面是HiberanteTransactionManager的源码的片段,它的set方法接受的是SessionFactory类型的。

spring的FactoryBean_第1张图片
但配置中引用的是LocalSessionFactory类型的,让人感到费解,看了关于spring的关于FactoryBean和BeanFactory的介绍,明白了其中的缘由,FactoryBean是一种特殊的Bean,spring会做特殊处理,FactoryBean被定义为了一个接口,下面是FactoryBean的代码
  package org.springframework.beans.factory;

public interface FactoryBean<T> {


	T getObject() throws Exception;

	Class<?> getObjectType();

	boolean isSingleton();

}

spring的依赖注入发生在getBean方法被调用的时候,除了作用域为singleTon类型的bean,当在txManager这个bean中配置引用了其他bean,spring就会调用getBean去从IOC容器中去找这个Bean,下面看getBean代码,(这个类AbstractBeanFactory)
 public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}

getBean调用了doGetBean,到这个方法里。
   protected <T> T doGetBean(
			final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
			throws BeansException {

		final String beanName = transformedBeanName(name);
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			if (logger.isDebugEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

这里先取到那个引用的bean,就是sharedInstance,在看这个调用,
 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);

这里spring检查是不是FactoryBean,进入这个方法,
  	if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
			return beanInstance;
		}

判断如果这个bean不是FactoryBean类型的直接返回对象,如果是执行下面的代码
    	Object object = null;
		if (mbd == null) {
			object = getCachedObjectForFactoryBean(beanName);
		}
		if (object == null) {
			// Return bean instance from factory.
			FactoryBean factory = (FactoryBean) beanInstance;
			// Caches object obtained from FactoryBean if it is a singleton.
			if (mbd == null && containsBeanDefinition(beanName)) {
				mbd = getMergedLocalBeanDefinition(beanName);
			}
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}

主要看这行代码
   object = getObjectFromFactoryBean(factory, beanName, !synthetic);

看方法名字就知道这个方法的意思,从FactoryBean中去取对象,进入这个方法
  protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName, boolean shouldPostProcess) {
		if (factory.isSingleton() && containsSingleton(beanName)) {
			synchronized (getSingletonMutex()) {
				Object object = this.factoryBeanObjectCache.get(beanName);
				if (object == null) {
					object = doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);
					this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
				}
				return (object != NULL_OBJECT ? object : null);
			}
		}
		else {
			return doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);
		}
	}

这里sping判断这个FactoryBean是不是singleton类型的,是的话做了一个缓存,主要看这一行
  object = doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);

进入这个方法
   object = factory.getObject();

这里只贴出了重要的代码,返回的是FactoryBean的getObject的类型,看下LocalSessionFactoryBean,它实现了FactoryBean接口,代码如下,
   
	/**
	 * Return the singleton SessionFactory.
	 */
	public SessionFactory getObject() {
		return this.sessionFactory;
	}

	public Class<? extends SessionFactory> getObjectType() {
		return (this.sessionFactory != null ? this.sessionFactory.getClass() : SessionFactory.class);
	}

	public boolean isSingleton() {
		return true;
	}


这里用到了泛型,它返回的是SessionFactory类型的。

你可能感兴趣的:(FactoryBean)