spring总结

来源:互联网 发布:户外烧烤 知乎 编辑:程序博客网 时间:2024/06/06 07:17

spring 7大组成模块:
1:spring core:提供了spring 的核心功能,BeanFactory是spring核心容器的主要组件,
      它通过Ioc把程序的配置和依赖性与实际的代码分开,是整个spring的基础

2:spring context:通过配置文件向spring提供上下文信息,
       它构建在BeanFactory之上,另外增加了国际化和资源访问等功能

3:spring dao:提供了一个简单有效的JDBC应用

4:spring aop:提供了面向方面编程的功能

5:spring orm:spring除了有自己的JDBC以外还提供了对其他ORM框架的支持,如Hibernate,都可以和spring进行良好的结合

6:spring web:提供了简化的处理多部分请求以及把请求参数绑定到域的任务。

7:spring MVC:提供了MVC2模式的实现,也可以和struts良好的集成在一起。

    这七大模块可以单独使用,不需要其他模块的支持
 
--------------------------------------------------------
    spring的特点:
 
    1:设计良好的分层结构。
    2:以IOC为核心,提倡面向接口编程。
    3:良好的架构设计。
    4:可以代替EJB
    5:实现了MVC2
    6:可以和其他框架良好的结合如:Hibernate ,struts等
 
    编写第一个HelloWorld程序:
    1:interface
     public interface IHelloWorld {
    public void sayHello();
}
    2:实现类:
    public class HelloWorld implements IHelloWorld{
    private String msg;
    public String getMsg() {
     return msg;
    }
    public void setMsg(String msg) {
     this.msg = msg;
    }
    public void sayHello(){
     System.out.println(msg);
    }
}
    3:编写spring配置文件:applicationContext.xml
     <beans>
    <bean    id="Hello" class="EnHelloWorld">
    <property name="msg">
    <value>Hello World!</value>
    </property>
    </bean>
      </beans>
   
    4:编写测试类:
    public class TestHelloWorld {
     public static void main(String[] args) {
      ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");
    IHelloWorld hw= (IHelloWorld)ac.getBean("Hello");
    hw.sayHello();
}
}

---------------------------------------------------------------------
依赖注入的三种方式:
1:接口注入
2:set注入
3:构造注入
spring支持set注入和构造注入
把上面的HelloWorld改为构造注入:
1:实现类:
    public class CHelloWorld implements IHelloWorld{
    public String msg;
    public CHelloWorld(String msg){
     this.msg = msg;
    }
    public void sayHello(){
     System.out.print(msg);
    }
}
    2:在spring配置文件:applicationContext.xml中:
      <bean    id="CHello" class="CHelloWorld">
      <constructor-arg index="0">
       <value>C Hello World!</value>
      </constructor-arg>
 </bean>
constructor-arg 用来表示用构造方式注入参数
index="0"表示是构造方法中的第一个参数

    3:编写测试类:
    public class TestHelloWorld {
     public static void main(String[] args) {
      ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");
    IHelloWorld hw= (IHelloWorld)ac.getBean("CHello");
    hw.sayHello();
}
}

---------------------------------------------------------------------------
Spring的核心容器:

spring中两个最基本最重要的包:
org.springframework.context和org.springframework.beans为spring的IOC提供了基础
在这两个最重要的类是BeanFactory和ApplicationContext。BeanFactory来管理各种bean。ApplicationContext在BeanFactory之上
增加了其他功能如国际化,获取资源事件传递等。
1:bean的标志(id 和name)
     每个bean都有一个id在管理bean的BeanFactory和ApplicationContext中必须是唯一标志。
     id和name都可以用来指定id这两者中至少有一个。区别是id的命名必须符合xml id中和合法字符。name则没有限制,而且可以使

用name指定多个id

2:bean的类

class属性路径要完整,包名.类名

3:singleton的使用
     在spring 中bean可以定义为两种部署模式:

 * singleton 每次调用getBean()时,只返回一个实例
 * prototype, 每次调用getBean()时,返回新的实例

(singleton, prototype, requesst, session ,global session)

4:bean的属性:
     在定义bean的属性时除了直接指定bean的属性外还可以参考配置文件中定义的其他bean
      1:
<bean    id="DateHello" class="DateHelloWorld">
<property name="msg">
<value>Hello World!</value>
</property>
<property name="date">
<bean id="date" class="java.util.Date"/>
</property>
</bean>
      2:
<bean    id="DateHello" class="DateHelloWorld">
<property name="msg">
<value>Hello World!</value>
</property>
<property name="date">
<ref bean="date"/>
</property>
</bean>
     <bean id="date" class="java.util.Date"/>

5:null值的处理
      把属性设为null值有两种方法:
1:
<bean    id="DateHello" class="DateHelloWorld">
<property name="msg">
<value>null</value>
</property>
</bean>
2:
<bean    id="DateHello" class="DateHelloWorld">
<property name="msg">
<null/>
</property>
</bean>

6:使用depends-on

bean的depends-on可以用来在初始化这个bean前,强制执行一个或多个bean的初始化。
如:
<bean    id="DateHello" class="DateHelloWorld" depends-on="date">

 

7:

什么是属性编辑器,其作用是什么?
 * 自定义属性编辑器的目的,是要将在spring配置文件中定义的字符串转换为相应的
 对象进行注入!spring已经内置了很多类型的属性编辑器。我们也可以定义自己的属性
 编辑器。
如何自定义属性编辑器?
 * 定义属性编辑器,请参考UtilDatePropertyEditor.java
 * 将属性编辑器注册到spring中,请参考applicationContext-beans.xml中的注册方式

public class UtilDatePropertyEditor extends PropertyEditorSupport {
 
