Spring学习流程(马士兵笔记)

来源:互联网 发布:mac word 勾选 编辑:程序博客网 时间:2024/06/01 23:06

原文链接:http://blog.csdn.net/chenggil10/article/details/5899353

目录(?)[+]

知识点名称介绍工作重要程度面试重要程度方法建议IOC XML *** 练IOC Annotation *** 练IOC 注入方式(两种) ****练+背简单属性 *  集合注入 * 查自动装配 ** 生命周期 **查AOP概念  *** AOP配置 * 查事务管理AOP(xml annotation)*****练+背hibernateTemplate ***  架构 ******练+理解+说OpenSessionInView ***** CharacterEncodingFilter ***  TestContext *  SpringJDBCTemplate   用到现学

课程内容

1.     面向接口(抽象)编程的概念与好处

2.     IOC/DI的概念与好处

a)     inversion of control

b)     dependency injection

3.     AOP的概念与好处

4.     Spring简介

5.     Spring应用IOC/DI(重要)

a)     xml

b)     annotation

6.     Spring应用AOP(重要)

a)     xml

b)     annotation

7.     Struts2.1.6 + Spring2.5.6 + Hibernate3.3.2整合(重要)

a)     opensessionInviewfilter(记住,解决什么问题,怎么解决)

8.     Spring JDBC

面向接口编程(面向抽象编程)

1.     场景:用户添加

2.     Spring_0100_AbstractOrientedProgramming

a)     不是AOP:Aspect Oriented Programming

3.     好处:灵活

什么是IOC(DI),有什么好处

1.     把自己new的东西改为由容器提供

a)     初始化具体值

b)     装配

2.     好处:灵活装配

Spring简介

1.     项目名称:Spring_0200_IOC_Introduction

2.     环境搭建

a)     只用IOC

                i.          spring.jar , jarkata-commons/commons-loggin.jar

3.     IOC容器

a)     实例化具体bean

b)     动态装配

4.     AOP支持

a)     安全检查

b)     管理transaction

Spring IOC配置与应用

1.     FAQ:不给提示:

a)     window – preferences – myeclipse – xml – xml catalog

b)     User Specified Entries – add

                 i.          Location:    D:/share/0900_Spring/soft/spring-framework-2.5.6/dist/resources/spring-beans-2.5.xsd

                ii.          URI:                        file:///D:/share/0900_Spring/soft/spring-framework-2.5.6/dist/resources/spring-beans-2.5.xsd

               iii.          Key Type:    Schema Location

              iv.          Key:                         http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

2.     注入类型

a)     Spring_0300_IOC_Injection_Type

b)     setter(重要)

c)     构造方法(可以忘记)

d)     接口注入(可以忘记)

3.     id vs. name

a)     Spring_0400_IOC_Id_Name

b)     name可以用特殊字符

4.     简单属性的注入

a)     Spring_0500_IOC_SimpleProperty

b)     <property name=… value=….>

5.     <bean 中的scope属性

a)     Spring_0600_IOC_Bean_Scope

b)     singleton 单例

c)     proptotype 每次创建新的对象

6.     集合注入

a)     Spring_0700_IOC_Collections

b)     很少用,不重要!参考程序

7.     自动装配

a)     Spring_0800_IOC_AutoWire

b)     byName

c)     byType

d)     如果所有的bean都用同一种,可以使用beans的属性:default-autowire

8.     生命周期

a)     Spring_0900_IOC_Life_Cycle

b)     lazy-init (不重要)

c)     init-method destroy-methd 不要和prototype一起用(了解)

9.     Annotation第一步:

a)     修改xml文件,参考文档<context:annotation-config/>

10.  @Autowired

a)     默认按类型by type

b)     如果想用byName,使用@Qulifier

c)     写在private field(第三种注入形式)(不建议,破坏封装)

d)     如果写在set上,@qualifier需要写在参数上

11.  @Resource(重要)

a)     加入:j2ee/common-annotations.jar

b)     默认按名称,名称找不到,按类型

c)     可以指定特定名称

d)     推荐使用

e)     不足:如果没有源码,就无法运用annotation,只能使用xml

12.  @Component @Service @Controller @Repository

a)     初始化的名字默认为类名首字母小写

b)     可以指定初始化bean的名字

13.  @Scope

14.  @PostConstruct = init-method; @PreDestroy = destroy-method;

 

什么是AOP

1.     面向切面编程Aspect-Oriented-Programming

a)     是对面向对象的思维方式的有力补充

2.     Spring_1400_AOP_Introduction

3.     好处:可以动态的添加和删除在切面上的逻辑而不影响原来的执行代码

a)     Filter

b)     Struts2的interceptor

4.     概念:

a)     JoinPoint

b)     PointCut

c)     Aspect(切面)

d)     Advice

e)     Target

f)      Weave

Spring AOP配置与应用

1.     两种方式:

a)     使用Annotation

b)     使用xml

2.     Annotation

a)     加上对应的xsd文件spring-aop.xsd

b)     beans.xml <aop:aspectj-autoproxy/>

c)     此时就可以解析对应的Annotation了

d)     建立我们的拦截类

e)     用@Aspect注解这个类

f)      建立处理方法

g)     用@Before来注解方法

h)     写明白切入点(execution …….)

i)      让spring对我们的拦截器类进行管理@Component

3.     常见的Annotation:

a)     @Pointcut

b)     @Before

c)     @AfterReturning

d)     @AfterThrowing

e)     @After

f)      @Around

4.     织入点语法

a)     void !void

b)     参考文档(* ..)

5.     xml配置AOP

a)     把interceptor对象初始化

b)     <aop:config

                i.          <aop:aspect …..

1.     <aop:pointcut

2.     <aop:before

Spring整合Hibernate

1.     Spring 指定datasource

a)     参考文档,找dbcp.BasicDataSource

                i.          c3p0

               ii.          dbcp

             iii.          proxool

b)     在DAO或者Service中注入dataSource

c)     在Spring中可以使用PropertyPlaceHolderConfigure来读取Properties文件的内容

2.     Spring整合Hibernate

a)     <bean .. AnnotationSessionFactoryBean>

                i.          <property dataSource

               ii.          <annotatedClasses

b)     引入hibernate 系列jar包

c)     User上加Annotation

d)     UserDAO或者UserServie 注入SessionFactory

e)     jar包问题一个一个解决

3.     声明式的事务管理

a)     事务加在DAO层还是Service层?

b)     annotation

                i.          加入annotation.xsd

               ii.          加入txManager bean

             iii.          <tx:annotation-driven

             iv.          在需要事务的方法上加:@Transactional

               v.          需要注意,使用SessionFactory.getCurrentSession 不要使用OpenSession

c)     @Transactional详解

                i.          什么时候rollback

1.     运行期异常,非运行期异常不会触发rollback

2.     必须uncheck (没有catch)

3.     不管什么异常,只要你catch了,spring就会放弃管理

4.     事务传播特性:propagation_required

5.     read_only

d)     xml(推荐,可以同时配置好多方法)

                i.          <bean txmanager

               ii.          <aop:config

1.     <aop:pointcut

