Spring总结

来源:互联网 发布:java一年经验工资 编辑:程序博客网 时间:2024/06/16 22:25

1.Spring作用和优点

    a.Spring框架是解决方案级的框架或者说整合框架,是各种组件、技术

     的使用平台,可以在这个平台上使用Struts,Hibernate,JDBC技术并且可

     以可以实现各种开发技术的组合。Spring提供了IoC和AOP机制的实

     现,可以改善程序结构,提高系统的灵活性,便于维护和扩展。

 Spring主要作用:让组件之间实现低耦合(方便解耦),让程序结构更  

                  加灵活,方便日后的维护和扩展 

                 低耦合:组件与组件之间的关联度较低

Spring相当于主机中的主板,而struts、Hibernate、jsp相当于主板上

的cpu、内存、显卡之类的组件(主板特点:可插拔 ) 

       b.在SSH使用中,Spring提供了一个容器,该容器具有IOC和AOP机

         制,利用这个容器IOC机制管理程序中的DAO,Service等组件,采用

         AOP机制实现事务,异常日志记录等共通处理。

2.Spring容器简介

   1)Spring容器是Spring框架的基础和核心。该容器具有以下功能:

    a.可以创建和初始化一个Bean组件对象

      在spring里,任何java对象和java组件都被当成bean处理。

    b.可以管理Bean对象的生命期

    c.可以利用IoC机制建立Bean对象之间的关系

    d.可以利用扩展的AOP机制将共通组件和某一批目标组件对象建立关联。

      (需要引入AOP扩展jar包)

 

    2)Spring容器类型可以使BeanFactory或者ApplicationContext.

     –Spring容器实例化

      ApplicationContext ac =new ClasspathXmlApplicationContext(xml配置);

     –从Spring容器获取Bean对象

      接口类型 变量 =  (接口类型)ac.getBean(“id属性”);

     –销毁Spring容器

       使用AbstractApplicationContext类型的close();

       一般情况下,销毁容器对象由Spring管理完成,无需手动销毁。如果要

       手动销毁需要使用AbstractApplicationContext容器,调用

       AbstractApplicationContext容器的close()方法。

   3)Spring容器的使用方法

      –引入spring核心包

     –在src下添加spring配置文件

     –在spring配置文件定义Bean组件

    <bean id=”标识符” class=”包名.实现类名”>

    </bean>

eg:

applicationContext.xml:

 <!– 定义Bean组件 –>

<bean id=“costDao” class=“com.tarena.dao.JdbcCostDAO”></bean>

     –实例化spring容器,通过容器的getBean(“标识符”)方法获取

 

       eg:

public static void main(String[] args) {

// CostDAO costDao = new JdbcCostDAO();

// costDao.save();

// costDao.update();

// 获取Spring容器中的CostDAO

// 第一步实例化Spring容器

String conf = ”applicationContext.xml”;

// 用于加载src下的xml配置文件

AbstractApplicationContext ac = new 

          ClassPathXmlApplicationContext(conf);

// AbstractApplicationContext ac = new 

         FileSystemXmlApplicationContext 用于加载磁盘路径的xml配置

// 获取容器中的DAO

CostDAO costDao = (CostDAO) ac.getBean(”costDao”);

costDao.save();

costDao.update();

// ac.close();//销毁Spring容器

}

3.Spring容器对Bean组件的管理

 *1)创建Bean对象的方式

     Spring可以采用单例模式非单例模式创建Bean对象。

     默认情况下,采用单例模式创建Bean对象。

     在<bean scope=”“>中利用scope属性控制创建模式。

     scope=”singleton”采用单例模式,

     scope=”prototype”采用原型(非单例)模式

     (在JavaWeb环境中,scope属性值还可以指定request,session等范围)

 如果scope=”singleton”,Spring容器实例化时,会自动创建Bean组件

     对象。

     如果scope=”prototype”,Spring容器会在调用getBean方法时创建Bean

     对象。

scope属性的取值介绍:

