一直对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类型的。
但配置中引用的是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类型的。