2.     <aop:advisor pointcut-ref advice-ref

             iii.          <tx:advice: id transaction-manager =

e)     HibernateTemplate、HibernateCallback、HibernateDaoSupport(不重要)介绍

                i.          设计模式:Template Method

               ii.          Callback:回调/钩子函数

             iii.          第一种:(建议)

1.     在spring中初始化HibernateTemplate,注入sessionFactory

2.     DAO里注入HibernateTemplate

3.     save写getHibernateTemplate.save();

             iv.          第二种:

1.     从HibernateDaoSupport继承

2.     必须写在xml文件中,无法使用Annotation,因为set方法在父类中,而且是final的

f)      spring整合hibernate的时候使用packagesToScan属性,可以让spring自动扫描对应包下面的实体类

Struts2.1.6 + Spring2.5.6 + Hibernate3.3.2

1.     需要的jar包列表

jar包名称

所在位置

说明

antlr-2.7.6.jar

hibernate/lib/required

解析HQL

aspectjrt

spring/lib/aspectj

AOP

aspectjweaver

..

AOP

cglib-nodep-2.1_3.jar

spring/lib/cglib

代理,二进制增强

common-annotations.jar

spring/lib/j2ee

@Resource

commons-collections-3.1.jar

hibernate/lib/required

集合框架

commons-fileupload-1.2.1.jar

struts/lib

struts

commons-io-1.3.2

struts/lib

struts

commons-logging-1.1.1

单独下载,删除1.0.4(struts/lib)

struts

spring

dom4j-1.6.1.jar

hibernate/required

解析xml

ejb3-persistence

hibernate-annotation/lib

@Entity

freemarker-2.3.13

struts/lib

struts

hibernate3.jar

hibernate

 

hibernate-annotations

hibernate-annotation/

 

hibernate-common-annotations

hibernate-annotation/lib

 

javassist-3.9.0.GA.jar

hiberante/lib/required

hibernate

jta-1.1.jar

..

hibernate transaction

junit4.5

 

 

mysql-

 

 

ognl-2.6.11.jar

struts/lib

 

slf4j-api-1.5.8.jar

hibernate/lib/required

hibernate-log

slf4j-nop-1.5.8.jar

hibernate/lib/required

 

spring.jar

spring/dist

 

struts2-core-2.1.6.jar

struts/lib

 

xwork-2.1.2.jar

struts/lib

struts2

commons-dbcp

spring/lib/jarkata-commons

 

commons-pool.jar

..

 

struts2-spring-plugin-2.1.6.jar

struts/lib

 

2.     BestPractice:

a)     将这些所有的jar包保存到一个位置,使用的时候直接copy

3.     步骤

a)     加入jar包

b)     首先整合Spring + Hibernate

                i.          建立对应的package

1.     dao / dao.impl / model / service / service.impl/ test

               ii.          建立对应的接口与类框架

1.     S2SH_01

             iii.          建立spring的配置文件(建议自己保留一份经常使用的配置文件,以后用到的时候直接copy改)

             iv.          建立数据库

               v.          加入Hibernate注解

1.     在实体类上加相应注解@Entity @Id等

2.     在beans配置文件配置对应的实体类,使之受管

             vi.          写dao service的实现

            vii.          加入Spring注解

1.     在对应Service及DAO实现中加入@Component,让spring对其初始化

2.     在Service上加入@Transactional或者使用xml方式(此处建议后者,因为更简单)

3.     在DAO中注入sessionFactory

4.     在Service中注入DAO

5.     写DAO与Service的实现

           viii.          写测试

c)     整合Struts2

                i.          结合点:Struts2的Action由Spring产生

               ii.          步骤:

1.     修改web.xml加入 struts的filter

2.     再加入spring的listener,这样的话,webapp一旦启动,spring容器就初始化了

3.     规划struts的action和jsp展现

4.     加入struts.xml

a)     修改配置,由spring替代struts产生Action对象

5.     修改action配置

a)     把类名改为bean对象的名称,这个时候就可以使用首字母小写了

b)     @Scope(“prototype”)不要忘记

             iii.          struts的读常量:

1.     struts-default.xml

2.     struts-plugin.xml

3.     struts.xml

4.     struts.properties

5.     web.xml

             iv.          中文问题:

1.     Struts2.1.8已经修正,只需要改i18n.encoding = gbk

2.     使用spring的characterencoding

3.     需要严格注意filter的顺序

4.     需要加到Struts2的filter前面

               v.          LazyInitializationException

1.     OpenSessionInViewFilter

2.     需要严格顺序问题

3.     需要加到struts2的filter前面

---------------------------------------------------------------------------------------------------------------------------------------

【详细版】

课程内容

1.     面向接口(抽象)编程的概念与好处

2.     IOC/DI的概念与好处

a)     inversion of control

b)     dependency injection

3.     AOP的概念与好处

4.     Spring简介

5.     Spring应用IOC/DI(重要)

a)     xml

b)     annotation

6.     Spring应用AOP(重要)

a)     xml

b)     annotation

7.     Struts2.1.6 + Spring2.5.6 + Hibernate3.3.2整合(重要)

a)     opensessionInviewfilter(记住,解决什么问题,怎么解决)

8.     Spring JDBC

面向接口编程(面向抽象编程)

1.     场景:用户添加

2.     Spring_0100_AbstractOrientedProgramming

a)     不是AOP:Aspect Oriented Programming

3.     好处:灵活

什么是IOC(DI),有什么好处

1.     把自己new的东西改为由容器提供

a)     初始化具体值

b)     装配

<?xml version="1.0"?>

-<beans>

<bean class="com.bjsxt.dao.impl.UserDAOImpl"id="u"/>class是个类。Id就等于构造了一个对象)

<bean class="com.bjsxt.service.UserService" id="userService">

<property bean="u"name="userDAO"/> </bean>

(把u这个对象注入到UserService这个类的一个userDAO的一个属性里)

-</beans>

2.     好处:灵活装配

Spring简介

1.     项目名称:Spring_0200_IOC_Introduction

2.     环境搭建

a)     只用IOC

               i.         spring.jar , jarkata-commons/commons-loggin.jar

3.     IOC容器

a)     实例化具体bean

b)     动态装配

4.     AOP支持

a)     安全检查

b)     管理transaction

Spring IOC配置与应用

1.     FAQ:不给提示:

a)     window – preferences – myeclipse – xml – xml catalog

b)     User Specified Entries – add

                i.         Location:       D:\share\0900_Spring\soft\spring-framework-2.5.6\dist\resources\spring-beans-2.5.xsd

               ii.         URI:             file:///D:/share/0900_Spring/soft/spring-framework-2.5.6/dist/resources/spring-beans-2.5.xsd

              iii.         KeyType:      Schema Location

             iv.         Key:              http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

2.     注入类型

a)     Spring_0300_IOC_Injection_Type

b)     setter(重要)

c)     构造方法(可以忘记)

d)    接口注入(可以忘记)

3.     id vs. Name(可以把Id换成name,没什么区别!)

a)     Spring_0400_IOC_Id_Name

b)     name可以用特殊字符

4.     简单属性的注入

a)     Spring_0500_IOC_SimpleProperty

b)     <property name=… value=….>