在web(仅限于web项目)环境中,还可以设置所创建的bean对象的生命周期和request、session。

a.request 表示bean对象生命周期和request生命周期相同

b.session 表示bean对象生命周期和session生命周期相同

c.global session 相当于application

d.singleton 单例模式

e.prototype 原型模式

   2)Bean对象的创建时机

     默认是随着容器创建,可以使用lazy-init=true设置(在调用getBean()创建)

     延迟创建

   3)Bean对象的初始化和销毁

     使用<bean init-method=”“ destroy-method=”“>

     可以指定Bean对象创建和销毁时触发的方法。

     destroy-method只适用于scope=”singleton”模式.

    当调用applicationcontext.close()时,容器会自动销毁所有单例对象,此时会  

    触发指定destory-method方法。

     init-method指定的初始化方法可以在构造方法执行后自动执行。

 

4.如何使用Spring容器的IoC机制

  Spring提供的IoC主要是用于建立两个对象(组件、Bean)之间的关系,

  好处是低耦合方式。Spring经典总结

   1)DI(依赖注入技术)

     Dependency Injection 称为依赖注入。意思是采用注入技术建立两个组件

     的依赖关系。

      Spring通过DI技术实现了IoC思想。DI技术可以分成以下几类:

      –setter方式注入(依靠属性的set方法注入)

<property….></property>对应的注入方式只能是setter注入

 applicationContext.xml配置:

<!– 定义Bean组件 –>

<bean id=“costDao” scope=“singleton” init-method=“myinit”

destroy-method=“mydestroy” class=“com.tarena.dao.JdbcCostDAO”>

</bean>

<bean id=“hibernateCostDao” 

     class=“com.tarena.dao.HibernateCostDAO”>

</bean>

<!– setter方式注入示例 –>

<bean id=“costAction” scope=“prototype” 

      class=“com.tarena.action.CostAction”>

<!– 将ref指定的id属性Bean对象给costDao属性注入 –>

<property name=“costDao” ref=“hibernateCostDao”></property>

</bean>

其中,name=”costDao”中的costDao为要注入的属性,即public void 

setCostDao ….方法中的setCostDao()方法名中的除”set”之后的部分

  /** setter方式注入示例*/

public class CostAction {

private CostDAO costDao1;

// spring自动调用该方法,注入一个CostDAO对象

public void setCostDao(CostDAO costDao) {

this.costDao1 = costDao;

}

public String add() {

System.out.println(“执行资费添加操作”);

costDao1.save();

return “success”;

}

}

      –构造方式注入(依靠构造方法注入)

  applicationContext.xml配置:

<!– 定义Bean组件 –>

<bean id=“costDao” scope=“singleton” init-method=“myinit”

destroy-method=“mydestroy” class=“com.tarena.dao.JdbcCostDAO”>

</bean>

   <bean id=“hibernateCostDao” 

  class=“com.tarena.dao.HibernateCostDAO”>

</bean>

<!– 构造方式注入示例 –>

<bean id=“costAction1” scope=“prototype” 

     class=“com.tarena.action.CostAction1”>

<!– 构造方式注入 –>

<!– “0”为构造参数索引:构造参数索引;”costDao”为要注入的Bean对象的id –>

<constructor-arg index=“0” ref=“costDao”>

</constructor-arg>

   </bean>

其中,<constructor-arg index=”构造参数索引”

            ref=”要注入的Bean对象的id”>

      </constructor-arg>

 Spring经典总结

/**构造方式注入示例*/

