spring 学习基础笔记 包括spring 的代理 JDK CGLIB 事物 AOP 以及各种注入

来源:互联网 发布:多益网络招聘要求 编辑:程序博客网 时间:2024/05/21 11:36
1.建立第一个sprint项目(java project)
步骤:window-->preferences-->java-->user libraries-->new-->给要加的包命名-->add jars-->
1)、spring的依赖包
    *spring_home/dist/spring.jar
    *spring_home/lib/jakarta-commons/commons-logging.jar
    *soring_home/lob/log4j/jog4j-1.2.14.jar
2).拷贝spring配置文件到src下
3).拷贝log4j配置文件到src下
4).在UserManagerImpl中提供构造函数(或set方法),spring将实例化好的UserDao实现诸如给我们
5.让spring关联我们的对象创建和依赖,必须在sprin配置文件(applcationContext.xml)中进行定义,如果在配置文件中打印的时候没有提示,可以加上相应文件的配置提示,eg加入AOP的提示文件加入方法如下:
*******
window-->preferrnces-->MyEclipse-->Files and Editors-->XML Catalog-->User Specified Entries-->add-->Key Type(选择URI),Location(File System加入要制定的文件:我们这里加入的是:F:\书籍\王勇Spring\Spring相关资料\spring-framework-2.0\dist\resources\spring-aop-2.0.xsd)-->Key Type(Schema Location), 再把Location中刚刚加上的文件的名字加到Key那个字符串的后面,注意加的的时候要加上"/":/spring-aop-2.0.xsd
*******
6.编写客户端

spring Ioc容器的关键点:
*必须将被管理的对象定义到spring配置文件中
*必须定义构造函数或setter方法,让spring将对象注入过来。
*spring Ioc(inversion )容器是依赖注入(DI:dependency injection ),控制反转
-------------------------------------------------------------------------
2.spring的基本属性和自定义属性编辑器注入:
*注意使用junit测试类的时候可以使用它的setUp()方法进行初始化,如我们测试spring的时候,每个方法都要用到beanFactory。所以我们可以再setUp()方法中初始化beanFactory。
public  void serUp throws Exception{

    BeanFactory facotry=new ClassPathXmlApplicationContext("ApplicationContext.xml");//通过classpath方式读取spring的配置文件//ApplicationContext.xml,配置文件可以写多个,如果有多个配置文件,那么可以//通过数据在读取,或者把配置文件的名字都命名为ApplicationContext-xx.xml,那//么就可以通过BeanFactory facotry=new ClassPathXmlApplicationContext//("ApplicationContext-*.xml")就可以读取所有的配置文件了。
}
*普通属性(String,int,list,map,数组等)注入可以参考开发手册的3.3章节(核心技术/容器/依赖/依赖注入).
**************
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:aop="http://www.springframework.org/schema/aop"
         xmlns:tx="http://www.springframework.org/schema/tx"
         xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.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">
    <bean id="bean1" class="com.xiaojing.spring.Bean1">
    <!-- int注入 -->
        <property name="intvalue" value="1000"/>
        <!--string注入  -->
        <property name="stringvalue" value="lily"/>
        <!-- list注入 -->
        <property name="listvalue" >
            <list>
                <value>ab</value>
                <value >cd</value>
                <ref bean="bean2"/><!-- list集合中放有bean2对象,引用 -->
                <value>ef</value>
                <value>gh</value>
            </list>
        </property>
        <!-- map注入 -->
        <property name="mapvalue">
            <map>
                <entry><!-- map容器中放有bean2对象,引用 -->
                    <key><value>k1</value></key>
                    <ref bean="bean2"/>
                </entry>
                <entry key="k2" value="I love you">
                </entry>
                <entry>
                    <key><value>k3</value></key>
                    <value>520</value>
                </entry>
            </map>
        </property>
        <!--  数组注入-->
        <property name="arrayvalue">
            <list>
                <value>array1</value>
                <value>array2</value>
                <value>1233</value>
            </list>
        </property>
        <!--set注入  -->
        <property name="setvalue">
            <set>
                <value>set1</value>
                <ref bean="bean2"/><!-- set容器中放有bean2对象,引用 -->
                <value>set3</value>
            </set>
        </property>
    </bean>
    <bean id="bean2" class="com.xiaojing.spring.Bean2">
        <property name="id">
            <value>10010</value>
        </property>
        <property name="name" value="lucy"/>
    </bean>
