Spring学习笔记

来源:互联网 发布:产品展示软件 编辑:程序博客网 时间:2024/06/02 02:40

 

 

该文是学习《精通Spring》的学习笔记。

 

一、IoC设计模式

 

 

1.1  BeanFactoryApplicationContext

 

ApplicationContext继承了BeanFactoryBeanFactory主要用于开发java应用,ApplicationContext主要用于j2ee应用

 

1.1.1          Bean的生命周期

任何处于IoC容器控制下的javabean的生命周期都存在4个阶段

1、实例化JavaBean

2JavaBean实例的初始化,即通过IoC注入其依赖性。

3、基于Spring应用对JavaBean实例的使用。

         4IoC容器销毁JavaBean实例。

 

 

IoC设计模式,重点关注组件的依赖性、配置及生命周期,具有“依赖注入”这个昵称。具有以下几方面优势:

1、  应用组件不需要在运行时寻找其协作者,因此更易于开发和编写应用

2、  借助于依赖关系,更易于单元测试和集成测试

3、  通过使用IoC能降低组件之间的耦合度

 

       

1、  Bean的创建

很多时候,需要借助于工厂方法创建JavaBean实例,

<bean name="fileHelloWorld" class="example4.HelloWorld" factory-method="createHelloWorldInstance">

         此时,HelloWorld必须提供createHelloWorldInstance这个静态方法

         当然,也可以委托给helloWorldFactory另一个bean

<bean name="fileHelloWorld" class="example4.HelloWorld" factory-bean="helloWorldFactory" factory-method="createHelloWorldInstance">

 

2、  初始化JavaBean

首先,如果开发者使用了<bean>元素的autowire属性,则借助于Spring提供的autowire功能,Spring能够自动将目标JavaBean需要注入的JavaBean找到,并注入进来。

其次,如果开发者使用了<bean>元素的dependency-check属性,则能够保证各个Spring配置文件中的各个JavaBean之间的相互关系

第三,借助于setter方法,能够将javabean的属性值注入进来,这些属性值可以是java原型,对象类型,其他bean,甚至是Null

第四,如果JavaBean实现了如下接口,则还需要调用setBeanFactory方法。

org.springframework.beans.factory.BeanFactoryAware

第五,Spring框架提供了若干接口,供开发者改变配置在BeanFactory中的Javabean的行为使用。

最后,在bean元素中包含init-method方法达到同InitializingBean一样的目的。

   

3、  使用JavaBean

一旦Spring创建,并初始化JavaBean实例后,应用就能够使用JavaBean实例了,因此,借助于getBean方法,开发者就能够在应用中使用它了。

 

4、  销毁JavaBean

一旦将基于Spring的(Web)应用停止Spring将调用那些JavaBean实例中存在的生命周期方法,或者那些在Spring配置文件中指定了destory-method属性的JavaBean。最终,Spring将销毁JavaBean实例。这些仅适用于那些通过“singleton”方式创建的JavaBean实例。对于那些以“prototype”方式创建的JavaBean实例,Spring并不能够控制其生命周期,因为一旦这种方式创建成功,整个JavaBean将交给Spring应用去管理。

 

 

 

 

 

 

      

1.2  ApplicationContext

对于Spring BeanFactory而言,如果用户没有调用getBean()方法,则使用到的JavaBean实例不会被创建,因此,在BeanFactory中使用了延迟装载机制。对于ApplicationContext,一旦ContextLoaderServletContextLoaderListener初始化成功,所有JavaBean实例会被创建。

ApplicationContext继承BeanFactory,因此推荐使用ApplicationContext

 

1.Web应用中创建ApplicationContext

通过ContextLoaderServletContextLoaderListener能自动创建ApplicationContext实例,当然,开发者也可以自己手工创建。

 

2. ApplicationContext接口实现

基于ApplicationContext接口,Spring提供了若干实现。开发者经常使用到如下3个实现:

l  ClassPathXmlApplicationContext

Web应用中,开发者可以从classpath中即WEB-INF/classesWEB-INF/libjar中装载Spring配置文件