在配置文件里直接赋值!(在此简单属性为int和string,会自动转换)

5.     <bean 中的scope属性

a)     Spring_0600_IOC_Bean_Scope

b)     singleton 单例(无论去多少次都是同一个bean

c)     proptotype 每次创建新的对象

6.     集合注入

a)     Spring_0700_IOC_Collections

b)     很少用,不重要!参考程序

7.     自动装配

a)     Spring_0800_IOC_AutoWire

b)     byName

c)     byType

d)     如果所有的bean都用同一种,可以使用beans的属性:default-autowire

-<beanclass="com.bjsxt.dao.impl.UserDAOImpl" name="userDAO">

<property name="daoId"value="1"/> </bean>

 

<bean class="com.bjsxt.dao.impl.UserDAOImpl"name="userDAO2">

<property name="daoId"value="2"/> </bean>

 

<bean class="com.bjsxt.service.UserService"

autowire="byType"scope="prototype" id="userService">

</bean> </beans>

(这里会报错,因为有两个userDAOUserDAO2都是int类型!)

(如果说byname则会显示第一个的内容“1”!,因为UserService类里面的userDAO属性与第一个的名字一样!)

8.     生命周期

a)     Spring_0900_IOC_Life_Cycle

b)     lazy-init (不重要)

c)     init-method与destroy-methd 不要和prototype一起用(了解)

<bean class="com.bjsxt.dao.impl.UserDAOImpl"id="u">

</bean>

<bean class="com.bjsxt.service.UserService"id="userService" scope="prototype" destroy-method="destroy"init-method="init">

</bean>

</beans>

9.     Annotation第一步:

a)     修改xml文件,参考文档<context:annotation-config/>

 

b)     默认按类型by type

c)     如果想用byName,使用@Qulifier

d)     写在private field(第三种注入形式)(不建议,破坏封装)

e)     如果写在set上,@qualifier需要写在参数上

f)     

10.  @Resource(重要)

a)     加入:j2ee/common-annotations.jar

b)     默认按名称,名称找不到,按类型

c)     可以指定特定名称

d)     推荐使用

e)     不足:如果没有源码,就无法运用annotation,只能使用xml

11.  @Component

 @Service @Controller @Repository(四个一样的功能!!)

a)     初始化的名字默认为类名首字母小写

b)     可以指定初始化bean的名字

首先先加载

ClassPathXmlApplicationContextctx = new ClassPathXmlApplicationContext("beans.xml");

beans.xml里面的内容,然后通过

找从com.bjsxt开始“scan”含@component的类,

找到之后就初始化对象,结果在

其一个属相的set方法上找到一个源为“u”的一个bean,于是就加载那个bean

12.  @Scope

13.  @PostConstruct = init-method;(在构造对象后执行此方法)

@PreDestroy =destroy-method;(在容器销毁前执行此方法)

 

 

什么是AOP

1.     面向切面编程Aspect-Oriented-Programming(权限)

a)     是对面向对象的思维方式的有力补充

2.     Spring_1400_AOP_Introduction

3.     好处:可以动态的添加和删除在切面上的逻辑而不影响原来的执行代码

a)     Filter

b)     Struts2的interceptor

4.     概念:

a)    JoinPoint  释意:切面与原方法交接点 即 切入点

b)     PointCut  释意:切入点集合

com.xyz.someapp.service.下面的任何类,任何方法,任何返回值的一个切入点的集合。

c)     Aspect(切面)释意:可理解为代理类前说明(简单的理解为夹在类的新的业务逻辑,就是业务逻辑类)

d)     Advice 释意:可理解为代理方法前说明例如@Before(即加在切面上的说明)

e)     Target  释意:被代理对象 被织入对象

f)      Weave  释意:织入

Spring AOP配置与应用

Spring AOP的底层实现技术---JDK动态代理

2008-06-12 10:38:54

JDK动态代理(proxy   invocationhandler)
    在JDK 1.3以后提供了动态代理的技术,允许开发者在运行期创建接口的代理实例。在Sun刚推出动态代理时,还很难想象它有多大的实际用途,现在我们终于发现动态代理是实现AOP的绝好底层技术。
    JDK的动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler。其中 InvocationHandler是一个接口,可以通过实现该接口定义横切逻辑,在并通过反射机制调用目标类的代码,动态将横切逻辑和业务逻辑编织在一起。
   而Proxy为InvocationHandler实现类动态创建一个符合某一接口的代理实例。这样讲一定很抽象,我们马上着手动用Proxy和InvocationHandler这两个魔法戒对上一节中的性能监视代码进行AOP式的改造。
    首先,我们从业务类ForumServiceImpl 中删除性能监视的横切代码,使ForumServiceImpl只负责具体的业务逻辑,如所示:
代码清单 5 ForumServiceImpl:移除性能监视横切代码

package com.baobaotao.proxy;

public class ForumServiceImpl implementsForumService {

 public void removeTopic(int topicId) {

         

  System.out.println("模拟删除Topic记录:"+topicId);

  try {

   Thread.currentThread().sleep(20);

  }catch (Exception e) {

   throw new RuntimeException(e);

  }

   

 }

 public void removeForum(int forumId) {

         

  System.out.println("模拟删除Forum记录:"+forumId);

  try {

   Thread.currentThread().sleep(40);

  }catch (Exception e) {

   throw new RuntimeException(e);

  } 

 }

}

    在代码清单 5中的①和②处,原来的性能监视代码被移除了,我们只保留了真正的业务逻辑。
    从业务类中移除的横切代码当然还得找到一个寄居之所,InvocationHandler就是横切代码的家园乐土,我们将性能监视的代码安置在PerformaceHandler中,如代码清单 6所示:
代码清单 6 PerformaceHandler

package com.baobaotao.proxy;

importjava.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

public class PerformaceHandler implementsInvocationHandler {

    private Object target; 一般的都有一个object对象,object是被代理对象!

 public PerformaceHandler(Object target){//①target为目标的业务类

  this.target = target;

 }

 public Object invoke(Object proxy, Methodmethod, Object[] args)

   throws Throwable {

  PerformanceMonitor.begin(target.getClass().getName()+"."+method.getName());

  Object bj = method.invoke(target, args);//②通过反射方法调用目标业务类的业务方法

  PerformanceMonitor.end();

  return obj;

 }

}

 

    粗体部分的代码为性能监视的横切代码,我们发现,横切代码只出现一次,而不是原来那样星洒各处。大家注意②处的method.invoke(),该语句通 过反射的机制调用目标对象的方法,这样InvocationHandler的invoke(Object proxy, Method method, Object[] args)方法就将横切代码和目标业务类代码编织到一起了,所以我们可以将InvocationHandler看成是业务逻辑和横切逻辑的编织器。下面, 我们对这段代码做进一步的说明。
首先,我们实现InvocationHandler接口,该接口定义了一个 invoke(Object proxy, Method method, Object[] args)的方法,proxy是代理实例,一般不会用到;method是代理实例上的方法,通过它可以发起对目标类的反射调用;args是通过代理类传入 的方法参数,在反射调用时使用。
    此外,我们在构造函数里通过target传入真实的目标对象,如①处所示,在接口方法invoke(Object proxy, Method method, Object[] args)里,将目标类实例传给method.invoke()方法,通过反射调用目标类方法,如②所示。
    下面,我们通过Proxy结合PerformaceHandler创建ForumService接口的代理实例,如代码清单 7所示:
代码清单 7 TestForumService:创建代理实例

package com.baobaotao.proxy;

import java.lang.reflect.Proxy;

public class TestForumService {

 public static void main(String[] args) {

  ForumService target = new ForumServiceImpl();//①目标业务类

//② 将目标业务类和横切代码编织到一起

  PerformaceHandler handler = newPerformaceHandler(target);

         //③为编织了目标业务类逻辑和性能监视横切逻辑的handler创建代理类

  ForumService proxy = (ForumService)Proxy.newProxyInstance(

target.getClass().getClassLoader(),

    target.getClass().getInterfaces(),

 handler);

         //④ 操作代理实例

  proxy.removeForum(10);

  proxy.removeTopic(1012);

 }

}

 

    上面的代码完成了业务类代码和横切代码编织和接口代理实例生成的工作,其中在②处,我们将ForumService实例编织为一个包含性能监视逻辑的PerformaceHandler实例,然后在③处,通过Proxy的静态方法newProxyInstance()为融合了业务类逻辑和性能监视逻辑 的handler创建一个ForumService接口的代理实例,该方法的第一个入参为类加载器,第二个入参为创建的代理实例所要实现的一组接口,第三 个参数是整合了业务逻辑和横切逻辑的编织器对象。
按照③处的设置方式,这个代理实例就实现了目标业务类的所有接口,也即ForumServiceImpl的ForumService接口。这样,我们就可以按照调用ForumService接口的实例相同的方式调用代理实例,如④所示。运行以上的代码,输出以下的信息:

begin monitor...

模拟删除Forum记录:10

end monitor...

com.baobaotao.proxy.ForumServiceImpl.removeForum花费47毫秒。

begin monitor...

模拟删除Topic记录:1012

end monitor...

com.baobaotao.proxy.ForumServiceImpl.removeTopic花费26毫秒。

 

我们发现,程序的运行效果和直接在业务类中编写性能监视逻辑的效果一致,但是在这里,原来分散的横切逻辑代码已经被我们抽取到 PerformaceHandler中。当其它业务类(如UserService、SystemService等)的业务方法也需要使用性能监视时,我们 只要按照以上的方式,分别为它们创建代理对象就可以了。下面,我们用时序图描述调用关系,进一步代理实例的本质,如图1所示:
 
                     图 1代理实例的时序图
    我们在上图中特别使用虚线阴影的方式对通过代理器创建的ForumService实例进行凸显,该实例内部利用PerformaceHandler整合横 切逻辑和业务逻辑。调用者调用代理对象的的removeForum()和removeTopic()方法时,上图的内部调用时序清晰地告诉了我们实际上所 发生的一切。

public class UserServiceTest {

    @Test

    publicvoid testProxy() {

        UserDAO userDAO = new UserDAOImpl();

        LogInterceptor li = new LogInterceptor();

        li.setTarget(userDAO);

        UserDAO userDAOProxy =

(UserDAO)Proxy.newProxyInstance(userDAO.getClass().getClassLoader(),             userDAO.getClass().getInterfaces(),li);

        System.out.println(userDAOProxy.getClass());

        userDAOProxy.delete();

        userDAOProxy.save(new User());

       

    }

    /*class $Proxy4 implements UserDAO

     * {

     * save(User u) {

     * Method m = UserDAO.getclass.getmethod

     * li.invoke(this, m, u)

     * }

     * }

     */

}

public class LogInterceptorimplements InvocationHandler {

    private Objecttarget;

   

    public Object getTarget() {

        returntarget;

    }

 

    publicvoid setTarget(Object target) {

        this.target = target;

    }

 

    publicvoid beforeMethod(Methodm) {

       

        System.out.println(m.getName() +" start");

    }

 

    public Object invoke(Objectproxy, Method m, Object[] args)

            throws Throwable {

        beforeMethod(m);

        m.invoke(target, args);

        returnnull;

    }

}

 

 

 

 

1.     两种方式:

a)     使用Annotation

b)     使用xml

2.     Annotation

a)     加上对应的xsd文件spring-aop.xsd

b)     beans.xml <aop:aspectj-autoproxy/>(aspectj是专门产生代理的类)

c)     此时就可以解析对应的Annotation了

d)     建立我们的拦截类

e)     用@Aspect(切面逻辑)注解这个类

f)      建立处理方法

g)     用@Before来注解方法

h)     写明白切入点(execution …….)

i)      让spring对我们的拦截器类进行管理@Component

3.     常见的Annotation:

a)     @JoinPoint

b)     @Pointcut  切入点声明以供其他方法使用 , 例子如下:

 

@Aspect

@Component

public class LogInterceptor {

   

    @Pointcut("execution(public * com.bjsxt.dao..*.*(..))")(dao..代表包的任何子类)

    public void myMethod(){}

 

    @Around("myMethod()")

    public void before(ProceedingJoinPointpjp) throws Throwable{

        System.out.println("method before");

        pjp.proceed();

    }

    @AfterReturning("myMethod()")

    public void afterReturning() throws Throwable{

        System.out.println("method afterReturning");

    }

    @After("myMethod()")

    public void afterFinily() throws Throwable{

        System.out.println("method end");

    }

        }

 

c)     @Before 发放执行之前织入

d)     @AfterReturning 方法正常执行完返回之后织入(无异常)

e)     @AfterThrowing 方法抛出异常后织入

f)      @After 类似异常的finally

g)     @Around 环绕 类似filter , 如需继续往下执行则需要像filter中执行FilterChain.doFilter(..)对象一样 执行ProceedingJoinPoint.proceed()方可,例子如下:

@Around("execution(* com.bjsxt.dao..*.*(..))")

        public voidbefore(ProceedingJoinPoint pjp) throws Throwable{

                System.out.println("method start");

                pjp.proceed();//类似FilterChain.doFilter(..)告诉jvm继续向下执行

}

4.     织入点语法

a)     void !void

b)     参考文档(* ..)

如果execution(* com.bjsxt.dao..*.*(..))中声明的方法不是接口实现则无法使用AOP实现动态代理,此时可引入包” cglib-nodep-2.1_3.jar” 后有spring自动将普通类在jvm中编译为接口实现类,从而打到可正常使用AOP的目的.

5.  xml配置AOP(重要)

a)     把interceptor对象初始化

b)     <aop:config

               i.         <aop:aspect …..

1.     <aop:pointcut

2.     <aop:before

例子:

<beanid="logInterceptor"class="com.bjsxt.aop.LogInterceptor"></bean>

    <aop:config>

        <!-- 配置一个切面 -->

        <aop:aspectid="point"ref="logInterceptor">

            <!-- 配置切入点,指定切入点表达式 -->

            <!-- 此句也可放到 aop:aspect标签外依然有效-->

            <aop:pointcut

                expression=

                "execution(public * com.bjsxt.service..*.*(..))"

                id="myMethod"/>

            <!-- 应用前置通知 -->

            <aop:beforemethod="before"pointcut-ref="myMethod"/>

            <!-- 应用环绕通知需指定向下进行 -->

            <aop:aroundmethod="around"pointcut-ref="myMethod"/>

            <!-- 应用后通知 -->

            <aop:after-returningmethod="afterReturning"

                pointcut-ref="myMethod"/>

            <!-- 应用抛出异常后通知 -->

            <aop:after-throwingmethod="afterThrowing"

                pointcut-ref="myMethod"/>

            <!-- 应用最终通知  -->

            <aop:aftermethod="afterFinily"

                pointcut="execution(public* om.bjsxt.service..*.*(..))"/>

        </aop:aspect>

</aop:config>

Spring整合Hibernate

1.    Spring 指定datasource  javax中的一个接口,里面有一个getConnection()的方法(标准化的取得连接的一种方式!)

a)     参考文档,找dbcp.BasicDataSource(dbcp databaseconnect pour 数据库连接池)

第一种写法:

 

 <beanid="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"                    destroy-method="close">

 

  <!-- results ina setDriverClassName(String) call -->

  <propertyname="driverClassName">

   <value>com.mysql.jdbc.Driver</value>

 </property>

  <propertyname="url">

    <value>jdbc:mysql://localhost:3306/mydb</value>

 </property>

  <propertyname="username">

   <value>root</value>

 </property>

  <propertyname="password">

   <value>masterkaoli</value>

 </property>

</bean>

第二种写法:

<bean id="myDataSource"class="org.apache.commons.dbcp.BasicDataSource"                 destroy-method="close">

  <!-- results ina setDriverClassName(String) call -->

  <propertyname="driverClassName" value="com.mysql.jdbc.Driver"/>

  <propertyname="url" value="jdbc:mysql://localhost:3306/mydb"/>

  <propertyname="username" value="root"/>

  <propertyname="password" value="masterkaoli"/>

</bean>

 

 

               i.         c3p0

              ii.         dbcp

Proxool不管通过何种持久化技术,都必须通过数据连接访问数据库,在Spring中,数据连接是通过数据源获得的。在以往的应用中,数据源一般是 Web应用服务器提供的。在Spring中,你不但可以通过JNDI获取应用服务器的数据源,也可以直接在Spring容器中配置数据源,此外,你还可以 通过代码的方式创建一个数据源,以便进行无依赖的单元测试配置一个数据源
    Spring在第三方依赖包中包含了两个数据源的实现类包,其一是Apache的DBCP,其二是 C3P0。可以在Spring配置文件中利用这两者中任何一个配置数据源。

DBCP数据源
    DBCP类包位于 /lib/jakarta-commons/commons-dbcp.jar,DBCP是一个依赖 Jakarta commons-pool对象池机制的数据库连接池,所以在类路径下还必须包括/lib/jakarta- commons/commons-pool.jar。下面是使用DBCP配置MySql数据源的配置片断:

xml 代码
<bean id="dataSource"class="org.apache.commons.dbcp.BasicDataSource"      
       destroy-method="close">      
    <propertyname="driverClassName" value="com.mysql.jdbc.Driver"/>     
    <property name="url"value="jdbc:mysql://localhost:3309/sampledb" />     
    <propertyname="username" value="root" />     
    <propertyname="password" value="1234" />     
</bean> 
  BasicDataSource提供了close()方法关闭数据源,所以必须设定destroy-method=”close”属性,以便Spring 容器关闭时,数据源能够正常关闭。除以上必须的数据源属性外,还有一些常用的属性:
    defaultAutoCommit:设置从数据源中返回的连接是否采用自动提交机制,默认值为 true;
    defaultReadOnly:设置数据源是否仅能执行只读操作, 默认值为 false;
    maxActive:最大连接数据库连接数,设置为0时,表示没有限制;
    maxIdle:最大等待连接中的数量,设置为0时,表示没有限制;
    maxWait:最大等待秒数,单位为毫秒, 超过时间会报出错误信息;
    validationQuery:用于验证连接是否成功的查询SQL语句,SQL语句必须至少要返回一行数据, 如你可以简单地设置为:“select count(*) from user”;
    removeAbandoned:是否自我中断,默认是 false ;
    removeAbandonedTimeout:几秒后数据连接会自动断开,在removeAbandoned为true,提供该值;
    logAbandoned:是否记录中断事件, 默认为 false;

C3P0数据源
    C3P0是一个开放源代码的JDBC数据源实现项目,它在lib目录中与Hibernate一起发布,实现了JDBC3和JDBC2扩展规范说明的 Connection 和Statement 池。C3P0类包位于/lib/c3p0/c3p0-0.9.0.4.jar。下面是使用C3P0配置一个 Oracle数据源:

xml 代码
<bean id="dataSource"class="com.mchange.v2.c3p0.ComboPooledDataSource"      
        destroy-method="close">     
    <propertyname="driverClass" value=" oracle.jdbc.driver.OracleDriver"/>     
    <property name="jdbcUrl"value=" jdbc:oracle:thin:@localhost:1521:ora9i "/>     
    <property name="user"value="admin"/>     
    <property name="password"value="1234"/>     
</bean> 
ComboPooledDataSource和BasicDataSource一样提供了一个用于关闭数据源的close()方法,这样我们就可以保证Spring容器关闭时数据源能够成功释放。
    C3P0拥有比DBCP更丰富的配置属性,通过这些属性,可以对数据源进行各种有效的控制:
    acquireIncrement:当连接池中的连接用完时,C3P0一次性创建新连接的数目;
    acquireRetryAttempts:定义在从数据库获取新连接失败后重复尝试获取的次数,默认为30;
    acquireRetryDelay:两次连接中间隔时间,单位毫秒,默认为1000;
    autoCommitOnClose:连接关闭时默认将所有未提交的操作回滚。默认为false;
    automaticTestTable: C3P0将建一张名为Test的空表,并使用其自带的查询语句进行测试。如果定义了这个参数,那么属性preferredTestQuery将被忽略。你不能在这张Test表上进行任何操作,它将中为C3P0测试所用,默认为null;
    breakAfterAcquireFailure:获取连接失败将会引起所有等待获取连接的线程抛出异常。但是数据源仍有效保留,并在下次调   用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试获取连接失败后该数据源将申明已断开并永久关闭。默认为 false;
    checkoutTimeout:当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出SQLException,如设为0则无限期等待。单位毫秒,默认为0;
    connectionTesterClassName: 通过实现ConnectionTester或QueryConnectionTester的类来测试连接,类名需设置为全限定名。默认为com.mchange.v2.C3P0.impl.DefaultConnectionTester;
    idleConnectionTestPeriod:隔多少秒检查所有连接池中的空闲连接,默认为0表示不检查;
    initialPoolSize:初始化时创建的连接数,应在minPoolSize与maxPoolSize之间取值。默认为3;
    maxIdleTime:最大空闲时间,超过空闲时间的连接将被丢弃。为0或负数则永不丢弃。默认为0;
    maxPoolSize:连接池中保留的最大连接数。默认为15;
    maxStatements:JDBC的标准参数,用以控制数据源内加载的PreparedStatement数量。但由于预缓存的Statement属 于单个Connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素,如果maxStatements与 maxStatementsPerConnection均为0,则缓存被关闭。默认为0;
    maxStatementsPerConnection:连接池内单个连接所拥有的最大缓存Statement数。默认为0;
    numHelperThreads:C3P0是异步操作的,缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能,通过多线程实现多个操作同时被执行。默认为3;
    preferredTestQuery:定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个参数能显著提高测试速度。测试的表必须在初始数据源的时候就存在。默认为null;
    propertyCycle: 用户修改系统配置参数执行前最多等待的秒数。默认为300;
    testConnectionOnCheckout:因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable
等方法来提升连接测试的性能。默认为false;
    testConnectionOnCheckin:如果设为true那么在取得连接的同时将校验连接的有效性。默认为false。

读配置文件的方式引用属性:

<bean id="propertyConfigurer"    
       class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">     
    <propertyname="location" value="/WEB-INF/jdbc.properties"/>     
</bean>     
<bean id="dataSource"class="org.apache.commons.dbcp.BasicDataSource"      
       destroy-method="close">     
    <propertyname="driverClassName" value="${jdbc.driverClassName}"/>     
    <property name="url"value="${jdbc.url}" />     
    <property name="username"value="${jdbc.username}" />     
    <propertyname="password" value="${jdbc.password}" />     
</bean>  
    在jdbc.properties属性文件中定义属性值:
    jdbc.driverClassName=com.mysql.jdbc.Driver
    jdbc.url= jdbc:mysql://localhost:3309/sampledb
    jdbc.username=root
    jdbc.password=1234
    提示 经常有开发者在${xxx}的前后不小心键入一些空格,这些空格字符将和变量合并后作为属性的值。如: 的属性配置项,在前后都有空格,被解析后,username的值为“ 1234 ”,这将造成最终的错误,因此需要特别小心。

获取JNDI数据源
    如果应用配置在高性能的应用服务器(如WebLogic或Websphere等)上,我们可能更希望使用应用服务器本身提供的数据源。应用服务器的数据源 使用JNDI开放调用者使用,Spring为此专门提供引用JNDI资源的JndiObjectFactoryBean类。下面是一个简单的配置:

xml 代码
<bean id="dataSource"class="org.springframework.jndi.JndiObjectFactoryBean">     
    <propertyname="jndiName" value="java:comp/env/jdbc/bbt"/>     
</bean> 
通过jndiName指定引用的JNDI数据源名称。
    Spring 2.0为获取J2EE资源提供了一个jee命名空间,通过jee命名空间,可以有效地简化J2EE资源的引用。下面是使用jee命名空间引用JNDI数据源的配置:

xml 代码
<beans xmlns=http://www.springframework.org/schema/beans   
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance   
xmlns:jee=http://www.springframework.org/schema/jee   
xsi:schemaLocation="http://www.springframework.org/schema/beans    
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd    
http://www.springframework.org/schema/jee   
http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">     
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/bbt"/>     
</beans> 
Spring的数据源实现类
    Spring本身也提供了一个简单的数据源实现类DriverManagerDataSource ,它位于org.springframework.jdbc.datasource包中。这个类实现了javax.sql.DataSource接口,但它并没有提供池化连接的机制,每次调用getConnection()获取新连接时,只是简单地创建一个新的连接。因此,这个数据源类比较适合在单元测试 或简单的独立应用中使用,因为它不需要额外的依赖类。
     下面,我们来看一下DriverManagerDataSource的简单使用:当然,我们也可以通过配置的方式直接使用DriverManagerDataSource。

java 代码
DriverManagerDataSource ds = new DriverManagerDataSource ();     
ds.setDriverClassName("com.mysql.jdbc.Driver");     
ds.setUrl("jdbc:mysql://localhost:3309/sampledb");     
ds.setUsername("root");     
ds.setPassword("1234");     
Connection actualCon = ds.getConnection(); 

小结

    不管采用何种持久化技术,都需要定义数据源。Spring附带了两个数据源的实现类包,你可以自行选择进行定义。在实际部署时,我们可能会直接采用应用服 务器本身提供的数据源,这时,则可以通过JndiObjectFactoryBean或jee命名空间引用JNDI中的数据源。

DBCPC3PO配置的区别:

C3PO DBCP

xml 代码
<bean id="dataSource"class="com.mchange.v2.c3p0.ComboPooledDataSource"destroy-method="close"> 
    <propertyname="driverClass"> 
       <value>oracle.jdbc.driver.OracleDriver</value> 
    </property> 
    <propertyname="jdbcUrl">            
       <value>jdbc:oracle:thin:@10.10.10.6:1521:DataBaseName</value> 
     </property> 
    <property name="user"> 
       <value>testAdmin</value> 
    </property> 
    <propertyname="password"> 
       <value>123456</value> 
    </property> 
</bean> 

xml 代码
<bean id="dataSource"class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close"> 
    <propertyname="driverClassName"> 
       <value>oracle.jdbc.driver.OracleDriver</value> 
    </property> 
    <propertyname="url">            
       <value>jdbc:oracle:thin:@10.10.10.6:1521:DataBaseName</value> 
     </property> 
    <propertyname="username"> 
       <value>testAdmin</value> 
    </property> 
    <propertyname="password"> 
       <value>123456</value> 
    </property> 
</bean>

            iii.          

 

b)     在DAO或者Service中注入dataSource

c)     在Spring中可以使用PropertyPlaceHolderConfigure来读取Properties文件的内容

<beanclass="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

   <property name="locations">

       <value>classpath:com/foo/jdbc.properties</value>

   </property>

</bean>

(在这个bin(PropertyPlaceholderConfigurer)下面有一个属性“locations”,在classpath下的jdbc.properties文件里面有配置,设置到相关下面bin里面,于是可以在src目录下建一个jdbc.properties的文件,里面写上,与下面的datasource相对应!)

<bean id="dataSource"destroy-method="close"

     class="org.apache.commons.dbcp.BasicDataSource">

   <property name="driverClassName" value="${jdbc.driverClassName}"/>

   <property name="url" value="${jdbc.url}"/>

   <property name="username" value="${jdbc.username}"/>

   <property name="password" value="${jdbc.password}"/>

</bean>

 

2.  Spring整合Hibernate

a)     <bean .. AnnotationSessionFactoryBean>

               i.         <property dataSource

              ii.         <annotatedClasses

b)     引入hibernate 系列jar包

c)     User上加Annotation

d)     UserDAO或者UserServie 注入SessionFactory

e)     jar包问题一个一个解决

3.     声明式的事务管理

a)     事务加在DAO层还是Service层?(加在Service

b)     annotation

               i.         加入annotation.xsd

              ii.         加入txManager bean

            iii.         <tx:annotation-driven

例如: <bean id="transactionManager"                    class="org.springframework.orm.hibernate3.HibernateTransactionManager">

          <propertyname="sessionFactory">

            <refbean="sessionFactory" />

          </property>

    </bean>

   <tx:annotation-driven transaction-manager="transactionManager"/>

            iv.         在需要事务的方法上加:@Transactional

              v.          

            vi.         需要注意,Hibernate获得session时要使用SessionFactory.getCurrentSession不能使用OpenSession