</beans>


**************
*什么是属性编辑器,作用?
 1).自定义属性编辑器,spring配置文件中的字符串转换成相应的对象进行注入,spring已经有内置的属性编辑器,我们可以根据自己的需求定义属性编辑器,
 2).如何定义属性编辑器?
    a.继承属性编辑器类java.beans.PropertyEditorSupport,覆写setAsText()方法
    b.将属性编辑器注册到org.springframework.beans.factory.config.customerEditorConfig类中的customEditors域成员的map中。

 eg:日期要写属性编辑器才可以注入,属性编辑器类要继承属性编辑器支持类(java.beans.PropertyEditorSupport),并且覆写他的setAsText(String text)方法,并在该方法中通过this调用setValue()方法把转换后的值传进去:this.setValue(date),其中date为转换后的日期,text为配置文件中传入的日期字符串。然后在配置文件中将该类注入到org.springframework.beans.factory.config.customerEditorConfig类中的域成员customerEditors的map中,
--------
//自己的属性编辑器把字符串转换为Date类型:
package com.xiaojing.spring;

import java.beans.PropertyEditorSupport;
import java.util.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
public class UtilDataPropertyEditorsup extends PropertyEditorSupport {
private String format;
//写上set方法并在配置文件中配置该类的bean的时候加上<property name="formt" value="yyyy-mm-dd"/>那么下面转换的方法就不用写上format= "yyyy-mm-dd";了
public void setFormat(String format) {
    this.format = format;
}
    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        //这里是没有在配置文件中配置format属性的值,如果配置了就不用在 写format了
    //    format= "yyyy-mm-dd";
        System.out.println("text="+text);
        try {
            //将配置文件中的时间字符串转换为时间类型,这里的text其实就是配置文件中传入的字符串
        SimpleDateFormat sdf=new SimpleDateFormat(format);
        Date d=sdf.parse(text);
            this.setValue(d);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    

}

--------
<bean id="CustomEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
        <property name="customEditors">
            <map>
                <entry>
                    <key><value>java.util.Date</value></key><!-- 将字符串转换为date类型 -->
                    <!-- 引用com.xiaojing.spring.UtilDataPropertyEditorsup类作为该key所对应的value的值
                    <ref bean="udpe"/>
                    -->
                    <!-- 把自己写的属性编辑器类作为他的内部bean,因为就只有该bean引用它(com.xiaojing.spring.UtilDataPropertyEditorsup) -->
                
                    <bean class="com.xiaojing.spring.UtilDataPropertyEditorsup">    
                        <property name="format" value="yyyy/mm/dd"></property>
                    </bean>
                    
                </entry>
            </map>
        </property>
    </bean>
    <!--  可以把该bean作为内部bean放到CustomEditorConfigurer所对应的bean中
    <bean id="udpe" class="com.xiaojing.spring.UtilDataPropertyEditorsup">    
                        <property name="format" value="yyyy/mm/dd"></property>
    </bean>
    -->

<bean id="bean3" class="com.xiaojing.spring.Bean3HasData">
        <property name="id" value="1"/>
        <property name="name" value="小静"/>
        <property name="createdate" value="2008/02/02"/><!-- 这里的日期要用到属性编辑器把string转换为date类型 -->
    </bean>
--------
Bean3HasData:
int id;
String name;
Date createdate;
-------------------------------------------------------------------------
3.依赖注入的方式,可以采用:
*ref属性
*<ref>标签
*内部<bean>
-------------------------------------------------------------------------
4.如何建公共的属性定义描述出来:
a.通过<bean>标签定义公共的属性,并且指定属性abstract="true";
b.具有相同属性的类的<bean>标签中指定其parent="上面定义的公共属性中bean标签中的id属性"
eg:如有类:
Bean1:int id;Bean2 bean2;Bean3 bean3;Bean4 bean4;(也就是bean234都是bean1的域成员)
Bean2:int id;String name;String password;
Bean3:int id;String name;
bean4:int age;
类Bean2和Bean3有相同的属性id和name,并且id的值都为1000,name为jack,如果值不同的话,也可以再自己的类Bean2和Bean3中重新abbstract="true"那个bean中的property的value值
那么在配置文件中可以这样写:
---
<beans>
    <bean id="bean1" class="com.xiaojing.spring.Bean1">
        <property name="id" value="1000000"/>
【注意name属性里面是Bean1类中的域成员,ref写引用的那个类对应配置文件中<bean>标签的id,】
        <property name="bean2" ref="b2"/>
        <property name="bean3">
            <ref bean="b3">
        </property>
        <property name="bean4" ref="b4"/>
    </bean>
    <bean id="commonbean" abstract="true">
        <property name="id" value="1000"/>
        <property name="name" value="jack">
    </bean>
【加入bean2中的name域成员的值不为jack而是lucy那么我们就要重写该成员的值
  即在里面加上<property name="name" value="lucy"/>
 】
    <bean id="b2" parent="commonbean"                             class="com.xiaojing.spring.Bean2">
        <property name="password" value="123"/>
        <property name="name" value="lucy"/>
    </bean>
    