public class CostAction1 {

private CostDAO costDao1;

// spring自动调用该方法,注入一个CostDAO对象

public CostAction1(CostDAO costDao) {

this.costDao1 = costDao;

}

public String add() {

System.out.println(“执行资费添加操作”);

costDao1.save();

return “success”;

}

         }

      –接口方式注入(了解名称,可以参考spring文档)

   2)IoC思想

      Inverse of Controller 称为反向控制或控制反转,确切讲被称为控制转移,

      意思就是转交控制权。

     所谓控制及控制权:指的是负责对象的创建、初始化以及销毁等工作。

     两个组件,当A调用B时,原有方式需要在A里面编写控制权逻辑代码,

     当需要替换B组件时,需要修改控制权逻辑,因此A和B组件的耦合度比

     较高。

     采用IoC思想后,就是将A中的控制权逻辑转移给第三方容器或框架,有

     第三方框架负责A,B对象的创建,释放,初始化和关系指定等工作。

 

    *3)Action—>DAO采用Spring的IoC方式

       –在Action中定义一个DAO接口类型的变量

       –在Action中定义一个setter方法,主要作用是接收spring注入进

         来DAO对象。

       –将Action和DAO都交给Spring容器,Action配置如下:

        <bean id=”action标识符” class=”action实现类”>

            <!–setter方式注入配置–>

            <property name=”属性名” 

               ref=”dao定义时的Bean组件Id值”>

            </property>

        </bean>

        参见上例“setter方式注入”

     4)采用构造方式注入重构3示例

          –定义带参数构造方法替代setter方法

          –定义Action的<bean>时,采用

        <constructor-arg>替代<property>配置

       <constructor-arg index=”构造参数索引”

           ref=”要注入的Bean对象的id”>

       </constructor-arg>

参见上例“构造方式注入”

 

5.各种类型数据的注入

  1)基本数据注入

     利用value属性指定,可以注入字符串,数值等简单数据。

  *2)Bean对象注入

     利用ref属性指定,可以注入一个Bean组件对象

<bean id=“hibernateCostDao” class=“com.tarena.dao.HibernateCostDAO”>

</bean>

<!– setter方式注入示例 –>

<bean id=“costAction” scope=“prototype” 

       class=“com.tarena.action.CostAction”>

<!– 将ref指定的id属性Bean对象给costDao属性注入 –>

<property name=“costDao” ref=“hibernateCostDao”>

</property>

    </bean>

  3)集合数据注入

  eg:

applicationContext.xml配置如下:

<bean id=“msgBean” scope=“singleton” 

class=“com.tarena.service.MessageBean”>

<!– 基本数据注入 –>

<property name=“name” value=“露丝”>

</property>

<!– 其中,value值的类型全部为String型,对于age属性来说,其类型为Int

型,在属性注入时Spring会自动进行类型转换(String—>int)

 –>

<property name=“age” value=“18”>

</property>

<!– List集合注入 –>

<property name=“friends”>

<list>

<value>TOM</value>

<value>JACK</value>

<value>张三丰</value>

</list>

</property>

<!– Set集合注入 –>

<property name=“cities”>

<set>

<value>北京</value>

<value>上海</value>

<value>深圳</value>

</set>

</property>

<property name=“includeTypes” value=“jpeg,gif,jpg”>

</property>

<!– Map集合注入 –>

<property name=“books”>

<map>

<entry key=“1001” value=“Core Java基础”></entry>

<entry key=“1002” value=“Struts框架详解”></entry>

<entry key=“1003” value=“编程之美”></entry>

</map>Spring经典总结

</property>

<!– Properties(本质是Map)属性注入 –>

<property name=“dbParams”>

<props>

<prop key=“username”>root</prop>

<prop key=“password”>1234</prop>

</props>

</property>

</bean>

测试类代码:

public class MessageBean {

private String name;

private int age;

private List<String> friends;

private Set<String> cities;

private Set<String> types;

private Map<Integer, String> books;

private Properties dbParams;

 

public void setDbParams(Properties dbParams) {

this.dbParams = dbParams;

}