 private String format = "yyyy-MM-dd";
 
 @Override
 public void setAsText(String text) throws IllegalArgumentException {
  SimpleDateFormat sdf = new SimpleDateFormat(format);
  try {
   Date dateValue = sdf.parse(text);
   setValue(dateValue);
  } catch (ParseException e) {
   e.printStackTrace();
  }
 }

 public void setFormat(String format) {
  this.format = format;
 }
}


 <!-- 自定义java.util.Date属性编辑器 -->
 <bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
  <property name="customEditors">
   <map>
    <entry key="java.util.Date">
     <bean class="com.bjsxt.spring.UtilDatePropertyEditor">
      <property name="format" value="yyyy/MM/dd"/>
     </bean>
    </entry>
   </map>
  </property>
 </bean>
 
 <bean id="bean1" class="com.bjsxt.spring.Bean1">
  <property name="strValue" value="hello"/>
  <property name="intValue" value="123"/>
  <property name="dateValue" value="2006/8/7"/>
 </bean>          
 
 <bean id="bean2" class="com.bjsxt.spring.Bean2">
  <property name="bean3" ref="bean3"/>
  <property name="bean4">
   <ref bean="bean4"/>
  </property>
  <property name="bean5">
   <bean class="com.bjsxt.spring.Bean5">
    <property name="id" value="100"/>
   </bean>
  </property>
 </bean>


8:abstract parent

spring中的继承是强调的属性值的注入
id="beanAbstract"可以没有class

 <bean id="beanAbstract" abstract="true">
  <property name="name">
   <value>Mike</value>
  </property>
 </bean>
 
 <bean id="bean3" class="com.bjsxt.spring.Bean3" parent="beanAbstract">
  <property name="date" value="2006/08/07"/>
 </bean> 
---------------------------------------------------------------------------------------

bean的生命周期:

1:bean的定义
//配置bean的开始,beans中包含一个或多个bean
<beans>
    //定义一个bean id是唯一标志,class是bean的来源
        <bean    id="DateHello" class="DateHelloWorld">
    //配置bean的开始
    <property name="msg">
    <null/>
    </property>
    //定义bean的结束
    </bean>
//配置bean的结束
</beans>
2:bean的初始化
初始化有两种方式:
1在配置文件中指定init-method属性来完成
     public class HelloWorld {
    private String msg;
    public void init(){
    msg="Hello World";
    }
    public String getMsg() {
     return msg;
    }
    public void setMsg(String msg) {
     this.msg = msg;
    }
    public void sayHello(){
     System.out.println(msg);
    }
    }

applicationContext.xml文件中
<bean    id="DateHello" class="HelloWorld" init-method="init">
 

2实现org.springframework.beans.factory.InitialingBean接口
          实现其中的afterPropertiesSet()方法

     public class HelloWorld implements InitializingBean{
    private String msg;
    public void afterPropertiesSet(){
    msg="Hello World";
    }
    public String getMsg() {
     return msg;
    }
    public void setMsg(String msg) {
     this.msg = msg;
    }
    public void sayHello(){
     System.out.println(msg);
    }
    }

applicationContext.xml文件中
<bean    id="DateHello" class="HelloWorld">
</bean>


3:bean的使用
有三种方式:
1:使用BeanWrapper
    HelloWorld helloWorld = new HelloWorld ();
    BeanWrapper bw = new BeanWrapperImpl(helloWorld);
       bw.setPropertyValue("msg","HelloWorld");
    System.out.println(bw.getPropertyValue("msg"));
2:使用BeanFactory
    InputStream is = new FileInputStream("applicationContext.xml");
    XmlBeanFactory factory = new XmlBeanFactory (is);
    HelloWorld helloWorld = (HelloWorld)factory.getBean ("HelloWorld");
    helloWorld.sayHello();

3:使用ApplicationContext
    ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");
    IHelloWorld hw= (IHelloWorld)ac.getBean("CHello");
    hw.sayHello();

4:bean的销毁
销毁有两种方式:
1在配置文件中指定destory-method属性来完成
     public class HelloWorld {
    private String msg;
    public void init(){
    msg="Hello World";
    }
    public void cleanup(){
    msg="";
    }
    public String getMsg() {
     return msg;
    }
    public void setMsg(String msg) {
     this.msg = msg;
    }
    public void sayHello(){
     System.out.println(msg);
    }
    }

applicationContext.xml文件中
<bean    id="DateHello" class="HelloWorld" init-method="init" destory-method="cleanup">
 

2实现org.springframework.beans.factory.DisposeableBean接口
          实现其中的destory()方法

     public class HelloWorld implements InitializingBean,DisposeableBean{
    private String msg;
    public void afterPropertiesSet(){
    msg="Hello World";
    }
    public void destory(){
    msg="";
    }
    public String getMsg() {
     return msg;
    }
    public void setMsg(String msg) {
     this.msg = msg;
    }
    public void sayHello(){
     System.out.println(msg);
    }
    }

applicationContext.xml文件中
<bean    id="DateHello" class="HelloWorld">
</bean>
----------------------------------------------------------
用ref属性指定依赖的三种方式
1:用local属性指定:local属性的值必须与被参考引用的bean的id一致,如果在同一个xml文件里没有匹配的元素,xml解析将产生一

个错误
     如:
<bean    id="DateHello" class="DateHelloWorld">
    <property name="msg">
     <value>Hello World!</value>
    </property>
    <property name="date">
     <ref local="date"/>
    </property>
</bean>
      <bean id="date" class="java.util.Date"/>
   
     2:用bean属性指定
          用ref元素中的bean属性指定被参考引用的bean是spring中最常见的形式,它允许指向的bean可以在同一xml文件中也可以不