    <bean id="b3" parent="commonbean"                         class="com.xiaojing.spring.Bean3">
    </bean>
    <bean id="b4" class="com.xiaojing.spring.Bean4">
        <property name="age" value="45"/>
    </bean>
</beans>
---
--------------------------------------------------------------------------
5.spring的bean的作用域:
scope可以取值:
 *singleton:每次调用getBean的时候返回相同的实例,默认的是singleton;
 *prototype:每次调用getBean的 时候返回不同的实例,线程安全;

<bean id="bean1" class="com.xiaojing.spring.Bean1" scope="singleton">
-------------------------------------------------------------------------
6.spring根据名称自动装配:有两种,一种是根据名称AutoWirebyName,另一种是根据类型AutoWirebyType,注意使用他们的时候都要在<beans>标签中配置defautl-autowire=""属性;如<beans default-autowire="buType(根据类型自动装配)/byName(根据姓名自动装配)">
--------------------------------------------------------------------------
7.代理模式:
静态代理:
1)写的代理类必须和被代理的类(也就是目标对象)实现同样的接口;要控制目标对象就必须具有目标对象的引用。
动态代理:
2)AOP的默认实现采用JDK的动态代理机制来实现的,把横切性的关注点单独拿出来,把散步在程序各个角落的东西拿出来模块化,模块化,模块化好处:模块化后就可以只单独维护模块就可以了
3)、动态代理类必须实现java.lang.reflect.InvocationHandler接口;
-----------
public class SecurityHandler implements InvocationHandler {
    //定义目标对象,因为目标对象不知道具体是哪一个所以就用他们的父类object;
    private Object targetObject;
    //创建目标对象,创建代理类
    public Object newProxy(Object targetObject){
        //给目标对象赋值
        this.targetObject=targetObject;
        /*返回代理对象:第一个参数定义代理类的类加载器,得到目标对象的ClassLoader;
         * 第二个参数为代理类要实现的接口列表:getInterfaces,第三个参数为指派方法调用的调用处理程序
         *实现了InvocationHandler接口的类,我们这里就是他本身
         */
        return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(), this);
    }
    //实现了代理类的实例在调用方法时会调用该方法:在代理实例上处理方法调用并返回结果.所以我们可以在invoke()方法中调用像安全检查之类的方法。
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        //在真正调用目标对象方法前调用检查方法:
        this.securityCheck();
    //由于目标对象的有些方法有返回值eg:findUser(),有的没有放回值eg:addUser();所以我们统一个返回值
        Object result=null;
        //有可能出现异常:
        try{
            //目标对象的实现
            //proxy - 从中调用基础方法的对象,目标对象
            //args - 用于方法调用的参数
            result=method.invoke(this.targetObject, args);
        }catch(Exception e){
            e.printStackTrace();
            throw new java.lang.RuntimeException(e);//继续将异常向上抛
        }
        return result;
    }
    //检查安全的方法
    private void securityCheck(){
        System.out.println("这是安全检查方法");
    }
}
-----------
4)AOP:
a.横切性关注点(Cross cutting concern)是AOP的术语,模块化的那个类就是切面(Aspect)类,该类中的具体实现如安全检查方法在Aop术语中交advice(横切性关注点的实现),有多种advice,有在目标对象的方法执行之前执行该具体实现advice如先执行安全检查在执行目标对象的添加add()方法(Before advice),方法执行之后(after advice)等;过滤条件也就是什么时候用到那个目标对象上,用到目标对象上的哪个方法等在AOP术语中交切入点(Pointcut(add*)所以add*的方法都用到该到该横切面);把切面应用到目标对象(target object)的过程在AOP的术语是织入weave,连接点(在Spring中就是目标对象的方法)在AOP中叫joinpoint;代理对象在AOP中叫Proxy object;introduction可以动态的加方法。
b.spring AOP的实现:Spring的切入点模型使得切入点可以独立于通知类型进行重用,这就使得针对不同 advice使用相同的pointcut成为可能
I、采用注解的方式(采用Annotation的方式):
*加上jar包:
spring的依赖包
    *spring_home/dist/spring.jar
    *spring_home/lib/jakarta-commons/commons-logging.jar
    *spring_home/lib/log4j/jog4j-1.2.14.jar
    *spring_home/lib/aspectj/*.jar(这个是SPRING的Aop的jar包)
*、指定切面aspect:
在类的上面写上:@Aspect
-------------
*写上标识:
private void alladdMethod(){};//定义Poingtcut,Poingcut的名称就是alladdMethod,此方法不能有返回值和参数,该方法只是一个标识,我们不会执行。

-------------
*定义Pointcut,Ponintcut的内容是一个表达式,描述哪些对象的哪些方法(订阅joinpoint),在切面类中写上一个标识方法private void alladdMethod(){};,在标识方法上写:@Poincut("execution(* add*(..))")//该句话的意思是定义pointcut,第一个*标识不管是有返回值的还是没有返回值的都行,add*表示只要是以add开头的方法,..表示不管是有参数还是没有参数的都可以。
------------
*定义Advice:标识在哪个切入点Pointcut何处织入advice,在具体的方法(advice方法)上定义:
@Before(alladdMethod());//表示在目标对象的方法(Joinpoint)执行前执行advice.
private void checkSecutrity(){//具体的方法advice;
        System.out.println("这是我们安全检测的方法advice");
}
-----------
*在配置文件中applicationContext.xml中配置:
首先加入标签指明使用注解(Annotation)方式:
<aop:aspectj-autoproxy/>
将Aspect类和目标对象配置到IOC容器(applicationContext.xml)中:
//这是aspect类
<bean id="securityHandler" class="com.xioajing.spring.SecurityHandler"/>
//这是目标对象
<bean id="userManager" class="com.xiaojing.spring.UserManagerImp"/>

----------
注意:在这种方法定义中,切入点的方法是不被执行的,它存在的目的仅仅是为了重用切入点。即:Adcice中通过切入点的方法名引用切入点。

--------------------------------------------
II.spring AOP的实现采用(静态文件方式)配置文件的方式:
在IOC容器中(applicationContex.xml文件中配置):
-----
//这是aspect类
<bean id="securityHandler" class="com.xioajing.spring.SecurityHandler"/>
//这是目标对象
<bean id="userManager" class="com.xiaojing.spring.UserManagerImp"/>

<aop:config>
    <aop:aspect id="security" ref="securityHandler">
        <aop:pointcut id="alladdMethod" expression="exectuion(*                     com.xiaojing.spring.UserManagerImpl.*)"/>
        <aop:before method="checkSecurity"
                 pointcut-ref="alladdMethod"/>
    </aop:aspect>
</aop:config>
-----
上面expression="execution(* com.xiaojing.spring.UserManagerImpl.*(..))"//表示advice应用到com.xiaojing.spring.UserManagerImpl类里的所有方法;
expression="execution(* com.xiaojing.spring.UserManagerImpl.add*(..))"//表示advice应用到com.xiaojing.spring.UserManagerImpl类里的所有以add开头的方法;expression="execution(* com.xiaojing.spring.UserManagerImpl.add*(..) || execution(* com.xiaojing.spring.UserManagerImpl.delete*(..))"//表示表示advice应用到com.xiaojing.spring.UserManagerImpl类里的所有以add和delete开头的方法.
<aop:aspect id="security" ref="securityHandler">,ref中的值是aspect类所对应<bean>标签的id的值,<aop:pointcut id="alladdMethod" ,pointcut中的id的值是写的一个标识,自己写的;<aop:before method="checkSecurity" pointcut-ref="alladdMethod"/>,before表示在joinpoint之前执行checkSecurity(advice)方法,checkSecurity是在Aspect类中的具体实现的方法,pointcut-ref中的值是<aop:pointcut>中id的值,表示执行哪个Pointcut。
--------------------------------------------
III、spring 对AOP的支持:
*Aspect 默认情况下不用实现接口,但对应目标对象(UserMangerImpl.java)在默认情况下必须实现接口,如果没有实现必须引入CGLib库,如果没有引入CGLIB库那么就会报错AopConfigException。
*我们可以通过在Advice方法中添加一个JointPoint参数,目标对象的信息会由spring自动传入,从JoinPoint中可以取得目标对象方法(joinpoint)的参数值、方法名等待。JoinPoint 的实例jp.getArgs()得到的是Object[]对象数组,该数组中放的是目标的对象中调用方法的参数;jp.getSignature().getName();得到被调用方法的名称。

-------------------------------------------------------------------------
8.JDK的动态代理和CGLib:
1).如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP;
2)如果目标对象实现了接口,可以强制使用CGLIB实现AOP:
a.如何强制使用CGLIB实现AOP?:
 *添加CGLIB库:spring_home/cglib/*.jar.
 *在spring配置文件(applicationContext.xml)中加入:
<aop:aspectj-autoproxy proxy-target-class="true"/>

3)、如果目标对象没有实现接口,必须使用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换。

总结:JDK动态代理和CGLIB字节码生成的区别:
 *JDK动态代理只能对实现了接口的类生成代理,而不能针对类;
 *CGLIB是针对类实现代理,主要是对指定的类生成一个子类作为代理,覆盖其中的    方法, 因为是继承,所以该类或方法最好不要声明成final

-------------------------------------------------------------------------9.hibernate和spring的集成:完成声明式事务的配置:
1).getCurrentSession()与openSession()得到的session的区别?
 *采用getCurrentSession()创建的session会绑定到当前的线程中,而采用openSession()创建的session则不会;
 *采用getCurrentSession()创建的session在提交(commmit)或者回滚(rollback)的时候自动关闭,而采用openSession()创建的session则必须手动关闭;
2)、使用getCurrentSession()需要在hibernate.cfg.xml文件中加入如下配置:
a.如果使用的是本地事务(JDBC事务,就是只有一个数据库等),加入如下:
<property name="hibenrante.current_session_context_class">thread</property>
b.如果使用的是全局事务(jta事务,就是不只有一个数据库或许有几个数据库,或者有其它的一些可以回滚事务的资源等),加入如下:
<property name="hibenrante.current_session_context_class">jta</property>
3).事务的传播特性,隔离级别:
4).hibernate和spring的集成:

配置:
在spring的配置文件中applicationContext.xml文件中配置:
a、配置sessionFactory,把配置文件hibernate.cfg.xml注入到LocalSessionFactory类中的configLocation属性中:
-----
<bean id="sessionFactory"     class="org.springframework.orm.hibernate3.LocalSessionFactory">
  <property name="configLocation">
    <value>classpath:hibernante.cfg.xml</value>
  </property>
</bean>
-----
上面代码中<bean>中的id是我们自己起的名字,但是一般都叫sessionFactory;
<property name="configLocation">中的configLocation是org.springframework.orm.hibernate3.LocalSessionFactory类的域成员;<value>采用classpath:协议注入,hibernante.cfg.xml是hibenrante的配置文件名称;
********************
b、配置事务管理器,把sessionFactory注入到HibernateTransactionManager类中的SessionFacotory属性中,让他管理sessionFactory:
----
<bean id="transactionmanager" class="org.springframeword.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" >
        <ref bean="sessionFactory"/>
    </property>
</bena>
----
上面代码中,id="transactionmanager" :id的值是自己起的名字,property中name属性的值是HibernateTransactionManager类的域成员,<ref>标签中bean的值是自己配置的sessionFactory中<bean>标签id的值。
*******************

c、配制事务传播特性;
----
<tx:advice id="txadvice" transaction-manager="tanasactionmanager">
    <tx:attributes>
        <tx:method name="add*" propagation="REQUIRED"/>
        <tx:method name="delete*" propagation="REQUIRED"/>
        <tx:method name="modify*" propagation="REQUIRED"/>
        <tx:method name="*" read-only="ture"/>
    </tx:attributes>
</tx:advice>
----
上面代码中,<tc:advice>标签中的id中的值是自己起的名字,transaction-manager中的值是自己配置的事物管理器<bean>标签中id的值,<tx:method name="add*/modify*/delete*" propagation="REQUIRED"/><tx:method name="*" read-only="ture"/>的意思分别是以add或者modify或者delete开头的方法的事物传
播特性是required,其余的方法都是只读。
****************************