 Spring经典总结

public void setIncludeTypes(String str) {

String[] arr = str.split(”,”);

types = new HashSet<String>();

for (String type : arr) {

types.add(type);

}

}

 

public void setCities(Set<String> cities) {

this.cities = cities;

}

 

public void setFriends(List<String> friends) {

this.friends = friends;

}

public void show() {

/**基本数据注入测试*/

System.out.println(“姓名:” + name);

System.out.println(“年龄:” + age);

/**List注入测试*/

System.out.println(“—她的朋友—”);

for (String s : friends) {

System.out.println(s);

}

/**Set集合注入测试*/

System.out.println(“—他们所在城市—”);

for (String s : cities) {

System.out.println(s);

}

System.out.println(“—允许上传的图片类型—”);

for (String s : types) {

System.out.println(s);

}

/**Map集合注入测试*/

System.out.println(“—–图书信息—–”);

Set<Integer> keys = books.keySet();

for (Integer key : keys) {

System.out.println(“编号:” + key + “ 名字:” + books.get(key));

}

/**Properties注入测试*/

System.out.println(“—-连接参数—–”);

Set<Object> dbKeys = dbParams.keySet();

for (Object key : dbKeys) {

System.out.println(key + “:” + dbParams.getProperty(key.toString()));

}

}

public void setAge(int age) {

this.age = age;

}

public void setName(String name) {

this.name = name;

}

public void setBooks(Map<Integer, String> books) {

this.books = books;

}

}

*6.什么是AOP,解决什么问题

     Aspect Oriented Programming 面向方面编程也叫面向切面编程

面向方面编程是以(OOP)面向对象编程为基础,这两种编程思想侧重点不同。OOP侧重于对象,根据需求提炼出对象结构。AOP侧重于方面对象,方面(共同处理组件)关注的是共通处理部分,例如事务管理,权限控制,日志记录等。可以通过配置将其作用到某一个或多个目标对象上。好处是实现组件重复利用,改善程序结构,提高灵活性。将共同处理组件与目标对象解耦。

   AOP主要是解决一对多调用问题,一个共通组件被多个目标组件调用,降低组件关联。

*7.Spring容器AOP的基本使用

 1)引入spring-aop开发包

 2)编写方面组件,封装共通的处理逻辑

 3)在spring配置文件中,定义方面组件,利用aop配置,将方面组件方

    法和目标组件方法作用在一起。

8. AOP相关概念

    *1)方面(Aspect)

        方面(组件)指的是共同业务处理,可以切入到(即作用到)多个目标

        对象,可以多次使用。

    *2)切入点(Pointcut)

        切入点是连接点(Pintcut)的集合,采用表达式指定,用于指定哪些

        组件和方法作为方面组件的切入目标。

*1)方法限定表达式

   可以规定哪些方法被切入方面组件,哪些不被切入,也就是

   定义目标对象,格式如下:

execution(修饰符? 返回类型 方法名(参数) throws异常? )

   示例1:匹配容器中Bean对象的find开始的方法

           execution(* find*(..))

第一个“*”表示返回类型不限,”find*”表示以“find

