Spring总结

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和non-singleton singleton:只有一个共享的实例存在 non-singleton:每次请求都创建新的实例

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">

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

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> </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有益的补充,不是对立面。 AOP的3个关键概念: 1:切入点:(PiontCut) 连接点(Jion piont):是指程序运行中的某个阶段,如方法的调用、异常的抛出等。 PiontCu就是Jion piont点的集合,它是程序中需要注入

的Advice的集合。指明Advice 在什么 条件下才被触发。 2:通知(Advice): 某个连接点采用的处理逻辑,也就是向连接点注入的代码。 3:Advisor 是PiontCut和Advice的配置器,它包含PiontCut和Advice,是把Advice注入到PiontCut位置的代码。 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> ------------------------------------------------------- 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 ="mons.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"></con

troller> <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; } }

applicationContext.xml: <beans> <bean id="loginInterface" class="spring.LoginImp"/> <!--要和Struts的路径对应--> <bean name="/login" class="com.yourcompany.struts.action.LogAction"> <property name="logInterface"> <ref bean="loginInterface"/> </property> </bean> </beans> c: 通过Spring

的DelegatingActionProxy类:(对应工程:SpringStruts3) 方法是Spring的

DelegatingActionProxy代替Struts的Action, 把Struts的Action置于Spring的的控

制之下 这种方式最灵活强大。并且它可以利用 Spring AOP 特性的优点。 步骤: 1:加入spring. 2: 加入struts 3:修改struts配置文件struts-config.xml文件注册

ContextLoaderPlugIn插件。 <struts-config> <data-sources /> <form-beans > <form-bean name="loginForm"

type="com.yourcompany.struts.form.LoginForm" /> </form-beans> <action-mappings > <action attribute="loginForm" input="/form/login.jsp" name="loginForm" path="/login" scope="request"

type="org.springframework.web.struts.DelegatingActionProxy"> <forward

name="show" path="/show.jsp" /> </action> </action-mappings> <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; } }

applicationContext.xml: <beans> <bean id="loginInterface"

class="spring.LoginImp"/> <!--要和Struts的路径对应--> <bean name="/login"

class="com.yourcompany.struts.action.LogAction"> <property name="logInterface">

<ref bean="loginInterface"/> </property> </bean> </beans> 拦截

Struts 通过将 Struts 动作委托给 Spring 框架而整合 Struts 和 Spring

的一个主要的优点是:您可以将 Spring 的 AOP 拦截器应用于您的 Struts

动作。通过将 Spring 拦截器应用于 Struts 动作,您可以用最小的代价处理

横切关注点。 虽然 Spring 提供很多内置拦截器,但是我将向您展示如何创

建自己的拦截器并把它应用于一个 Struts 动作。为了使用拦截器,您需要做

三件事: 1: 创建拦截器。

2:注册拦截器。

3:声明在何处拦截代码。 这看起来非常简单的几句话却非

常强大。例如,在清单 7 中,我为 Struts 动作创建了一个日志记录拦截器。 这个拦截器在每个方法调用之前打印一句话: 清单 7. 一个简单的日志记录

拦截器 public class LoggingInterceptor implements