d.哪些类哪些方法参与事务,即:配置aspect;
------
<aop:config>
    <aop:pointcut name="allmanagermethod"  expression="execution(*    com.xiaojing.mamager.*(..))"/>
    <aop:advisor pointcut-ref="allmanagermethod" advice-ref="txadvice"/>
</aop:config>
------
上面代码中<aop:pointcut>标签中name的值是自己给pointcut起的名字,expression中的以上是com.xiaojing.mamager包中所有类的所有方法都是用事物。<aop:abvisor>相当于<aop:aspect>标签,这里的<adisor>标签是spring特定的,里面pointcut-ref的值是<aop:pointcut>中name的值,advic-ref的值是事物传播特性中<tx:advice>中id的值。
*******************************

e.那些要使用到SessionFacory或this.getHibernateTemplate()(用spring的话可以用他的this.getHibernateTemplate()获得sessionFactory)的类在spring的配置文件中都要把SessionFactory注入进去。即:
<property name="sessionFactory" ref="sessionFactory"/>,并且该类要继承HibernateDaoSupport类,这里id中的sessionFactory是HibernateDaoSupport类的域成员,ref中的sessionFactory是自己配置sessionFactory的<baen>标签中id属性的值。
f.编写业务逻辑方法:
*那么这些具有该方法的类必须继承HibernateDaoSupport类,使用HibernateTemplate是Hibernate Session的轻量级封装
*默认情况下运行期异常(RunTimeException)才会回滚,包括继承了RunTimeException的子类也回滚,普通异常默认情况下是不回滚的。
*编写业务逻辑方法是,最好将异常一直向上抛,在表示层(struts那块)做处理;
*关于事务边界的设置(比如表示层要访问的地方),通常设置到业务层,不要添加到DAO上。
--------
注意通过spring管理SessionFactory,回滚事务默认是回滚运行期异常,也就是runTimeException。

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