”开头的所有方法,”..”表示一个或多个参数(也即参

数不限)

   示例2:匹配CostServiceImpl类中所有方法

      execution(* tarena.service.CostServiceImpl.*(..))

   示例3:匹配tarena.service包下所有类的所有方法

    execution(* tarena.service.*.*(..))

   示例4:匹配tarena.service包及其子包下所有类所有方法

    execution(* tarena.service..*.*(..))

   示例5:匹配容器Bean对象中的find开始的方法,并且是 public void 修饰的

     execution(public void find*(..))

   *2.类型限定表达式

     可以规定哪个类中的所有方法被切入方面组件

  格式:within(包名.类型名)

    示例1:匹配CostServiceImpl类中所有方法

     within(tarena.service.CostServiceImpl)

    示例2:匹配tarena.service包下所有类所有方法

       within(tarena.service.*)

    示例3:匹配tarena.service包及其子包中所有类所有方法

       within(tarena.service..*)

   3.Bean的Id或Name名称限定

     可以按<bean>定义时,id或name属性值匹配  

      bean(beanIdOrName)

      示例1:匹配容器中id=costService的Bean对象

          bean(costService)

    示例2:匹配容器中id值以Service结尾的对象

        bean(*Service)

   4.参数类型限定

     args(参数类型列表)

     示例1:匹配有且只有一个参数,参数类型符合

               Serializable类型的方法

       args(java.io.Serializable)

   *注意:上述切入点表达式可以联合使用,采用&&,||连接

     3)连接点(JoinPoint)

       // 连接点的集合组成切入点,连接点指的是切面组件在目标对象上 // 作用的位置,例如:在方法调用前、方法调用后、或者发生异常。

       切入点是连接点的集合。代表方面组件和某一个目标方法的关联点。

    *4)通知(Advice)

        用于指定方面组件作用于目标对象中的目标方法的时机。例如前置

        通知,意思是先执行方面组件,再执行目标方法。

 Spring提供了5种类型的通知。用于指定方面组件在目标方法哪个

 位置切入。Spring经典总结

   a.前置通知 <aop:before>

      先执行方面组件,再执行目标组件方法

   b.后置通知 <aop:after-returning>

      先执行目标组件方法,没有异常再执行方面组件。

      如果发生异常,不会执行方面组件

   c.异常通知 <aop:after-throwing>

      当目标方法抛出异常之后,执行方面组件。

   d.最终通知 <aop:after>

      先执行目标方法,无论有没有异常都执行方面组件

   e.环绕通知 <aop:around>

      相当于前置+后置通知。在目标方法前和后都执行方面组件

   内部实现原理:

try{

     //前置通知切入

  //环绕前置通知切入

     //目标组件方法

  //环绕后置通知切入

     //后置通知切入

   }catch(){

    //异常通知切入

   }finally{

     //最终通知切入

   }

     5)目标对象(Target)

        方面组件作用的对象,即与切入点表达式匹配的对象。

     6)动态代理(AutoProxy)

       Spring采用了动态代理技术实现了AOP控制

       如果Spring采用了AOP配置后,容器getBean方法返回的组件对象

      是代理对象(一个动态生成类型,即动态代理类),用户在使用时,由

       代理对象调用切面组件和目标对象的功能。

     Spring采用的动态代理技术有以下两种:

      a.目标对象没有接口(使用cglib.jar工具包)

      适用于目标组件没有接口实现的情况。

 public class ServiceEnhancerCGLIB extends

 原目标组件类型{

    //重写目标对象的方法,在重写的方法中调用目标对象和方面组   件对象功能

 }

  b.目标对象有接口(采用JDK Proxy API)

      适用于目标组件有接口实现的情况。

      public class $Proxy4 implements 原目标组件接口{

         //重写目标接口方法,在重写的方法中调用目标对象和方面组件对 

           象功能

       }

    public void testDelete() {

String[] confs = { ”applicationContext.xml” };

ApplicationContext ac = new ClassPathXmlApplicationContext(confs);

CostService service = (CostService) ac.getBean(”costService”);

System.out.println(类名:”+service.getClass().getName());

//获得代理类中的所有public方法

                Method[] ms =service.getClass().getMethods();

for(Method m : ms){

System.out.println(m);

}

service.deleteCost();

}Spring经典总结

      程序运行结果如下:

类名:$Proxy4

public final void $Proxy4.addCost()

public final void $Proxy4.deleteCost()

public final void $Proxy4.findById()

public final boolean $Proxy4.isFrozen()

public final org.springframework.aop.TargetSource 

      $Proxy4.getTargetSource()

public final void 

      $Proxy4.addAdvisor(int,org.springframework.aop.Advisor) 

 

  从以上结果可以看出,动态代理类中重写了原实现类中的

         addCost()、deleteCost()、findById()方法并加入了方面(共同

         处理的方法),这样就可以实现对目标对象实现方面切入。

 

9.采用AOP记录异常信息

   1)编写记录异常信息的方面组件

   2)指定切入点表达式,指定目标对象

   3)指定异常通知,目标方法发生异常后执行方面组件

10.Log4j日志工具

   log4j-1.2.11.jar