MethodBeforeAdvice { public void before(Method method, Object[]

objects, Object o) throws Throwable

{ System.out.println("logging

before!"); } }

这个拦截器非常简单。before() 方法在拦截点中每个方法之

前运行。在本例中,它打印出一句话,其实它可以做您想做的任何事。下一步就是在 Spring 配置文件中注册这个拦截器,如清单 8 所示: 清单 8. 在 Spring 配置文件

中注册拦截器 <beans> <bean id="bookService"

class="ca.nexcel.books.business.BookServiceImpl"/> <bean

name="/searchSubmit" class="ca.nexcel.books.actions.SearchSubmit"> <property name="bookService"> <ref bean="bookService"/> </property> </bean> <!-- Interceptors --> <bean

name="logger" class="ca.nexcel.books.interceptors.LoggingInterceptor"/> |(1) <!-- AutoProxies --> <bean name="loggingAutoProxy"

class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">

|(2) <property name="beanNames"> <value>/searchSubmit</value>

|(3) </property> <property name="interceptorNames"> <list> <value>logger</value> |(4) </list> </property> </bean> </beans>

您可能已经注意到了,清单 8 扩展了 清单 6 中所示的应用程序以包含一个

拦截器。具体细节如下: 在 (1) 处,我注册了这个拦截器。

在 (2) 处,我创建了一个 bean 名称自动代理,它描述如何应用拦截器。

还有其他的方法定义拦截点,但是这种方法常见而简便。

在 (3) 处,我将 Struts 动作注册为将被拦截的 bean。如果您想要拦截

其他的 Struts 动作,则只需要在 "beanNames" 下面创建附加的 <value>

标记。

在 (4) 处,当拦截发生时,我执行了在 (1) 处创建的拦截器 bean 的名称。这里列出的所有拦截器都应用于“beanNames”。 就是这样。就像这

个例子所展示的,将您的 Struts 动作置于 Spring 框架的控制之下,为处理您的 Struts 应用程序提供了一系列全新的选择。在本例中,使用动作委托可以轻松地利用 Spring 拦截

器提高 Struts 应用程序中的日志记录能力。 --------------------------------------------------------------------------------

--------------- Struts + Spring + Hibernate

的整合使用 开发工

具:Eclipse3.1,MyEclipse4.0 ,Tomcat5.0.28,mysql-4.0.18 开发步骤: 1:创建web projectSSHlogin 加入struts1.2 创建loginForm

选择DynaValidatorForm,加入password,username,创建jsp文件打上钩,将路径改为

/login.jsp,然后下一步,改LoginAction的Input source改为/login.jsp,加入 <forward

name="ok" path="ok.jsp" />点击完成 完成后修改

struts-config.xml文件加入 <plug-in

className="org.apache.struts.validator.ValidatorPlugIn"> <set-property

property="pathnames"

value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml" /> </plug-in>

拷贝validator-rules.xml和validation.xml到WEB-INF目录中 在validation.xml文件

中加入 <form-validation> <formset> <form name="loginForm"> <field property="username" depends="required"> <arg0 key="prompt.username"

/> </field> <field property="password" depends="required"> <arg0 key="prompt.password" /> </field> </form> </formset>

</form-validation> validator-rules.xml文件直接考一个就行。 编辑资源文件

“ApplicationResources.properties” 增加以下内容 prompt.username=User Name

prompt.password=User Password errors.required={0} is required. 修改LoginAction.java文件的execute方法,内容如下 public ActionForward

execute( ActionMapping mapping, ActionForm form, HttpServletRequest

request, HttpServletResponse response) { DynaValidatorForm loginForm =

(DynaValidatorForm) form; String username=loginForm.getString("username");

String password=loginForm.getString("password");

if(username.equals("test")||password.equals("test")){ return

mapping.findForward("indexGo"); }else{ return

mapping.getInputForward(); } } 好了,现在可以启动Tomcat进行测试了如果不

输入任何数据而直接提交表单的话就可以看到效果了。 好了,如果没有什么问题的话就继

续往下看吧,如果有问题的话就得往上看了^_^ 2:加入Spring框架 在这里我将Spring

所有的包全部加载进去,因为我还不知道具体用到哪些类,全部加进去方便点 单选框选

第二个,这样的话所有的类库和标签等都将拷贝到项目中去,这样方便以后的布署 下一步

后是创建配置文件,将文件放到“WebRoot/WEB-INF”目录下,文件名称为

“applicationContext.xml” 配置struts-config.xml文件,添加(spring)的插

件 <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"> <set-property property="contextConfigLocation"

value="/WEB-INF/applicationContext.xml" /> </plug-in> 修改

LoginAction配置 原: <action attribute="loginForm" input="/login.jsp" name="loginForm" path="/login" scope="request" validate="true" type="com.test.struts.action.LoginAction" > <forward name="ok" path="ok.jsp"

/> </action> </action-mappings> 改为: <action attribute="loginForm" input="/login.jsp" name="loginForm" path="/login" scope="request" validate="true" type="org.springframework.web.struts.DelegatingActionProxy"> <forward

name="ok" path="ok.jsp" /> </action> </action-mappings> 这里将使

用spring的代理器来对Action进行控制 当提交到/login.do是将控制权交给了

spring,然后由spring来决定是否转回到struts的Action 现在来配置spring

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD

BEAN//EN" "/dtd/spring-beans.dtd"> <beans>

<bean name="/login" class="com.test.struts.action.LoginAction"

singleton="false"></bean> </beans> 好了,现在可以启动Tomcat进行测

试了如果没有什么问题的话就继续往下看吧,如果有问题的话就得往上看了^_^ 3:

创建Hibernate框架 建立数据库在 这里我使用的是

mysql4.1.18 CREATE TABLE `user` ( `ID` int(11) NOT NULL auto_increment,

`USERNAME` varchar(50) NOT NULL default '', `PASSWORD` varchar(50) NOT NULL

default '', PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1;

添加记录 insert into user (USERNAME,PASSWORD) values ('test','test') 在配置界面中配置数据库的连接部份,重要的是点击链接将jdbc驱动拷贝到lib目录中 使

用MyEclipse的数据Database Explorer工具创建User.hmb.xml、AbstractUser.java、

User.java映射文件 创建UserDAO.java、UserDAOImp.java

UserDAO.java: public interface UserDAO { public abstract boolean

isValidUser(String username, String password); } UserDAOImp.java:

import java.util.List; import

org.springframework.orm.hibernate3.support.HibernateDaoSupport; public

class UserDAOImp extends HibernateDaoSupport implements UserDAO { private

static String hql = "from User u where u.username=? and password=?"; public

boolean isValidUser(String username, String password) { String[]

userlist=new String[2]; userlist[0]=username; userlist[1]=password; List userList = this.getHibernateTemplate().find(hql,userlist); if

(userList.size() > 0) { return true; } return

false; } }

</property> <property name="transactionAttributes"> <props> <prop key="insert*">PROPAGATION_REQUIRED</prop> <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="is*">PROPAGATION_REQUIRED,readOnly</prop> </props> </property> </bean> <bean name="/login" class="com.test.struts.action.LoginAction" singleton="false"> <property name="userDAO"> <ref bean="userDAOProxy" /> </property> </bean> </beans> 现在可以进行测试了! 在编写代码有配 置内容时一定要注意 hibernate 和 hibernate3 , 这两个包的名字就只差一个字, 千万不要 有错,否则找错误可是很难的。 注意要把 spring-hibernate.jar 或者把 spring.jar 加 到工程 lib 里 工程原码见 SSHlogin