10.AOP的总结:AOP关注横切性的关注点,我们使用AOP主要是完成声明式事物,注意他里面的术语:Cross cutting concern,Aspect,Advice,Pointcut,Joinpoint(注意在spring只支持方法级的Joinpoint),Weave(织入:advice应用到Joinpoint的过程),Target Object,Proxy,Introduction
-------------------------------------------------------------------------11、spring+struts的集成(第一种集成方案)
原理:在Action中取得BeanFactory对象,然后通过BeanFactory获得业务逻辑对象;

步骤:
1).spring和struts依赖库配置:
 *配置struts
  --拷贝struts类库和jstl类库
  --修改web.xml文件来配置ActionServlet
  --提供struts-config.xml文件
  --提供国际化资源文件
 *配置spring
  --拷贝spring类库
  --提供spring配置文件applicationContext.xml;

2).在struts的Action中调用如下代码取得BeanFactory
创建文件
SessionFactory factory=webapplicationContextUtils.getRequiredApplicationContext(required.getSession.getContext);

3).通过beanFactory取得业务对象,调用业务逻辑方法。
--------------------------------------------------------------------------
12、spring+struts的集成(第二种集成方案)
原理:将业务逻辑对象通过spring注入到Action中,从而避免在Aciton类中直接代码查找;