在同一个xml文件里
          bean属性的值可以与被引用的bean的id相同也可以与name相同。
      <bean    id="DateHello" class="DateHelloWorld">
    <property name="msg">
    <value>Hello World!</value>
    </property>
    <property name="date">
    <ref bean="date"/>
    </property>
<!--
<property name="date" ref="date"/>
-->
    </bean>
      <bean id="date" class="java.util.Date"/>
     3:用parent属性指定
      用ref元素中的parent属性指定被参考引用的bean时,允许引用当前BeanFactory或ApplicationContext的父BeanFactory或

ApplicationContext
      bean属性的值可以与被引用的bean的id相同也可以与name相同。

<bean    id="DateHello" class="DateHelloWorld">
    <property name="msg">
     <value>Hello World!</value>
    </property>
    <property name="date">
     <ref parent="date"/>
    </property>
</bean>
     用local属性指定和用bean属性指定的比较
     相同:都可以使用id来参考引用,可以对同一xml文件进行参考引用
     不同:bean属性的值可以与被引用的bean的id相同也可以与name相同。可以引用不在同一个xml文件里的bean
   
----------------------------------------------------------
bean自动装配的5种模式:
可以使用bean元素的autowire属性来指定bean的装配模式:
1:byName
2: byType
3:constructor
4:autodetect
5:no
显示的指定依赖如:property 和constructor-arg元素总会覆盖自动装配。对与大型应用不鼓励使用自动装配

--------------------------------------------------------------
      bean 依赖检查的4种模式:

      依赖检查能够分别对每个bean应用或取消应用,默认的是不检查依赖关系,
      可以使用bean元素的dependency-check属性来指定bean的依赖检查,共有4种:
      1:使用simple模式
      是指对基本类型、字符串和集合进行依赖检查
      如:
      <bean    id="DateHello" class="DateHelloWorld" autowire="autodetect" dependency-check="simple">
    </bean>
      <bean id="date" class="java.util.Date"/>
      只会对msg进行检查

      2:使用object模式
      是指对对象进行依赖检查
      如:
      <bean    id="DateHello" class="DateHelloWorld" autowire="autodetect" dependency-check="object">
    </bean>
      <bean id="date" class="java.util.Date"/>
      只会对date进行检查
   
      3:使用all模式
      是指对所有属性进行依赖检查
      如:
      <bean    id="DateHello" class="DateHelloWorld" autowire="autodetect" dependency-check="all">
    </bean>
      <bean id="date" class="java.util.Date"/>
      会对msg进行检查和date进行检查
    
     4:使用none模式
      是指对所有属性不进行依赖检查
      如:
      <bean    id="DateHello" class="DateHelloWorld" autowire="autodetect" dependency-check="none">
    </bean>
      <bean id="date" class="java.util.Date"/>
      不会对msg进行检查和date进行检查
   
      总结:一般情况下依赖检查和自动装配结合使用,当bean属性都有默认值或不需要对bean的属性是否被设置到bean上检查时,依

赖检查的作用就不大了
    
-----------------------------------------------------------------------
集合的注入方式
对于集合List Set Map Props元素则有不同的配置方式
1:List
       public class HelloWorld{
       //定义一个List变量msg
       List msg=null;
       public void setMsg(List msg){
       this.msg = msg;
      }
       }
       xml文件:
      <bean    id="Hello" class="HelloWorld">
    <property name="msg">
    <list>
    <value>Hello World!</value>
    <value>Hello World2!</value>
    </list>
    </property>
    </bean>

2:set

       public class HelloWorld{
       //定义一个Set变量msg
          Set msg=null;
       public void setMsg(Set msg){
       this.msg = msg;
      }
       }
       xml文件:
      <bean    id="Hello" class="HelloWorld">
    <property name="msg">
    <set>
    <value>Hello World!</value>
    <value>Hello World2!</value>
    </set>
    </property>
    </bean>
3:map
       public class HelloWorld{
       //定义一个Map变量msg
          Map msg=null;
       public void setMsg(Map msg){
       this.msg = msg;
      }
       }
       xml文件:
      <bean    id="Hello" class="HelloWorld">
    <property name="msg">
    <map>
    <entry key="h1">
    <value>Hello World!</value>
    </entry>
    <entry key="h2">
    <value>Hello World2!</value>
    </entry>
    </map>
    </property>
    </bean>

4:properties
  
       public class HelloWorld{
       //定义一个properties变量msg
       Properties msg;
       public void setMsg(Properties msg){
       this.msg = msg;
      }
       }
       xml文件:
      <bean    id="Hello" class="HelloWorld">
    <property name="msg">
    <props>
    <prop key ="h1">Hello World!</prop>
    <prop key ="h2">Hello World2!</prop>
    </props>
    </property>
    </bean>
 
 
 
    ---------------------------------------------------------------
    Spring AOP(Aspect Oriented Programming)
 
    应用程序通常包含两种代码:一是核心业务代码,一是和业务关系不大的代码如日志、事物处理等。
    AOP的思想就是使这两种代码分离,从而降低了两种代码的偶合性,达到了易于重用和维护的目的。
    AOP和OOP:
    在AOP里,每个关注点的实现并不知道是否有其他关注点关注它,这是AOP和OOP的主要区别,
    在AOP里组合的流向是从横切关注点到主关注点,在OOP中组合流向是从主关注点到横切关注点。
    AOP和OOP所关注的对象不同,AOP是OOP有益的补充,不是对立面。
 