主要用于消息输出。可以控制消息输出的级别,输出方式,格式。

   该工具主要有三类组件构成:

   1)Logger日志器

   用于将消息分成级别输出。

   2)Appender输出器

   用于实现消息输出的不同方式。例如控制台,文件等

   3)Layout布局器

   用于格式化消息内容

11.Spring注解配置

   Spring注解配置的作用和在applicationContext.xml中的配置的效果是一

   样的。如果开发大型程序,在applicationContext.xml中添加配置过于麻

   烦。

1)组件自动扫描技术

     可以自动扫描指定包下的组件,当遇到组件类定义前面有以下注解标记时,

     会将该组件纳入Spring容器。等价于<bean>定义。

      –首先需要在spring配置中开启组件扫描技术

     <context:component-scan base-package=”要扫描的包路径”/>

      –如果发现类定义前有以下注解标记

 @Component  :(字面意思就是组件),它在你确定不了是哪一

               个层的时候使用。各个情况都可使用

      @Controller  : 建议在Action组件使用

      @Service  : 业务逻辑层,就是我们的service或者manager层。建议

                    在Service组件使用

      @Repository  : 控制层,就是我们的action层。建议在DAO组件使用

   

其实,这四个注解的效果都是一样的,Spring都会把它们当做需要注入的Bean加载在上下文中;但是在项目中,却建议你严格按照除Componen的其余三个注解的含义使用在项目中。这对分层结构的web架构很有好处。

 

    上面四种标记默认将组件扫描到Spring容器,id值使用的是类名首字母小写,如果需要指定id,可以使用@Service(“id值”)格式定义.

可以使用@Scope注解指定scope=”“属性值,使用格式

@Scope(“prototype”)注解,

getBean(“costServiceImpl”)中的”costServiceImpl”为类名

CostServiceImpl的首字母小写,也可以在类前指定

@Service(“costService”)

      –如果两个组件之间有注入关系

    可以使用@Resource或@Autowired

    按类型匹配注入也可以按名称匹配注入,如果按名称匹配注入, 

    @Resource(name=”id属性”)

 

eg:

   DAO实现类的定义:

@Repository

@Scope(“prototype”)

public class CostDAOImpl implements CostDAO{

 …………

}

如此配置后,spring便将DAO扫描进容器,id为”CostDAO”(注意: 

id值是以CostDAOImpl实现的接口CostDAO的名称定义的。

 

  Service实现类的定义(需要用到DAO实现类,即Service组件和DAO 

  组件之间有注入关系):

@Service(“costService”)

@Scope(“prototype”)

public class CostServiceImpl implements CostService{

@Resource

//@Autowired和@Resource既可以放在属性前也可以放在setter

     方法前

private CostDAO costDao;

//public void setCostDao(CostDAO costDao){//可省略

//this.costDao = costDao;

//}

private CostDAO costDao;

  public void setCostDao(CostDAO costDao){//可省略

 this.costDao = costDao;

}

2)AOP注解配置

      –在spring配置中开启AOP注解方式

       <aop:aspectj-autoproxy />

      –在方面组件中使用以下注解标记

          ======类定义前使用======

          @Component //将组件扫描到容器

          @Asepect //将组件指定为方面组件

          ======通知方法前使用======

          @Around(“切入点表达式”) :环绕通知切入

          @Before(“切入点表达式”) :前置通知切入

          @AfterReturning() :后置通知切入

          @AfterThrowing() : 异常通知切入

          @After() : 最终通知切入

 

===================Spring整合=====================

12.Spring对数据访问技术的支持

   1)提供了一致的异常处理层次

       Spring将各种不同访问技术的异常类型封装,统一成了Spring的

       异常类型,DataAccessException。

   2)提供了编写DAO的一些DaoSupport和Template工具类采用JDBC

     技术,提JdbcDaoSupport,JdbcTemplate采用Hibernate,提供

     HibernateDaoSupport,HiberanteTemplate

   3)提供了声明式事务管理方法

     采用AOP机制实现了事务管理,在使用时只要追加事务配置就可以。

 