步骤:
1).spring和struts依赖库配置:
 *配置struts
  --拷贝struts类库和jstl类库
  --修改web.xml文件来配置ActionServlet
  --提供struts-config.xml文件
  --提供国际化资源文件
 *配置spring
  --拷贝spring类库
  --提供spring配置文件applicationContext.xml;
2).
*因为action需要调用业务逻辑方法,所以需要在aciton中提供setter方法,让       spring把业务逻辑对象注入过来。
*在struts-config.xml文件中配置action:
<action>标签中的type属性需要修改为spring提供的action的代理,代理的action:
DelegatingActionProxy是一个代理的action,主要作用是取得BeanFactory,然后根据<action>标签中path属性值到IoC容器中取得本次请求对应的Action;
*在spring配置文件中需要定义struts的Action,如:
------
<bean name="/login" class="com.xiaojing.usermagr.actions.LoginAction" scope="prototype">
    <property name="userManager" ref="userManager"/>
</bean>
-------
上面代码中【注意】:
*<bean>标签中使用一定使用name属性,并且name属性的值要和sturts-config.xml文件中<action>标签中的path属性值一模一样。
*、必须注入业务逻辑对象,eg:ref="userManager",这里<property>标签中name属性的值是LoginAction类的域成员,ref属性的值是UserManagerImpl类对应<bean>标签中id的值。。
*建议将scope设置为Prototype,这样就避免了struts Action的线程安全问题。不在是单实例,而是每次过来创建一个实例。
-------------------------------------------------------------------------13.struts-spring-hibernate集成:
*在配置sessionfactory的时候:<!-- 配置sessionFactory,如果hibernate.cfg.xml是放在src写,那么就采用classpath:hibernate.cfg.xml的形式初始化配置文件,如果放在web-inf下就采用下面的方式 -->
-----------
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="configLocation" >
            <value>
              /WEB-INF/hibernate.cfg.xml
            </value>
        </property>
    </bean>