切面(Aspect)
连接点(Joinpoint)
通知(Advice)
切入点(Pointcut)
引入(Introduction)
目标对象(Target Object)
AOP代理(AOP Proxy)
织入(Weaving)

通知的类型:

前置通知(Before advice)
返回后通知(After returning advice)
抛出异常后通知(After throwing advice)
后通知(After (finally) advice)
环绕通知(Around Advice)

环绕通知是最常用的一种通知类型。大部分基于拦截的AOP框架,例如Nanning和JBoss4,都只提供环绕通知。

 


    Spring 的3种切入点的实现:
    1:静态切入点:
       静态切入点只限于给定的方法和目标类。不考虑方法的参数。
    2:动态切入点:
       动态切入点不仅限于给定的方法和目标类,还可以指定方法的参数。(众多重载方法中的一个)
       动态切入点有很大的性能损耗,一般很少使用。
    3:自定义切入点:
      正在发展
   
   
    Spring 的通知:
    1:Intercdption Around通知
 
     Intercdption Around在JiontPoint的前后执行。实现Intercdption Around通知要实现
     MethodInterceptor接口,示例代码如下:
     public class LoginInterceptor implements MethodInterceptor{
      public Object invoke(MenthodInvocation invocation) throws Throwable{
       System.out.println("开始审核数据");
       Object result = invocation.proceed();
       System.out.println("审核数据结束");
       return result;
      }
     }
    2:Before通知
 
        Before通知在JiontPoint的前执行。实现Befored通知要实现
     MethodBeforeAdvice接口,示例代码如下:
     public class LoginBeforeAdvice implements MethodBeforeAdvice{
      public void Beforee(Menthod m,Object [] atgs,Object target) throws Throwable{
       System.out.println("开始审核数据");
      }
     }
  
  
    3:After Return 通知
 
      After Return通知在JiontPoint后执行。实现After Returnd通知要实现
     AfterReturningAdvice接口,示例代码如下:
     public class LoginAfterAdvice implements AfterReturningAdvice{
      public void AfterReturning(Menthod m,Object [] atgs,Object target) throws Throwable{
       System.out.println("审核数据结束");
      }
     }
 
    4:Throw通知
 
      Throw通知在JiontPoint抛出异常时执行。实现Throw通知要实现
     ThrowAdvice接口,示例代码如下:
     public class LoginThrowAdvice implements ThrowAdvice{
      public void AfterThrowing(RemoteException ex) throws Throwable{
       System.out.println("审核数据异常");
      }
     }
 
    5:Introduction 通知
 
      Introduction通知在JiontPoint 调用完毕后执行。实现Introduction通知要实现
     IntroductionAdvisor接口和IntroductionInterceptor接口。

--------------------------------------------------------
以下为老的方式不再用了