13.Spring如何整合JDBC技术

   1)引入Spring开发包和配置文件

   2)引入JDBC开发包(驱动包)

   3)编写数据表对应的实体类POJO

   4)编写DAO接口和实现类

      实现类 extends JdbcDaoSupport后,可以使用

      this.getJdbcTemplate方法获取Template对象。利用Template对

      象方法执行增删改查操作。

   5)在Spring容器中定义DAO,注意必须给DAO注入一个dataSource

      对象。

   6)引入dbcp连接池开发包,在Spring容器中定义一个dataSource

      对象,给DAO注入.

<!– 配置数据源–>

<bean id=“mydataSource” 

      class=“org.apache.commons.dbcp.BasicDataSource”>

<property name=“url”

value=“jdbc:oracle:thin:@localhost:1522:xe”>

</property>

<property name=“driverClassName” 

         value=“oracle.jdbc.driver.OracleDriver”>

</property>

<property name=“username” value=“system>

</property>

<property name=“password” value=“zhuxun”>

</property>

</bean>

<!–  配置SessionFactory –>

<bean id=“jdbcCostDAO” class=“com.tarena.dao.impl.JdbcCostDAO”>

<!– 注入dataSource连接资源 –>

<property name=“dataSource” ref=“mydataSource”>

</property>

</bean>

 

14.Spring如何整合Hibernate?

 1)引入开发框架

      –Spring开发包

      –数据库驱动包和dbcp连接池包

      –Hibernate开发包

    2)在src下添加Spring的配置文件applicationContext.xml

    3)添加实体类POJO和映射描述文件hbm.xml

    4)编写DAO接口和HibernateDAO实现类

       需要继承HibernateDaoSupport,使用HibernateTemplate工具类

       完成增删改查操作。

     5)需要在applicationContext.xml定义DAO组件,需要给DAO注入

       sessionFactory;SessionFactory需要注入DataSource.

==============================

JdbcCostDAO(JdbcTemplate)<—DataSource

    HibernateCostDAO(HibernateTemplate)<—SessionFactory<—DataSource

==============================

15.Spring如何与Struts2整合

   1)将Action纳入到Spring容器中

      可以采用扫描注解方式也可以采用XML的<bean>定义。

   2)Action使用Service或DAO组件时,采用注入方式,将Service

     和DAO给Action注入

   3)引入一个struts2-spring-plugin-2.1.8.jar开发包(当发生action请

      求时,StrutsFilter控制器会通过该开发包去Spring容器寻找Action

      对象,进行请求处理    )

     ===struts2-spring-plugin-2.1.8.jar原理=====

 该组件提供了一个StrutsSpringObjectFactory,当引入该jar包后,会利用StrutsSpringObjectFactory替代原Struts框架中的ObjectFactory负责生成Action对象。

StrutsSpringObjectFactory可以访问Spring容器。

该Factory会按struts.xml中<action>配置的class属性值作为原则寻找Spring容器中的Bean对象。

    a.利用class属性当做Bean组件的id值去Spring容器寻找

 4-1)修改struts.xml中所有<action>的class属性值,修改成容器中对应Action组件的id值

   b.利用class属性采用反射机制创建普通的action,之后将Spring容器Bean对象给action注入。

 4-2)不需要修改原有的struts.xml配置,需要修改Action组件代码,添加setter方法,以setter方式接收注入的DAO或Service.例如要注入容器中的costDAO,

就需要在Action中追加setCostDAO(){}

  ====================================

  5)在web.xml中定义ContextLoaderListener,用于在服务器启动时,

      实例化Spring容器。

 

StrutsSpringObjectFactory主要实现