l  FileSystemXmlApplicationContext

开发者可以从文件系统中装载Spring配置文件。

l  XmlWebApplicationContext:ContextLoaderListenerContextLoaderServlet内部装载Spring配置文件使用

 

 

依赖注入实例:

 

1、先编写helloworld.properties文件,内容如下:

 

helloworld =Hello world!

 

这是消息文件。

 

2、在src下,新建一applicationContext.xml文件,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
 <bean name="fileHelloWorld" class="example4.HelloWorld">
 <!-- 通过构造函数传入一个对象,该对象由fileHello这个bean创建 -->
  <constructor-arg>
   <ref bean="fileHello" />
  </constructor-arg>
 </bean>


 <!-- 直接将helloworld.properties的值传给FileHelloStr类里的propfilename,通过构造函数传入值,constructor-arg标签是指通过构造函数传参 -->
 <bean name="fileHello" class="example4.FileHelloStr">
  <!-- 通过构造函数传值 -->
  <constructor-arg>
   <value>helloworld.properties</value>
  </constructor-arg>
  <!-- 亦可以通过property标签赋值,但类里的propfilename属性需要有get,set方法,而且还要有空的构造函数 -->
  <!-- <property name="propfilename" value="helloworld.properties"></property> -->
 </bean>
</beans>

该配置表中,构造了一个叫"fileHelloWorld"的bean,指向example4.HelloWorld.java类,通过向该类的构造方法,传入另一个叫“fileHello”的bean(实际bean也即是一个类),该“fileHello”的bean指向example4.FileHelloStr.java类,也是通过向该类的构造方法,传入一字符串“helloworld.properties”实际是传入消息文件名,以读取消息。

 

         3、现在开始编写类

首先,编写一接口HelloStr,定义一方法 getContent();

package example4;

public interface HelloStr {
 public String getContent();
}

 

 

FileHelloStr .java该类是负责读取内容的。代码如下:

package example4;

import java.io.InputStream;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class FileHelloStr implements HelloStr {

 protected static final Log log = LogFactory.getLog(FileHelloStr.class);
 private String propfilename;

 /*
  * 通过非构造函数赋值,需要添加个空的构造函数,而且propfilename也要有get,set方法
  * */
 // public FileHelloStr(){
 //  
 // }
 // public String getPropfilename() {
 // return propfilename;
 // }
 //
 //
 // public void setPropfilename(String propfilename) {
 // this.propfilename = propfilename;
 // }
 
 public FileHelloStr(String propfilename) {
  this.propfilename = propfilename;
 }
 @Override
 public String getContent() {
  
  String helloworld = "";
  try {
   //read the properties file
   Properties properties = new Properties();
   InputStream is = getClass().getClassLoader().getResourceAsStream(propfilename);
   properties.load(is);
   is.close();
   helloworld = properties.getProperty("helloworld");
  } catch (Exception e) {
   log.info(e);
  }
  return helloworld;
 }
}

HelloWorld.java是具体的调用类。

package example4;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class HelloWorld {
 protected static final Log log = LogFactory.getLog(HelloWorld.class);
 private HelloStr hStr;
 public HelloWorld(HelloStr hStr){
  this.hStr = hStr;
 }
 public String getContent(){
  return hStr.getContent();
 }
}

客户端类,测试:

package example4;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class HelloWorldClient {

 /*
  * 创建了单实例的HelloWorld和FileHelloStr,通过spring配置文件中的bean元素的singleton属性可以控制创建java实例的方式
  */

 protected static final Log log = LogFactory.getLog(HelloWorldClient.class);

 public static void main(String[] args) {

  // HelloWorld hw = HelloWorldFactory.getFileHelloWorld();

  ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

  HelloWorld hw = (HelloWorld) ac.getBean("fileHelloWorld");
  log.info(hw.getContent());
 }
}

运行客户端类,输出结果如下:

2011-4-13 10:36:33 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@19c26f5: display name [org.springframework.context.support.ClassPathXmlApplicationContext@19c26f5]; startup date [Wed Apr 13 10:36:33 CST 2011]; root of context hierarchy
2011-4-13 10:36:34 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
2011-4-13 10:36:34 org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory
信息: Bean factory for application context [org.springframework.context.support.ClassPathXmlApplicationContext@19c26f5]: org.springframework.beans.factory.support.DefaultListableBeanFactory@1193779
2011-4-13 10:36:34 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1193779: defining beans [fileHelloWorld,fileHello]; root of factory hierarchy
2011-4-13 10:36:34 example4.HelloWorldClient main
信息: Hello world!

 

 整个项目图如下:

 

 

 二、Spring AOP

 

 

 

1、前置通知(Before)

 

先定义接口IHelloWorld.java

package example5;

public interface IHelloWorld {
 public String getContentText(String text);

 public String getContent(String helloworld);

}


 接口实现类HelloWorld.java

package example5;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class HelloWorld implements IHelloWorld {
 
 protected static final Log log = LogFactory.getLog(HelloWorld.class);

 @Override
 public String getContent(String helloworld) {
  log.info(helloworld+"...");
  return helloworld;
 }

 @Override
 public String getContentText(String text) {
  log.info(text+"===");
  return text;
 }

}

客户端调用类HelloClient.java:

package example5;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/*
 * 前置通知
 * before : The Invocation of getContent.这句是在调用了getContent方法之前输出的
 * */

public class HelloClient {
 protected static final Log log = LogFactory.getLog(HelloClient.class);

 public static void main(String[] args) {
  ApplicationContext ac = new ClassPathXmlApplicationContext( "example5/appcontext.xml");
  IHelloWorld hw = (IHelloWorld) ac.getBean("helloworldbean");
  log.info(hw.getContent("TTT"));
  log.info(hw.getContentText("text text"));
 }
}

 

前置通知类LoggingBeforeAdvice.java,实现MethodBeforeAdvice接口。

package example5;

import java.lang.reflect.Method;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.MethodBeforeAdvice;

public class LoggingBeforeAdvice implements MethodBeforeAdvice {

 protected static final Log log = LogFactory.getLog(LoggingBeforeAdvice.class);

 @Override
 public void before(Method arg0, Object[] arg1, Object arg2)
   throws Throwable {
  log.info("before : The Invocation of getContent.");
 }

}

 

以上几个类都是独立的类,前置通知类与其他类相对独立,关键是xml配置表中配置使其起作用。

appcontext.xml如下:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
 <bean id="helloworldbean"
  class="org.springframework.aop.framework.ProxyFactoryBean">
  <property name="proxyInterfaces">
   <value>example5.IHelloWorld</value>
  </property>
  <property name="target">
   <ref local="helloworldbeanTarget" />
  </property>
  <property name="interceptorNames">
   <list>
    <value>loggingBeforeAdvisor</value>
   </list>
  </property>
 </bean>
 <bean id="helloworldbeanTarget" class="example5.HelloWorld"></bean>
 <bean id="loggingBeforeAdvisor"
  class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
  <property name="advice">
   <ref local="loggingBeforeAdvice"/>
  </property>
  <property name="pattern">
   <value>.*</value>
  </property>
 </bean>
 <bean id="loggingBeforeAdvice"  class="example5.LoggingBeforeAdvice"></bean>
</beans>

 

整个项目图如下:

 

运行,结果如下:

2011-4-13 10:50:34 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@19c26f5: display name [org.springframework.context.support.ClassPathXmlApplicationContext@19c26f5]; startup date [Wed Apr 13 10:50:34 CST 2011]; root of context hierarchy
2011-4-13 10:50:34 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [example5/appcontext.xml]
2011-4-13 10:50:34 org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory
信息: Bean factory for application context [org.springframework.context.support.ClassPathXmlApplicationContext@19c26f5]: org.springframework.beans.factory.support.DefaultListableBeanFactory@1193779
2011-4-13 10:50:34 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1193779: defining beans [helloworldbean,helloworldbeanTarget,loggingBeforeAdvisor,loggingBeforeAdvice]; root of factory hierarchy
2011-4-13 10:50:34 example5.LoggingBeforeAdvice before
信息: before : The Invocation of getContent.
2011-4-13 10:50:34 example5.HelloWorld getContent
信息: TTT...
2011-4-13 10:50:34 example5.HelloClient main
信息: TTT
2011-4-13 10:50:34 example5.LoggingBeforeAdvice before
信息: before : The Invocation of getContent.
2011-4-13 10:50:34 example5.HelloWorld getContentText
信息: text text===
2011-4-13 10:50:34 example5.HelloClient main
信息: text text

 

 