-----------

*不要忘记加载数据库的jar包
步骤:
先加人jar包,(这里采用的是手动:Spring(spring.jar,log4j.jarjakarta-commons/commons-logging.jar)--hibernante(hibernate3.jar,lib/*.jar,数据库驱动)--sturts(sturs的所有jar包)--数据库驱动的jar包(如果hibernate没有加的话));
【hiberante】关联的原码和配置文件分别是:hibernate-3.2.0.ga.zip;hibernante.cfg.xml;
【spring】关联的原码是:F:\书籍\王勇Spring\Spring相关资料\spring-framework-2.0\dist\spring-src.zip;applicationContext.xml;(注意spring关联的只能是springjar包中的spring文件才可以)
【struts】关联的原码是:F:\书籍\王勇struts\JSTL_BeanUtils_Struts相关资料\struts_install\struts-1.2.9-src.zip,struts-cfg.xml;
-------------------------------------------------------------------------14.spring的总结:Ioc就相当于工厂,我们可以通过Ioc拿到对象,叫控制反转。IoC有两种实现方式:依赖查找和依赖注入。Spring实现是依赖注入。
--------------------------------------------------------------------------
15.oracle数据库的driver:Class.forName("oracle.jdbc.driver.OracleDriver");
   oracle数据库的URL:String url="jdbc:oracle:thin:@localhost:1521:orcl";//其中1521是oracle的端口号,orcl是连接的数据库名(如我自己建立的oracle数据库的名字是orcl)
oracle数据库要加的jar包是ojdbc14.jar(有两个)
-------------------------------------------
16.spring的配置文件applicationContext.xml文件中: <ref bean="mybean"/>和
<ref   local="mybean"/>  的区别:
    有多个spring的配置文件,mybean不在当前xml中用<ref   bean="mybean"/>   

 mybean在当前xml中用<ref   local="mybean"/> 


这些都是我学习spring的时候随笔写下的一些笔记,现在共享出来,希望能对学习spring的朋友有一些帮助。有需要可以QQ找我 1336051675