try{

   //利用class属性去容器寻找

   Object action = ac.getBean(className);

}catch(Exception ex){

 //利用class属性找不到,尝试利用className采用反射机制创 

  建一个常规的action对象.

 //如果创建了action对象,会将Spring容器中的Bean对象给

   action对象注入。(默认采用名称匹配规则,容器中Bean的Id

   值和Action的set属性一致,就自动注入 )

}

 

 Spring经典总结

 

 启动Tomcat加载

 web.xml–>StrutsFilter–>struts.xml,strus-default.xml,struts-plugin.xml

 加载web.xml–>ContextLoaderListener–>applicationContext.xml

 

 

—hibernate—

antlr-2.7.6.jar

asm-attrs.jar

asm.jar

c3p0-0.9.1.jar

cglib-2.1.3.jar

 

dom4j-1.6.1.jar

freemarker.jar

hibernate3.jar

hibernate-tools.jar

jta.jar

 

junit-4.4.jar

log4j-1.2.11.jar

 

—struts2—

struts2-json-plugin-2.1.8.jar

xwork-core-2.1.6.jar

struts2-core-2.1.8.jar

ognl-2.7.3.jar

freemarker-2.3.15.jar

 

commons-fileupload-1.2.1.jar

commons-io-1.4.jap

 

—springIOC—

commons-logging-1.0.4.jar

spring.jar

 

—DBCP—

commons-collections-3.1.jar

commons-dbcp-1.2.2.jar

commons-pool.jar

 

—springAOP—

aspectjrt.jar

aopalliance.jar

aspectjweaver.jar

cglib-nodep-2.1_3.jar

 

struts2-spring-plugin

 Spring经典总结

—-jdbc—–

ojdbc6.jar

mysql-connector-java-5.1.8-bin.jar

 

16.Spring的事务管理

   Spring提供以下两种形式事务管理方法。

  *1)声明式事务管理(基于配置实现)

     a.基于XML方式配置

        –定义事务管理Bean

           Hibernate采用HibernateTransactionManager

           JDBC采用DataSourceTransactionManager

        –定义<tx:advice>事务通知

        –定义<aop:config>切入配置

        注意:如果将事务切入到Action组件,需要在<aop:config>添加

              proxy-target-class=”true”,指定采用CGLIB技术生成动态代理类

              实现AOP切入。目标对象有接口,不需要指定。

     b.基于注解方式配置 

       –定义事务管理Bean

       –在spring配置文件中开启事务注解配置

       <tx:annotation-driven proxy-target-class=”true”

       transaction-manager=”txManager”/>

       –在目标组件中使用@Transactional注解

         定义在方法前:该方法采用指定事务管理

         定义在类前:该类所有方法采用指定事务管理

@Transactiona(readOnly=true,

propagation=Propagation.REQUIRED)

 

  2)编程式事务管理,了解(基于Java代码实现)

public class SimpleService implements Service {

 

  public Object someServiceMethod() {

    return transactionTemplate.execute(

      new TransactionCallback() {

         public Object doInTransaction  

            (TransactionStatus status) {

            updateOperation1();

            return resultOfUpdateOperation2();

         }

    });

  }

      }

 

3)Spring中常用事务类型:

REQUIRED–支持当前事务,如果当前没有事务,就新建一个事务。这是 最常见的选择。

SUPPORTS–支持当前事务,如果当前没有事务,就以非事务方式执行。

MANDATORY–支持当前事务,如果当前没有事务,就抛出异常。

REQUIRES_NEW–新建事务,如果当前存在事务,把当前事务挂起。

NOT_SUPPORTED–以非事务方式执行操作,如果当前存在事务,就把当   前事务挂起。

NEVER–以非事务方式执行,如果当前存在事务,则抛出异常。

NESTED–如果当前存在事务,则在嵌套事务内执行。如果当前没有事务, 则进行与REQUIRED类似的操作。

              拥有多个可以回滚的保存点,内部回滚不会对外部事务产生影

              响。只对DataSourceTransactionManager有效

 以上的“Spring经典总结“是本人在学习期间亲自总结出来的,今天,把她晒出来,希望能够和大家分享下!

原创粉丝点击