`
yun342173024
  • 浏览: 72865 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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类型的。


但配置中引用的是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类型的。
3
1
分享到:
评论

相关推荐

    spring的FactoryBean增强我们的目标对象.rar

    通过FactoryBean在获取目标类的时间我们将增强的代理类给返回,使得我们调用方法的时间使用的代理类来增强,如果需要继续使用未代理的对象,则直接@Autowired 注入使用.

    SpringFactoryBean:spring FactoryBean的样本,在运行时在两个bean之间进行更改

    spring FactoryBean的小样本,如何在运行时在两个bean之间进行切换。

    详解Spring中的FactoryBean

    本篇文章主要介绍了Spring中的FactoryBean,如果一个bean的创建过程中涉及到很多其他的bean 和复杂的逻辑,用xml配置比较困难,这时可以考虑用FactoryBean

    spring中的FactoryBean代码示例

    主要介绍了spring中的FactoryBean代码示例,涉及FactoryBean的实现等相关内容,具有一定参考价值,需要的朋友可以了解下。

    spring中FactoryBean中的getObject()方法实例解析

    主要介绍了spring中FactoryBean中的getObject()方法实例解析,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下

    spring源码解析之FactoryBean相关测试代码demo

    spring源码解析之FactoryBean相关测试代码demo,文章中也有相关代码

    Spring中的FactoryBean.rar

    Spring中的FactoryBean.rar

    简单了解Spring中BeanFactory与FactoryBean的区别

    主要介绍了简单了解Spring中BeanFactory与FactoryBean的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    spring:这是Spring框架研究

    spring This is spring framework study ...八、使用spring FactoryBean技术模拟mybatis MapperScan注解 https://github.com/AvengerEug/spring/tree/develop/implement-mapperscan 九、mybatis源码学习 ...

    Spring基于ProxyFactoryBean创建AOP代理

    主要介绍了Spring基于ProxyFactoryBean创建AOP代理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    FactoryBean代码最简实现

    这篇代码主要适用于我的博客,用来帮助理解Spring配置文件+FactoryBean的实例化过程。注意,这里是FactoryBean,而不是BeanFactory,下载资源要看清楚哈。

    深入了解Spring中的FactoryBean

    主要介绍了深入了解Spring中的FactoryBean,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    Spring中BeanFactory与FactoryBean接口的区别详解

    主要给大家介绍了关于Spring中BeanFactory与FactoryBean接口的区别的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者使用Spring具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧

    spring如何通过FactoryBean配置Bean

    主要介绍了spring如何通过FactoryBean配置Bean,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    Spring BeanFactory和FactoryBean区别解析

    主要介绍了Spring BeanFactory和FactoryBean区别解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    spring4示例代码

    spring-2 演示了外部配置文件的引入(connection),spel(spring el)表达式 ,静态工厂方式及实例工厂方式及factorybean方式创建bean, spring的生命周期及BeanPostProcessor的使用,注解方式创建bean 及使用...

    spring的详细介绍

    Spring介绍 1. Spring 2. 使用spring的主要目的 3. Spring的模块 Ejb容器(以前是) Ioc容器(现在的控制权) 控制反转Ioc(Invertion of control)依赖注入(Dependency Injection) ...13. 接口FactoryBean的使用

    精通Spring整合MyBatis:架构师的实践指南

    Spring和MyBatis的整合是Java...Spring使用FactoryBean来创建特定类型的bean,例如MyBatis的Mapper接口的动态代理实例。BeanDefinitionRegistry则用于注册这些动态生成的bean,确保它们可以被Spring容器识别和管理。

    factory-bean-demo.7z

    spring 自定义 FactoryBean 样例工程,可以通过这个工程通过实现FactoryBean来扩展Spring容器

    高级开发spring面试题和答案.pdf

    BeanFactory和FactoryBean有什么区别; Spring中用到的设计模式; SPI 机制(Java SPI 实际上是“基于接口的编程+策略模式+配置文件”组合实现的动态加载机制), 很多地方有用到: AOP Spring的AOP的底层实现原理; ...

Global site tag (gtag.js) - Google Analytics