c)     @Transactional详解

               i.         什么时候rollback

1.     运行期异常,非运行期异常不会触发rollback

2.     必须uncheck (没有catch)

3.     不管什么异常,只要你catch了,spring就会放弃管理

4.     事务传播特性:propagation_required(propagation是一个enum,默认值是required!唯一需要记住的)

例如:@Transactional(propagation=Propagation.REQUIRED)等同于(@Transactional)

作用,一个方法声明了@Transactional事务后,其内再调用的方法不需要再声明@Transactional.

5.     read_only

例如:@Transactional(propagation=Propagation.REQUIRED,readOnly=true)

当方法声明readOnly=true,该方法及其调用的方法内都不执行insert update

Property

Type

Description

 

propagation

enum: Propagation

optional propagation setting

 

isolation

enum: Isolation

optional isolation level

 

readOnly

boolean

read/write vs. read-only transaction

 

timeout

int (in seconds granularity)

the transaction timeout

 

rollbackFor

an array of Class objects, which must be derived from Throwable

an optional array of exception classes which must cause rollback

自己设置的异常回滚

rollbackForClassname

an array of class names. Classes must be derived from Throwable

an optional array of names of exception classes that must cause rollback

 

noRollbackFor

an array of Class objects, which must be derived from Throwable

an optional array of exception classes that must not cause rollback.

 

noRollbackForClassname

an array of String class names, which must be derived from Throwable

an optional array of names of exception classes that must not cause rollback

 

 

d)     xml(推荐,可以同时配置好多方法)

               i.         <bean txmanager

              ii.         <aop:config

1.     <aop:pointcut

2.     <aop:advisor pointcut-ref advice-ref

            iii.         <tx:advice: idtransaction-manager =

            iv.         <propertyname="packagesToScan">  可定义扫描目标包下所有实体类

例如: <bean id="sessionFactory"

             class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">

          <property name="dataSource"ref="dataSource" />

          <propertyname="hibernateProperties">

                  <props>

                <propkey="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>

                        <propkey="hibernate.show_sql">true</prop>  

                  </props>

            </property>

            <!--

          <propertyname="annotatedClasses">

                <list>

                      <value>com.bjsxt.model.TestUser</value>

                      <value>com.bjsxt.model.Log</value>

                </list>

          </property>

           -->

           <!-- 将参数名称设为packagesToScan可定义扫描目标包下所有实体类 -->

           <property name="packagesToScan">

               <list>

                     <value>com.bjsxt.model</value>

               </list>

           </property>

    </bean>

<bean id="transactionManager"

       class="org.springframework.orm.hibernate3.HibernateTransactionManager">

        <propertyname="sessionFactory">

            <refbean="sessionFactory" />

       </property>

    </bean>

   

    <aop:config>

       <aop:pointcut

                  expression="execution(public* com.bjsxt.service..*.*(..))"

                  id="myServiceMethod"/>

       <aop:advisor pointcut-ref="myServiceMethod"advice-ref="txAdvice"/>

   </aop:config>

   

    <tx:adviceid="txAdvice" transaction-manager="transactionManager">

       <tx:attributes>

           <tx:method name="save*" propagation="REQUIRED"/>

           <tx:method name="add*" propagation="REQUIRED"/>

           <tx:method name="update*" propagation="REQUIRED"/>

           <tx:method name="del*" propagation="REQUIRED"/>

           <tx:method name="cancel*" propagation="REQUIRED"/>

           <tx:method name="*" read-only="true" />

       </tx:attributes>

    </tx:advice>

e)     HibernateTemplate(理解这个)、HibernateCallback、HibernateDaoSupport(不重要)介绍

               i.         设计模式:TemplateMethod(模板方法)

              ii.         Callback:回调/钩子函数

            iii.         第一种:(建议)

1.     在spring中初始化HibernateTemplate,注入sessionFactory

<bean id="hibernateTemplate"

    class="org.springframework.orm.hibernate3.HibernateTemplate">

<property name="sessionFactory"ref="sessionFactory" />

</bean>

2.     DAO里注入HibernateTemplate

private HibernateTemplate hibernateTemplate;

 

@Resource

public void setHibernateTemplate(HibernateTemplatehibernateTemplate) {

      this.hibernateTemplate= hibernateTemplate;

}

3.     save写getHibernateTemplate.save();

public void save(TestUser testUser) {

      hibernateTemplate.save(testUser);

}

            iv.         第二种:

1.     从HibernateDaoSupport继承(此方法不好用可忽略)

2.     必须写在xml文件中,无法使用Annotation,因为set方法在父类中,而且是final的

例如:

首先,新建SuperDAOImpl(使用Annotation注入--@Component):

@Component

public class SuperDAOImpl {

      privateHibernateTemplate hibernateTemplate; //此处定义由spring注入管理

      publicHibernateTemplate getHibernateTemplate() {

            return hibernateTemplate;

      }

      @Resource

      public voidsetHibernateTemplate(HibernateTemplate hibernateTemplate) {

            this.hibernateTemplate =hibernateTemplate;

      }

}

此时,xml中必须要有:

<bean id="hibernateTemplate"

class="org.springframework.orm.hibernate3.HibernateTemplate">

      <propertyname="sessionFactory" ref="sessionFactory" />

</bean>

或者,SuperDAOImpl类写成下面代码:

@Component

public class SuperDAOImpl extends HibernateDaoSupport {

      @Resource(name="sessionFactory")

      public voidsetSuperHibernateTemplate(SessionFactory sessionFactory) {

            super.setSessionFactory(sessionFactory);

      }

}

对应的xml中则可省略

<bean id="hibernateTemplate"………部分

只要包含

<bean id="sessionFactory"……..部分即可

 

最后,其他类继承SuperDaoImpl类后便可直接使用HibernateTemplate

@Component("u")

public class UserDAOImpl extends SuperDAOImpl implementsUserDAO {

      public voidsave(TestUser testUser) {

            this.getHibernateTemplate().save(testUser);

      }

}

第三种:

f)      spring整合hibernate的时候使用packagesToScan属性,可以让spring自动扫描对应包下面的实体类

Struts2.1.6 + Spring2.5.6 + Hibernate3.3.2

1.     需要的jar包列表

jar包名称

所在位置

说明

antlr-2.7.6.jar

hibernate/lib/required

解析HQL

aspectjrt

spring/lib/aspectj

AOP

aspectjweaver

..

AOP

cglib-nodep-2.1_3.jar

spring/lib/cglib

代理,二进制增强

common-annotations.jar

spring/lib/j2ee

@Resource

commons-collections-3.1.jar

hibernate/lib/required

集合框架

commons-fileupload-1.2.1.jar

struts/lib

struts

commons-io-1.3.2

struts/lib

struts

commons-logging-1.1.1

单独下载,删除1.0.4(struts/lib)

struts

spring

dom4j-1.6.1.jar

hibernate/required

解析xml

ejb3-persistence

hibernate-annotation/lib

@Entity

freemarker-2.3.13

struts/lib

struts

hibernate3.jar

hibernate

 