//////////////////////////////////////////////////////////////////////////////////////////////////////////
//用ProxyFactoryBean创建AOP代理
//    使用org.springfamework.aop.framework.ProxyFactoryBean是创建AOP代理的基本方式。
//
//1:使用ProxyFactoryBean代理目标类中的所有方法
// 示例代码:
// <beans>
// <bean id="log" class="logAround"/>
// <bean id="logBefore" class="logBefore"/>
// <bean id="logAfter" class="logAfter"/>
// <bean id="logThrow" class="logThrow"/>
// <bean id="timebook" class="TimeBook"/>
// <!-设定代理类-->
// <bean id="logProxy" class ="org.springframework.aop.framework.ProxyFactoryBean">
// <!--代理的是接口-->
// <property name="proxyInterface">
// <value>TimeBookInterface</value>
// </property>
//    <!--要代理的目标类-->
// <property name="target">
// <ref bean="timebook"/>
// </property>
// <!--程序中的Advice-->
// <property name="interceptorNames">
// <list>
// <value>logBefore</value>
// <value>logAfter</value>
// <value>logThrow</value>
// </list>
// </property>
// </bean>
// </beans>
//
//
//2:使用ProxyFactoryBean代理目标类中的指定方法
//
//  示例代码:
//  <beans>
//  <bean id="log" class="logAround"/>
//  <bean id="logBefore" class="logBefore"/>
//  <bean id="logAfter" class="logAfter"/>
//  <bean id="logThrow" class="logThrow"/>
//  <bean id="timebook" class="TimeBook"/>
//  <!--代理目标类的指定方法-->
//  <bean id ="logAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
//  <property name="advice">
//  <ref bean="log"/>
//  </property>
//  <!--指定要代理的方法-->
//  <property name="patterns">
//  <value>doCheck*</value>
//  </property>
//  </bean>
//  <!-设定代理类-->
//  <bean id="logProxy" class ="org.springframework.aop.framework.ProxyFactoryBean">
//  <!--代理的是接口-->
//  <property name="proxyInterfaces">
//  <value>TimeBookInterface</value>
//  </property>
//     <!--要代理的目标类-->
//  <property name="target">
//  <ref bean="timebook"/>
//  </property>
//  <!--程序中的Advice-->
//  <property name="interceptorNames">
//  <list>
//   <value>logAdvisor</value>
//  </list>
//  </property>
//  </bean>
//  </beans>
//
//  ---------------------------------------------------------
//
// 正则表达式:
// 1:.表示可以匹配任何一个字符
// 2:[]表示只有[]里指定的字符才能匹配
// 3:*表示匹配次数
// 4:?表示可以匹配1或0次
// 5:/是正则表达式的连接符
//
// ---------------------------------------------------------------
// Spring 中两种AOP代理方式
// 1:动态代理
// 动态代理是指代理的是接口,Spring默认的是动态代理
// 2:CGLIB代理
// <beans>
// <bean id="log" class="logAround"/>
// <bean id="logBefore" class="logBefore"/>
// <bean id="logAfter" class="logAfter"/>
// <bean id="logThrow" class="logThrow"/>
// <bean id="timebook" class="TimeBook"/>
// <bean id="logProxy" class ="org.springframework.aop.framework.ProxyFactoryBean">
// <property name="proxyTargetClass">
// <value>true</value>
// </property>
// <property name="target">
// <ref bean="timebook"/>
// </property>
// <property name="interceptorNames">
// <list>
// <value>logBefore</value>
// <value>logAfter</value>
// <value>logThrow</value>
// </list>
// </property>
// </bean>
// </beans>
//
//-----------------------------------------------------------------------
//Spring 中的自动代理方式
//
//自动代理可以跨越多个类,不管哪个类中的方法只要符合要求都可以代理
//<beans>
//<bean id="log" class="logAround"/>
//<bean id="logBefore" class="logBefore"/>
//<bean id="logAfter" class="logAfter"/>
//<bean id="logThrow" class="logThrow"/>
//<bean id="timebook" class="TimeBook"/>
//<bean id="timework" class="TimeWork"/>
//<!--使用自动代理-->
//<bean id="autoProxy" class ="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
//<bean id="logBeforAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
//<property name="advice">
//<ref bean="logBefore"/>
//</property>
//<property name="patterns">
//<value>.*do.*</value>
//</property>
//</bean>
//</beans>
//
//------------------------------------------------------------
//Spring中的事务处理
//
// 事务处理是由多个步骤组成,这些步骤之间有一定的逻辑关系,作为一个整体的操作过程,所有的步骤必须同时成功
//
//或失败。
// 1:提交     当所有的操作步骤都被完整执行后,称为该事物被提交。
// 2:回滚     由于某个操作失败,导致所有的步骤都没被提交则事物必须回滚,回到事物执行前的状态。
//
// 事务的特性:
// ACID:原子性(Atomicity)一致性(Consistency)隔离性(Isolation)持久性(Durablity)
//
// Spring中的事务处理是基于动态AOP机制的实现。
//
// 1:编程式事务处理:
//
// spring 提供的TransactionTemplate能够以编程的方式实现事务控制。
//
// HelloADO.java:
//
//  public int create(String msg){
//  DefaultTransactionDefinition def = new DefaultTransactionDefinition();
//  TransactionStatus status = transactionManager.getTransaction(def);
//
//  try{
//   JdbcTemplate jt = new JdbcTemplate(dataSource);
//   int i=jt.update("insert into st(name,password) values('zz','zz')");
//   return i;
//  }catch (Exception e){
//   transactionManager.rollback(status);
//   return 0;
//  }
//  finally {
//   transactionManager.commit(status);
//  }
//  }
// applicationContext.xml
//
//  <beans>
//  <bean id ="dataSource" class ="org.springframework.jdbc.datasource.DriverManagerDataSource">
//  <property name="driverClassName">
//  <value>com.mysql.jdbc.Driver</value>
//  </property>
//  <property name="url">
//  <value>jdbc:mysql://localhost:3306/newdb</value>
//  </property>
//  <property name="username">
//  <value>root</value>
//  </property>
//  <property name="password">
//  <value>lxl</value>
//  </property>
//  </bean>
//  <bean id="transactionManager"
//
//class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
//  <property name="dataSource">
//  <ref bean="dataSource"/>
//  </property>
//  </bean>
//  <bean id="helloDAO" class ="HelloDAO">
//  <property name="dataSource">
//  <ref bean="dataSource"/>
//  </property>
//  <property name="transactionManager">
//  <ref bean="transactionManager"/>
//  </property>
//  </bean>
//  </beans>
//
// 2:声明式事务处理:
//
// HelloADO.java:
//
//  public class HelloDAO {
//  private DataSource dataSource ;
//  private JdbcTemplate jdbcTemplate;
//  public void setDataSource(DataSource dataSource) {
//   this.dataSource = dataSource;
//   jdbcTemplate = new JdbcTemplate(dataSource);
//  }
//  public void create(String name){
//   jdbcTemplate.update("insert into st(name,password)values('lxl','lxl')");
//  }
//  }
// applicationContext.xml
//  <beans>
//  <bean id ="dataSource" class ="org.springframework.jdbc.datasource.DriverManagerDataSource">
//  <property name="driverClassName">
//  <value>com.mysql.jdbc.Driver</value>
//  </property>
//  <property name="url">
//  <value>jdbc:mysql://localhost:3306/newdb</value>
//  </property>
//  <property name="username">
//  <value>root</value>
//  </property>
//  <property name="password">
//  <value>lxl</value>
//  </property>
//  </bean>
//  <bean id="transactionManager"
//
//class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
//  <property name="dataSource">
//  <ref bean="dataSource"/>
//  </property>
//  </bean>
//  <bean id="helloDAO" class ="HelloDAO">
//  <property name="dataSource">
//  <ref bean="dataSource"/>
//  </property>
//  </bean>
//  <!-- 声明式事务处理-->
//  <bean id="helloDAOProxy"
//
//class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
//  <property name="transactionManager">
//  <ref bean="transactionManager"/>
//  </property>
//  <property name="target">
//  <ref bean="helloDAO"/>
//  </property>
//  <property name="transactionAttributes">
//  <props>
//  <!-- 对create方法进行事务管理,PROPAGATION_REQUIRED表示如果没有事务就新建一个事务-->
//  <prop key="create*">PROPAGATION_REQUIRED</prop>
//  </props>
//  </property>
//  </bean> 
//  </beans>
////////////////////////////////////////////////////////////////////////////////////////////////////////