2、后置通知

 

先定义接口:

package example6;

public interface IHelloWorld {

 public String getContent(String helloworld);

}

 

 

 

HelloWorld.java的代码:

 

package example6;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class HelloWorld implements IHelloWorld {
 
 protected static final Log log = LogFactory.getLog(HelloWorld.class);

 @Override
 public String getContent(String helloworld) {
  log.info(helloworld+"...");
  return helloworld;
 }
}

 

HelloClient.java代码:

package example6;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/*
 * 后置通知
 * after : The Invocation of getContent. 这句是在调用了getContent方法以后输出的
 * */

public class HelloClient {
 protected static final Log log = LogFactory.getLog(HelloClient.class);

 public static void main(String[] args) {
  ApplicationContext ac = new ClassPathXmlApplicationContext( "example6/appcontext.xml");
  IHelloWorld hw = (IHelloWorld) ac.getBean("helloworldbean");
  log.info("main方法输出:"+hw.getContent("wenbin"));
 }
}

 

后置通知类:

package example6;

import java.lang.reflect.Method;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.AfterReturningAdvice;


public class LoggingAfterAdvice implements AfterReturningAdvice{
 
 protected static final Log log = LogFactory.getLog(LoggingAfterAdvice.class);

 @Override
 public void afterReturning(Object arg0, Method arg1, Object[] arg2,
   Object arg3) throws Throwable {
  log.info("after : The Invocation of getContent.");  
 }
}

appcontext.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
 <bean id="helloworldbean" class="org.springframework.aop.framework.ProxyFactoryBean">
  <!-- 接口名构成的字符串列表,即接口集合 -->
  <property name="proxyInterfaces">
   <list><value>example6.IHelloWorld</value></list>
  </property>
  <!-- 执行目标类 -->
  <property name="target">
   <ref local="helloworldbeanTarget" />
  </property>
  <!-- 拦截器构成的字符串列表,即拦截器集合 -->
  <property name="interceptorNames">
   <list>
    <value>loggingAfterAdvisor</value>
   </list>
  </property>
 </bean>
 <bean id="helloworldbeanTarget" class="example6.HelloWorld"></bean>
 <bean id="loggingAfterAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
  <property name="advice">
   <ref local="loggingAfterAdvice"/>
  </property>
  <property name="pattern">
   <value>.*</value>
  </property>
 </bean>
 <bean id="loggingAfterAdvice"  class="example6.LoggingAfterAdvice"></bean>
</beans>

 

 

环绕通知:该通知最灵活,可以在事件执行前后调用,而且可以更改消息

 

IHelloWorld .java代码如下:

package example8;

public interface IHelloWorld {

 public String getContent(String helloworld);

}

 

 

HelloWorld .java代码:

package example8;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class HelloWorld implements IHelloWorld {
 
 protected static final Log log = LogFactory.getLog(HelloWorld.class);

 @Override
 public String getContent(String helloworld) {
  log.info(helloworld+"...");
  return helloworld;
 }
}

 

客户端HelloClient .java:

package example8;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/*
 * 环绕通知
 * 在执行方法的前后执行
 * */

public class HelloClient {
 protected static final Log log = LogFactory.getLog(HelloClient.class);

 public static void main(String[] args) {
  ApplicationContext ac = new ClassPathXmlApplicationContext( "example8/appcontext.xml");
  IHelloWorld hw = (IHelloWorld) ac.getBean("helloworldbean");
  log.info("main方法输出:"+hw.getContent("wenbin"));
 }
}

 

环绕通知类:

package example8;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/*
 * 环绕通知
 * 可在方法执行前后执行
 * */
public class LoggingAroundAdvice implements MethodInterceptor{

 protected static final Log log = LogFactory.getLog(LoggingAroundAdvice.class);
 
 @Override
 public Object invoke(MethodInvocation invocation) throws Throwable {
  log.info("before : The Invocation of getContent. the output params is :"+invocation.getArguments()[0]);
  invocation.getArguments()[0] = "wenbin";  //invocation.getArguments()[0]就是截获的第一个参数,由hw.getContent("wenbin")里传入的参数提供,可以人工改调传输过程的参数,实现截获信息并修改信息
  invocation.proceed();
  log.info("after : The Invocation of getContent. and the output params is :"+invocation.getArguments()[0]);
  return null;
 }

}

 

appcontext.xml代码:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
 <bean id="helloworldbean"
  class="org.springframework.aop.framework.ProxyFactoryBean">
  <!-- 接口名构成的字符串列表,即接口集合 -->
  <property name="proxyInterfaces">
   <list>
    <value>example8.IHelloWorld</value>
   </list>
  </property>
  <!-- 执行目标类 -->
  <property name="target">
   <ref local="helloworldbeanTarget" />
  </property>
  <!-- 拦截器构成的字符串列表,即拦截器集合 -->
  <property name="interceptorNames">
   <list>
    <value>loggingAroundAdvisor</value>
   </list>
  </property>
 </bean>
 <bean id="helloworldbeanTarget" class="example8.HelloWorld"></bean>
 <bean id="loggingAroundAdvisor"
  class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
  <property name="advice">
   <ref local="loggingAroundAdvice" />
  </property>
  <property name="pattern">
   <value>.*</value> <!-- 对接口集合进行过滤 -->
  </property>
 </bean>
 <bean id="loggingAroundAdvice"
  class="example8.LoggingAroundAdvice">
 </bean>
</beans>

 

 

以上各个通知,都是使用了Spring IoC 依赖注入类

 

若不利用Spring IoC,则

package example9;

import org.aopalliance.aop.Advice;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.framework.ProxyFactory;

/*
 * 环绕通知
 * 借助于Spring AOP手工创建AOP代理,不依赖于IoC容器创建对象
 * 但是不推荐这样,这样违背了Spring的初衷,依赖注入
 * */

public class HelloClient {
 protected static final Log log = LogFactory.getLog(HelloClient.class);

 public static void main(String[] args) {
  //创建LoggingAroundAdvice环绕通知
  Advice advice = new LoggingAroundAdvice();
  
  //创建ProxyFactory,从而不需要借助Spring IoC容器提供控制反转功能
  ProxyFactory factory = new ProxyFactory(new HelloWorld());
  factory.addAdvice(advice);
  
  //调用业务操作
  IHelloWorld hw = (IHelloWorld)factory.getProxy();
  log.info("main方法输出:"+hw.getContent("wenbin"));
 }
}

此时就不需要xml表了,但是不建议这样做,这样违背了Spring的初衷,依赖注入

 

 

 

 

 

三、Spring JTA(事务管理)

        Spring 同时支持两种事务编程模型:声明式和编程式。

对于声明式服务而言,Spring支持各种事务管理器,而不像EJBEJB仅仅支持JTA(Java Transaction API).

        在Spring中,PlatformTransactionManager

       

       

        对于Hibernate而言,需要借助org.springframework.orm.hibernate3.HibernateTransactionManager,开发者必须为其提供sessionFactory值,实际上HibernateTransactionManager会把事务委托给Transaction对象办理。在Spring提供的所有事务管理器中,都是对底层事务的封装。它自身并没实现底层事务的管理.

       

          <!-- 配置事务管理器 -->
 <bean id="transactionManager"
  class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  <property name="sessionFactory">
   <ref bean="sessionFactory" />
  </property>
 </bean>

 

其中,HibernateTransactionManager就是实现了PlatformTransactionManager接口,而且,它还是通过Spring IoC容器加载的。

 

 

 

 

 

 

 

原创粉丝点击