hibernate-annotations

hibernate-annotation/

 

hibernate-common-annotations

hibernate-annotation/lib

 

javassist-3.9.0.GA.jar

hiberante/lib/required

hibernate

jta-1.1.jar

..

hibernate transaction

junit4.5

 

 

mysql-

 

 

ognl-2.6.11.jar

struts/lib

 

slf4j-api-1.5.8.jar

hibernate/lib/required

hibernate-log

slf4j-nop-1.5.8.jar

hibernate/lib/required

 

spring.jar

spring/dist

 

struts2-core-2.1.6.jar

struts/lib

 

xwork-2.1.2.jar

struts/lib

struts2

commons-dbcp

spring/lib/jarkata-commons

 

commons-pool.jar

..

 

struts2-spring-plugin-2.1.6.jar

struts/lib

 

2.     BestPractice:

a)     将这些所有的jar包保存到一个位置,使用的时候直接copy

3.     步骤

a)     加入jar包

b)     首先整合Spring + Hibernate

               i.         建立对应的package

1.     dao / dao.impl / model / service / service.impl/ test

              ii.         建立对应的接口与类框架

1.     S2SH_01

            iii.         建立spring的配置文件(建议自己保留一份经常使用的配置文件,以后用到的时候直接copy改)

            iv.         建立数据库

              v.         加入Hibernate注解

1.     在实体类上加相应注解@Entity @Id等

在字段属性的get方法上加--@Column(name = "表字段名")

2.     在beans配置文件配置对应的实体类,使之受管

            vi.         写dao service的实现

           vii.         加入Spring注解

1.     在对应Service及DAO实现中加入@Component,让spring对其初始化

2.     在Service上加入@Transactional或者使用xml方式(此处建议后者,因为更简单)

3.     在DAO中注入sessionFactory

4.     在Service中注入DAO

5.     写DAO与Service的实现

          viii.         写测试

c)     整合Struts2

               i.         结合点:Struts2的Action由Spring产生

              ii.         步骤:

1.     修改web.xml加入 struts的filter

如下:

<filter>

      <filter-name>struts2</filter-name>

      <filter-class>

            org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

      </filter-class>

</filter>

<filter-mapping>

      <filter-name>struts2</filter-name>

      <url-pattern>/*</url-pattern>

</filter-mapping>

2.     再加入spring的listener,这样的话,webapp一旦启动,spring容器就初始化了

如下:

<!-- 指定由spring初始化加载xml配置文件 springstruts结合必备 -->

<listener>

      <listener-class>

            org.springframework.web.context.ContextLoaderListener

            <!-- 默认寻找xml路径:WEB-INF/applicationContext.xml -->

      </listener-class>

</listener>

 

<!--整个应用的参数服务启动时读取.

      可指定spring初始化文件路径位置 -->

<context-param>

      <param-name>contextConfigLocation</param-name>

      <param-value>

            classpath*:spring/*applicationContext.xml

      </param-value>

</context-param>

3.     规划struts的action和jsp展现

4.     加入struts.xml

a)    修改配置,由spring替代struts产生Action对象

5.     修改action配置

a)    把类名改为bean对象的名称,这个时候就可以使用首字母小写了

b)    @Scope(“prototype”)不要忘记

            iii.         struts的读常量:

1.     struts-default.xml

2.     struts-plugin.xml

3.     struts.xml

4.     struts.properties

5.     web.xml

            iv.         中文问题:

1.     Struts2.1.8已经修正,只需要改i18n.encoding= gbk

2.     使用spring的characterencoding

:

<!-- 过滤器相关配置 ========字符编码过滤======== -->

<filter>

      <filter-name>CharacterEncodingFilter</filter-name>

      <filter-class>

            org.springframework.web.filter.CharacterEncodingFilter

      </filter-class>

      <init-param>

            <param-name>encoding</param-name>

            <param-value>UTF-8</param-value>

      </init-param>

      <init-param>

            <param-name>forceEncoding</param-name>

            <param-value>true</param-value>

      </init-param>

</filter>

3.     需要严格注意filter的顺序

4.     需要加到Struts2的filter前面

              v.         LazyInitializationException

1.     OpenSessionInViewFilter

2.     需要严格顺序问题

3.     需要加到struts2的filter前面

 

:

1

@Autowired @Resource都可以用来装配bean.  都可以写在属性定义上,或写在set方法上

@Autowired (srping提供的)默认按类型装配

@Resource ( j2ee提供的 )默认按名称装配,当找不到(不写name属性)名称匹配的bean再按类型装配.

可以通过@Resource(name="beanName")指定被注入的bean的名称,要是指定了name属性,就用字段名去做name属性值,一般不用写name属性.

@Resource(name="beanName")指定了name属性,按名称注入但没找到bean,就不会再按类型装配了.

@Autowired @Resource可作用在属性定义上就不用写set方法了(此方法不提倡);

 

 

2

      a.

Action类前加@Component,Action可由spring来管理,例子如下:

Action中写:

@Component("u") //spring管理注解

@Scope("prototype") //多态

public class UserAction extends ActionSupportimplements ModelDriven{

      //内部属性需要有get/set方法且需要set方法前加@Resource@Autowired

}

 

Struts2配置文件中写

<action name="u"class="u">

 

Jsp

<form method="post"action="u.do" >

 

b.

Action中也可不加@ComponentActionstruts2-spring-plugin管理。此时,如果Action中定义的属性有set方法@Autowired@Resource也可不写,但是如果没有set方法,则需要在属性前加上@Autowired@Resource才能生效。

 

 

      3

Hibernate如果使用load来查询数据,例如:

Service中:

public User loadById(int id) {

      returnthis.userDao.loadById(id);

}

DAO中:

public User loadById(int id) {

      return(User)this.hibernateTemplate.load(User.class, id);

}

此时,session(应该说的是Hibernatesession)在事物结束(通常是service调用完)后自动关闭。由于使用的是load获取数据,在jsp页面申请取得数据时才真正的执行sql,而此时session已经关闭,故报错。

Session关闭解决方法:

web.xml中增加filter—openSessionInView,用于延长sessionjsp调用完后再关闭

如下所示:

注意:filter–openSessionInView一定要在 filter—struts2之前调用

        Filter顺序先进后出!

<filter>

      <filter-name>OpenSessionInViewFilter</filter-name>

      <filter-class>

org.springframework.orm.hibernate3.support.OpenSessionInViewFilter

</filter-class>

      <init-param>

            <param-name>sessionFactoryBeanName</param-name>

            <param-value>sf</param-value>(此处默认指定的sessionFactory应为” sessionFactory”默认可省略此行如果shring配置文件中配置的sessionFactory”sf”则此处需要写sf  一般用不到)

      </init-param>

</filter>

<filter-mapping>

      <filter-name>OpenSessionInViewFilter </filter-name>

      <url-pattern>/*</url-pattern>

</filter-mapping>

<filter>

      <filter-name>struts2</filter-name>

      <filter-class>

org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

</filter-class>

</filter>

<filter-mapping>

      <filter-name>struts2</filter-name>

      <url-pattern>/*</url-pattern>

</filter-mapping>



0 0
原创粉丝点击