AOP spring两种方式
1,对AspectJ的支持
2,spring自身的xml文件配置方式

  * 如果目标类实现了接口,默认采用JDK动态代理来实现AOP
  * 如果目标类没有实现接口,必须添加CGLIB支持,Spring会自动的在JDK和CGLIB代理之间切换
  * 如果目标类实现了接口,可以定义让spring强制使用CGLIB代理

  如何强制使用CGLIB代理实现AOP
  * 将<aop:config>定义为<aop:config proxy-target-class="true">,
    并且要引入CGLIB包:SPRING_HOME/lib/cglib/*.jar
 

1,AspectJ

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
/**
 * 定义切面
 */
@Aspect
public class MySecurityManagerImpl implements MySecurityManager {

 /**
  * 定义一个切入点,切入点的名称:allAddMethod(该方法的返回值需要是void,该
  * 方法只是一个标识),切入点的内容是一个表达式,以描述需要横切那些对象的那些方法
  * 的调用
  *
  * 具体表达是式的用法,参考spring文档6.2.3.4章节
  */
 @Pointcut("execution(* add*(..)) || execution(* del*(..)) || execution(* modify*(..))")
 private void allAddMethod() {}
 
 /**
  * 定一个advice,标识在那些切入点的何处插入本方法
  * 返回值必是void
  */
 @Before("allAddMethod()")
 public void checkSecurity() {
  //...
  //...
  System.out.println("进行安全检查!!");
 }
}

--------applicationContext-beans.xml

   <aop:aspectj-autoproxy/><!--  对AspectJ的支持-->
   
   <bean id="userManager" class="com.bjsxt.spring.UserManagerImpl"/>
   
   <bean id="mySecurityManager" class="com.bjsxt.spring.MySecurityManagerImpl"/>

----
***
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;

@Aspect
public class AroundExample {
 //Around通知可怜有参数
  @Around("com.xyz.myapp.SystemArchitecture.businessService()")
  public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
 // start stopwatch
 Object retVal = pjp.proceed();
 // stop stopwatch
 return retVal;
  }

}
***
对于切入点 就是 表达式

合并切入点表达式

@Pointcut("execution(public * *(..))")
 private void anyPublicOperation() {}

 @Pointcut("within(com.xyz.someapp.trading..*")
 private void inTrading() {}

 @Pointcut("anyPublicOperation() && inTrading()")
 private void tradingOperation() {}
***
下面给出一些常见切入点表达式的例子。

任意公共方法的执行:

execution(public * *(..))
任何一个以“set”开始的方法的执行:

execution(* set*(..))
AccountService 接口的任意方法的执行:

execution(* com.xyz.service.AccountService.*(..))
定义在service包里的任意方法的执行:

execution(* com.xyz.service.*.*(..))
定义在service包或者子包里的任意方法的执行:

execution(* com.xyz.service..*.*(..))
在service包里的任意连接点(在Spring AOP中只是方法执行) :

within(com.xyz.service.*)
在service包或者子包里的任意连接点(在Spring AOP中只是方法执行) :

within(com.xyz.service..*)
实现了 AccountService 接口的代理对象的任意连接点(在Spring AOP中只是方法执行) :

this(com.xyz.service.AccountService)
'this'在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得代理对象可以在通知体内访问到的部分。

实现了 AccountService 接口的目标对象的任意连接点(在Spring AOP中只是方法执行) :

target(com.xyz.service.AccountService)
'target'在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得目标对象可以在通知体内访问到的部分。

任何一个只接受一个参数,且在运行时传入的参数实现了 Serializable 接口的连接点 (在Spring AOP中只是方法执行)

args(java.io.Serializable)
'args'在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得方法参数可以在通知体内访问到的部分。

请注意在例子中给出的切入点不同于 execution(* *(java.io.Serializable)): args只有在动态运行时候传入参数是可序列化的

(Serializable)才匹配,而execution 在传入参数的签名声明的类型实现了 Serializable 接口时候匹配。

有一个 @Transactional 注解的目标对象中的任意连接点(在Spring AOP中只是方法执行)

@target(org.springframework.transaction.annotation.Transactional)
'@target' 也可以在binding form中使用:请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。

任何一个目标对象声明的类型有一个 @Transactional 注解的连接点(在Spring AOP中只是方法执行)

@within(org.springframework.transaction.annotation.Transactional)
'@within'也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分

任何一个执行的方法有一个 @Transactional annotation的连接点(在Spring AOP中只是方法执行)

@annotation(org.springframework.transaction.annotation.Transactional)
'@annotation' 也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的

部分。

任何一个接受一个参数,并且传入的参数在运行时的类型实现了 @Classified annotation的连接点(在Spring AOP中只是方法执行)

@args(com.xyz.security.Classified)
'@args'也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。

2,spring自身的xml文件配置方式

spring对AOP的支持(使用Spring的配置文件来演示)

将切面,切入点和通知定义在spring文件中:
 <aop:config>
  <aop:pointcut id="allAddMethod" expression="execution(* add*(..))"/>
  <aop:aspect id="securityAspect" ref="mySecurityManager">
   <aop:before pointcut-ref="allAddMethod" method="checkSecurity"/>
  </aop:aspect>  
 </aop:config>

 * 通过<aop:piontcut> 标签定义切入点
 * 通过<aop:aspect> 标签定义切面
 * 可以在<aop:aspect>内部定义通知对应的方法和对应的切入点

直接使用advisor
所引用的advisor要实现相应的接口或继承相应的父类

 <bean id="myAdvice" class="com.bjsxt.spring.MyAdvice"></bean>
 <aop:config>
  <aop:advisor pointcut="execution(* add*(..))" advice-ref="myAdvice"/>
 </aop:config>

拦截around通知:例
public class DebugInterceptor implements MethodInterceptor {

    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("Before: invocation=[" + invocation + "]");
        Object rval = invocation.proceed();
        return rval;
    }
}

before 通知:
public class CountingBeforeAdvice implements MethodBeforeAdvice {

    private int count;

    public void before(Method m, Object[] args, Object target) throws Throwable {
        ++count;
    }

    public int getCount() {
        return count;
    }
}
异常通知:
public class RemoteThrowsAdvice implements ThrowsAdvice {

    public void afterThrowing(RemoteException ex) throws Throwable {
        // Do something with remote exception
    }
}
后置通知:
public class CountingAfterReturningAdvice implements AfterReturningAdvice {

    private int count;

    public void afterReturning(Object returnValue, Method m, Object[] args, Object target)
            throws Throwable {
        ++count;
    }

    public int getCount() {
        return count;
    }
}
------------------------------------------------------
spring 事务管理 支持hibernate

SessionFactory.getCurrentSession与openSession的区别
    1. 如果使用的是getCurrentSession来创建session的话,在commit后,session就自动被关闭了,
         也就是不用再session.close()了。但是如果使用的是openSession方法创建的session的话,
         那么必须显示的关闭session,也就是调用session.close()方法。这样commit后,session并没有关闭
 2. getCurrentSession的使用可以参见hibernate/hibernate-3.2/doc/tutorial/src项目
 3.  使用SessionFactory.getCurrentSession()需要在hibernate.cfg.xml中如下配置:
  * 如果采用jdbc独立引用程序配置如下:
    <property name="hibernate.current_session_context_class">thread</property>
  * 如果采用了JTA事务配置如下 
    <property name="hibernate.current_session_context_class">jta</property>


在dao层可以使用spring 的 HibernateDaoSupport

public class LogManagerImpl extends HibernateDaoSupport  implements LogManager {

 public void addLog( Log log)  {
  this.getHibernateTemplate().save(log);
 }
}

也可不用spring中的包装类

public class LogManagerImpl extends  implements LogManager {
 private SessionFactory sessionFactory;
 public void setSessionFactory(SessionFactory sessionFactory)
 {this sessionFactory=sessionFactory;}
 public void addLog( Log log)  {
  session=sessionFacotry.getCurrentSession;
  session.save(log);
  
 }
}

spring配置式事务管理:


<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.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

 <!-- 配置sessionFactory -->
 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  <property name="configLocation">
   <value>classpath:hibernate.cfg.xml</value>
  </property>
 </bean> 
 
 <!-- 配置事务管理器 --> 
 <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  <property name="sessionFactory">
   <ref local="sessionFactory"/>
  </property>
 </bean>
   
    <!-- 配置事务特性 -->      
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
     <tx:attributes>
      <tx:method name="add*" propagation="REQUIRED"/>
      <tx:method name="*" read-only="true"/>
     </tx:attributes>
    </tx:advice>
   
    <!-- 配置那些类的方法进行事务管理 -->
    <aop:config>
     <aop:pointcut id="allManagerMethod" expression="execution (* com.bjsxt.usermgr.manager.*.*(..))"/>
     <aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod"/>
    </aop:config>
</beans>

* 默认回滚异常:RuntimeException   
  * 在编写业务逻辑方法的时候,最好将异常向上抛出,直到呈现层处理     
  * Spring的事务管理是配添加的业务逻辑方法上面,而不要添加到DAO上

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

Spring持久层的封装       通过xml实现DataSource数据源的注入有3种方式:  

1:使用spring自带的DriverManagerDataSource   

<beans>
 <bean id="dataSource"
  class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName">
   <value>com.mysql.jdbc.Driver</value>
  </property>
  <property name="url">
   <value>jdbc:mysql://localhost:3306/newdb</value>
  </property>
  <property name="username">
   <value>root</value>
  </property>
  <property name="password">
   <value>lxl</value>
  </property>
 </bean>
 <bean id="transactionManager"
  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource">
   <ref bean="dataSource" />
  </property>
 </bean>
 <bean id="helloDAO" class="HelloDAO">
  <property name="dataSource">
   <ref bean="dataSource" />
  </property>
 </bean><!-- 声明式事务处理-->
 <bean id="helloDAOProxy"
  class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
  <property name="transactionManager">
   <ref bean="transactionManager" />
  </property>
  <property name="target">
   <ref bean="helloDAO" />
  </property>
  <property name="transactionAttributes">
   <props><!-- 对create方法进行事务管理,PROPAGATION_REQUIRED表示如果没有事务就新建一个事务-->
    <prop key="create*">PROPAGATION_REQUIRED</prop>
   </props>
  </property>
 </bean>
</beans>

2:使用DBCP连接池      

<beans>
 <bean id="dataSource"
  class="org.apache.commons.dbcp.BasicDataSource"
  destroy-method="close">
  <property name="driverClassName">
   <value>com.mysql.jdbc.Driver</value>
  </property>
  <property name="url">
   <value>jdbc:mysql://localhost:3306/newdb</value>
  </property>
  <property name="username">
   <value>root</value>
  </property>
  <property name="password">
   <value>lxl</value>
  </property>
 </bean>
 <bean id="transactionManager"
  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource">
   <ref bean="dataSource" />
  </property>
 </bean>
 <bean id="helloDAO" class="HelloDAO">
  <property name="dataSource">
   <ref bean="dataSource" />
  </property>
 </bean><!-- 声明式事务处理-->
 <bean id="helloDAOProxy"
  class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
  <property name="transactionManager">
   <ref bean="transactionManager" />
  </property>
  <property name="target">
   <ref bean="helloDAO" />
  </property>
  <property name="transactionAttributes">
   <props><!-- 对create方法进行事务管理,PROPAGATION_REQUIRED表示如果没有事务就新建一个事务-->
    <prop key="create*">PROPAGATION_REQUIRED</prop>
   </props>
  </property>
 </bean>
</beans>

3:使用Tomcat提供的JNDI      

<beans>
 <bean id="dataSource"
  class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="driverClassName">
   <value>com.mysql.jdbc.Driver</value>
  </property>
  <property name="url">
   <value>jdbc:mysql://localhost:3306/newdb</value>
  </property>
  <property name="username">
   <value>root</value>
  </property>
  <property name="password">
   <value>lxl</value>
  </property>
 </bean>
 <bean id="transactionManager"
  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource">
   <ref bean="dataSource" />
  </property>
 </bean>
 <bean id="helloDAO" class="HelloDAO">
  <property name="dataSource">
   <ref bean="dataSource" />
  </property>
 </bean><!-- 声明式事务处理-->
 <bean id="helloDAOProxy"
  class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
  <property name="transactionManager">
   <ref bean="transactionManager" />
  </property>
  <property name="target">
   <ref bean="helloDAO" />
  </property>
  <property name="transactionAttributes">
   <props><!-- 对create方法进行事务管理,PROPAGATION_REQUIRED表示如果没有事务就新建一个事务-->
    <prop key="create*">PROPAGATION_REQUIRED</prop>
   </props>
  </property>
 </bean>
</beans>
-------------------------------------------------------
Spring 和Struts的整合使用 Spring 和 Struts的整合有3种方式:
1:通过Spring的ActionSupport类
2:通过Spring的DelegatingRequestProcessor类
3:通过Spring的DelegatingActionProxy类

a: 通过Spring的ActionSupport类:(对应工程:SpringStruts)
方法是Action类不再继承Struts的Action而是继承Spring提供的ActionSupport,
然后在Action中获得Spring的ApplicationContext.
缺点是Action和Spring耦合在一起,而且Action不在Spring控制之内。也不能处理多个动作在一个Action中的情况。 步骤:
1:加入spring.
2: 加入struts
3:修改struts配置文件struts-config.xml文件注册ContextLoaderPlugIn插件。
<plug-in
 className="org.springframework.web.struts.ContextLoaderPlugIn">
 <set-property property="contextConfigLocation"
  value="/WEB-INF/applicationContext.xml" />
</plug-in>
4:创建Action时:
(1) 处,我通过从 Spring 的 ActionSupport 类而不是 Struts 的 Action
类进行扩展,创建了一个新的 Action。
(2) 处,我使用 getWebApplicationContext() 方法获得一个
ApplicationContext。为了获得业务服务,我使用在
(3) 处 查找一个 Spring bean。 //(1) public
class LoginAction extends ActionSupport { public ActionForward execute(
ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) { LoginForm loginForm = (LoginForm) form;
// TODO Auto-generated method stub //(2) ApplicationContext ac =
this.getWebApplicationContext();//获得ApplicationContext //(3)
LoginInterface li =
(LoginInterface)ac.getBean("loginInterface");//获得Bean boolean you =
li.checkUser(loginForm.getName(),loginForm.getPassword()); if(you){
request.setAttribute("msg","welcome"); return
mapping.findForward("show"); } else{
request.setAttribute("msg","failed"); return
mapping.findForward("show"); } } } applicationContext.xml:
<beans>
 <bean id="loginInterface" class="spring.LoginImp" />
</beans>
b: 通过Spring的DelegatingRequestProcessor类:(对应工程:SpringStruts2)
方法是Spring的DelegatingRequestProcessor代替Struts的RequstProcessor,
把Struts的Action置于Spring的的控制之下
缺点是开发人员可以自己定义RequestProcessor这样就需要手工整合Struts和Spring。 步骤: 1:加入spring. 2:
加入struts 3:修改struts配置文件struts-config.xml文件注册ContextLoaderPlugIn插件。
<struts-config>
 <form-beans>
  <form-bean name="loginForm"
   type="com.yourcompany.struts.form.LoginForm" />
 </form-beans>
 <action-mappings>
  <action attribute="loginForm" input="/login.jsp"
   name="loginForm" path="/login" scope="request"
   type="com.yourcompany.struts.action.LogAction">
   <forward name="show" path="/show.jsp" />
  </action>
 </action-mappings>
 <controller
  processorClass="org.springframework.web.struts.DelegatingRequestProcessor">
 </controller>
 <message-resources
  parameter="com.yourcompany.struts.ApplicationResources" />
 <plug-in
  className="org.springframework.web.struts.ContextLoaderPlugIn">
  <set-property property="contextConfigLocation"
   value="/WEB-INF/applicationContext.xml" />
 </plug-in>
</struts-config>


4:创建Action时:     

 public class LogAction extends Action {      
 private LoginInterface logInterface;          
 public ActionForward execute(ActionMapping mapping,
    actionForm form,
    HttpServletRequest request,       
    HttpServletResponse response) {       
     LoginForm loginForm = (LoginForm) form;       
     // TODO
 }
    }
// Auto-generated method stub
 boolean you = logInterface.checkUser(loginForm.getName(),loginForm.getPassword());
 if(you){
 request.setAttribute("msg","welcome");
 return
 mapping.findForward("show");
 }
 else{
 request.setAttribute("msg","failed");
 return
 mapping.findForward("show");
 } }
 public
 void
 setLogInterface(LoginInterface
 logInterface)
 {
 this.logInterface
 =
 logInterface;
 } }