Java Web框架

Spring(3)

简介:Spring是一个开源框架,Spring是于2003年兴起的一个轻量级的Java开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。

1. 事务管理

  • 事务:一组业务操作ABCD,要么全部成功,要么全部不成功。

  • 特性:ACID

原子性:整体
一致性:完成
隔离性:并发
持久性:结果

  • 隔离问题:

脏读:一个事务读到另一个事务没有提交的数据
不可重复读:一个事务读到另一个事务已提交的数据(update)
虚读(幻读):一个事务读到另一个事务已提交的数据(insert)

  • 隔离级别:

read uncommitted:读未提交。存在3个问题
read committed:读已提交。解决脏读,存在2个问题
repeatable read:可重复读。解决:脏读、不可重复读,存在1个问题。
serializable:串行化。都解决,单事务。

3.1-1.隔离级别.png

  • MySQL事务简单操作
  • // ABCD 一个事务
  • Connection conn = null;
  • try{
  • // 1 获得连接
  • conn = ...;
  • // 2 开启事务
  • conn.setAutoCommit(false);
  • A
  • B
  • C
  • D
  • // 3 提交事务
  • conn.commit();
  • } catche(){
  • // 4 回滚事务
  • conn.rollback();
  • }
  • MySQL事务操作:Savepoint
  • // 需求:AB(必须),CD(可选)
  • Connection conn = null;
  • Savepoint savepoint = null; // 保存点,记录操作的当前位置,之后可以回滚到指定的位置。(可以回滚一部分)
  • try{
  • // 1 获得连接
  • conn = ...;
  • // 2 开启事务
  • conn.setAutoCommit(false);
  • A
  • B
  • savepoint = conn.setSavepoint();
  • C
  • D
  • // 3 提交事务
  • conn.commit();
  • } catche(){
  • if(savepoint != null){ // CD异常
  • // 回滚到CD之前
  • conn.rollback(savepoint);
  • // 提交AB
  • conn.commit();
  • } else{ // AB异常
  • // 回滚AB
  • conn.rollback();
  • }
  • }

2. 事务管理介绍

  • 导入jar包:spring-tx-3.2.0.RELEASE.jar

  • 三个顶级接口,spring-tx-3.2.0.RELEASE.jar\org.springframework.transaction下:

  1. PlatformTransactionManager 平台事务管理器,Spring要管理事务,必须使用事务管理器。
  2. TransactionDefinition:事务详情(事务定义、事务属性),Spring用于确定事务具体详情,例如:隔离级别、是否只读、超时时间等;进行事务配置时,必须配置详情。Spring将配置项封装到该对象实例。
  3. TransactionStatus:事务状态,Spring用于记录当前事务运行状态。例如:是否有保存点,事务是否完成。Spring底层根据状态进行相应操作。

2.1. PlatformTransactionManager 事务管理器

  • 导入jar包:需要时平台事务管理器的实现类
  1. JDBC开发:spring-jdbc-3.2.0.RELEASE.jar
  2. 整合Hibernate:spring-orm-3.2.0.RELEASE.jar
  • 常见的事务管理器
  1. DataSourceTransactionManager,JDBC开发时事务管理器,采用JdbcTemplate;
  2. HibernateTransactionManager,Hibernate开发时事务管理器,整合Hibernate。
  • API详解
  1. TransactionStatus getTransaction(TransactionDefinition definition),事务管理器,通过“事务详情”,获得“事务状态”,从而管理事务。
  2. void commit(TransactionStatus status),根据状态提交。
  3. void rollback(TransactionStatus status),根据状态回滚。
  • TransactionStatus
boolean **hasSavepoint**() Return whether this transaction internally carries a savepoint, that is, has been created as nested transaction based on a savepoint.
boolean **isCompleted**() Return whether this transaction is completed, that is, whether it has already been committed or rolled back.
boolean **isNewTransaction**() Return whether the present transaction is new (else participating in an existing transaction, or potentially not running in an actual transaction in the first place).
boolean **isRollbackOnly**() Return whether the transaction has been marked as rollback-only (either by the application or by the transaction infrastructure).
void **setRollbackOnly**() Set the transaction rollback-only.
  • TransactionDefinition
static int **ISOLATION_DEFAULT** Use the default isolation level of the underlying datastore.
static int **ISOLATION_READ_COMMITTED** Indicates that dirty reads are prevented; non-repeatable reads and phantom reads can occur.
static int **ISOLATION_READ_UNCOMMITTED** Indicates that dirty reads, non-repeatable reads and phantom reads can occur.
static int **ISOLATION_REPEATABLE_READ** Indicates that dirty reads and non-repeatable reads are prevented; phantom reads can occur.
static int **ISOLATION_SERIALIZABLE** Indicates that dirty reads, non-repeatable reads and phantom reads are prevented.
static int **PROPAGATION_MANDATORY** Support a current transaction; throw an exception if no current transaction exists.
static int **PROPAGATION_NESTED** Execute within a nested transaction if a current transaction exists, behave like PROPAGATION_REQUIRED else.
static int **PROPAGATION_NEVER** Do not support a current transaction; throw an exception if a current transaction exists.
static int **PROPAGATION_NOT_SUPPORTED** Do not support a current transaction; rather always execute non-transactionally.
static int **PROPAGATION_REQUIRED** Support a current transaction; create a new one if none exists.
static int **PROPAGATION_REQUIRES_NEW** Create a new transaction, suspending the current transaction if one exists.
static int **PROPAGATION_SUPPORTS** Support a current transaction; execute non-transactionally if none exists.
static int **TIMEOUT_DEFAULT** Use the default timeout of the underlying transaction system, or none if timeouts are not supported.
int **getIsolationLevel**() Return the isolation level.
String **getName**() Return the name of this transaction.
int **getPropagationBehavior**() Return the propagation behavior.
int **getTimeout**() Return the transaction timeout.
boolean **isReadOnly**() Return whether to optimize as a read-only transaction.

传播行为:在两个业务之间如何共享事务。

  1. PROPAGATION_REQUIRED,required,必须 【默认值】。支持当前事务,A如果有事务,B将使用该事务。如果A没有事务,B将创建一个新的事务。

  2. PROPAGATION_SUPPORTS ,supports,支持。支持当前事务,A如果有事务,B将使用该事务。如果A没有事务,B将以非事务执行。

  3. PROPAGATION_MANDATORY,mandatory,强制。支持当前事务,A如果有事务,B将使用该事务。如果A没有事务,B将抛异常。

  4. PROPAGATION_REQUIRES_NEW ,requires_new,必须新的。如果A有事务,将A的事务挂起,B创建一个新的事务。如果A没有事务,B创建一个新的事务。

  5. PROPAGATION_NOT_SUPPORTED,not_supported,不支持。如果A有事务,将A的事务挂起,B将以非事务执行。如果A没有事务,B将以非事务执行。

  6. PROPAGATION_NEVER ,never,从不。如果A有事务,B将抛异常。如果A没有事务,B将以非事务执行。

  7. PROPAGATION_NESTED ,nested ,嵌套。A和B底层采用保存点机制,形成嵌套事务。

掌握:PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、PROPAGATION_NESTED

3. 案例

3.1. 创建数据库

  • create database ee19_spring_day03;
  • use ee19_spring_day03;
  • create table account(
  • id int primary key auto_increment,
  • username varchar(50),
  • money int
  • );
  • insert into account(username,money) values('jack','10000');
  • insert into account(username,money) values('rose','10000');

3.2. 导入jar包

  • 核心:4+1
  • AOP:4 (AOP联盟、Spring AOP、AspectJ规范、Spring Aspect)
  • 数据库:2(JDBC/TX)
  • 驱动:MySQL
  • 连接池:C3P0

3.3. 原始版本

  1. DAO层
  • package com.coderap.dao;
  • public interface AccountDao {
  • /**
  • * 汇款
  • *
  • * @param outer
  • * @param money
  • */
  • public void out(String outer, Integer money);
  • /**
  • * 收款
  • *
  • * @param inner
  • * @param money
  • */
  • public void in(String inner, Integer money);
  • }
  • package com.coderap.dao.impl;
  • import org.springframework.jdbc.core.support.JdbcDaoSupport;
  • import com.coderap.dao.AccountDao;
  • public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
  • @Override
  • public void out(String outer, Integer money) {
  • this.getJdbcTemplate().update("update account set money = money - ? where username = ?", money,outer);
  • }
  • @Override
  • public void in(String inner, Integer money) {
  • this.getJdbcTemplate().update("update account set money = money + ? where username = ?", money,inner);
  • }
  • }
  1. Service层
  • package com.coderap.service;
  • public interface AccountService {
  • /**
  • * 转账
  • * @param outer
  • * @param inner
  • * @param money
  • */
  • public void transfer(String outer ,String inner ,Integer money);
  • }
  • package com.coderap.service.impl;
  • import com.coderap.dao.AccountDao;
  • import com.coderap.service.AccountService;
  • public class AccountServiceImpl implements AccountService {
  • private AccountDao accountDao;
  • public void setAccountDao(AccountDao accountDao) {
  • this.accountDao = accountDao;
  • }
  • @Override
  • public void transfer(String outer, String inner, Integer money) {
  • accountDao.out(outer, money);
  • // 断电
  • // int i = 1/0;
  • accountDao.in(inner, money);
  • }
  • }
  1. Spring配置,src/applicationContext.xml
  • <?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:context="http://www.springframework.org/schema/context"
  • xmlns:aop="http://www.springframework.org/schema/aop"
  • xsi:schemaLocation="http://www.springframework.org/schema/beans
  • http://www.springframework.org/schema/beans/spring-beans.xsd
  • http://www.springframework.org/schema/aop
  • http://www.springframework.org/schema/aop/spring-aop.xsd
  • http://www.springframework.org/schema/context
  • http://www.springframework.org/schema/context/spring-context.xsd">
  • <!-- 1 datasource -->
  • <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  • <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
  • <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ee19_spring_day03"></property>
  • <property name="user" value="root"></property>
  • <property name="password" value="1234"></property>
  • </bean>
  • <!-- 2 dao -->
  • <bean id="accountDao" class="com.coderap.dao.impl.AccountDaoImpl">
  • <property name="dataSource" ref="dataSource"></property>
  • </bean>
  • <!-- 3 service -->
  • <bean id="accountService" class="com.coderap.service.impl.AccountServiceImpl">
  • <property name="accountDao" ref="accountDao"></property>
  • </bean>
  • </beans>
  1. 测试
  • package com.coderap;
  • import org.junit.Test;
  • import org.springframework.context.ApplicationContext;
  • import org.springframework.context.support.ClassPathXmlApplicationContext;
  • import com.coderap.service.AccountService;
  • public class TestApp {
  • @Test
  • public void demo01(){
  • String xmlPath = "applicationContext.xml";
  • ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
  • AccountService accountService = (AccountService) applicationContext.getBean("accountService");
  • accountService.transfer("jack", "rose", 1000);
  • }
  • }

3.4. 手动管理事务(了解)

Spring底层使用TransactionTemplate事务模板进行操作。实现步骤如下:

  1. Service 需要获得TransactionTemplate
  2. Spring 配置模板,并注入给service;
  3. 模板需要注入事务管理器;
  4. 配置事务管理器:DataSourceTransactionManager,需要注入DataSource

我们首先修改Service,为其注入TransactionTemplate对象:

  • package com.coderap.service.impl;
  • import org.springframework.transaction.TransactionStatus;
  • import org.springframework.transaction.support.TransactionCallback;
  • import org.springframework.transaction.support.TransactionCallbackWithoutResult;
  • import org.springframework.transaction.support.TransactionTemplate;
  • import com.coderap.dao.AccountDao;
  • import com.coderap.service.AccountService;
  • public class AccountServiceImpl implements AccountService {
  • private AccountDao accountDao;
  • public void setAccountDao(AccountDao accountDao) {
  • this.accountDao = accountDao;
  • }
  • // 需要spring注入模板
  • private TransactionTemplate transactionTemplate;
  • public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
  • this.transactionTemplate = transactionTemplate;
  • }
  • @Override
  • public void transfer(final String outer, final String inner,
  • final Integer money) {
  • transactionTemplate.execute(new TransactionCallbackWithoutResult() {
  • @Override
  • protected void doInTransactionWithoutResult(TransactionStatus arg0) {
  • accountDao.out(outer, money);
  • // 断电
  • // int i = 1/0;
  • accountDao.in(inner, money);
  • }
  • });
  • }
  • }

接下来修改Spring配置,将对象的创建和注入交由Spring来管理:

  • <?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:context="http://www.springframework.org/schema/context"
  • xmlns:aop="http://www.springframework.org/schema/aop"
  • xsi:schemaLocation="http://www.springframework.org/schema/beans
  • http://www.springframework.org/schema/beans/spring-beans.xsd
  • http://www.springframework.org/schema/aop
  • http://www.springframework.org/schema/aop/spring-aop.xsd
  • http://www.springframework.org/schema/context
  • http://www.springframework.org/schema/context/spring-context.xsd">
  • <!-- 1 datasource -->
  • <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  • <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
  • <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ee19_spring_day03"></property>
  • <property name="user" value="root"></property>
  • <property name="password" value="1234"></property>
  • </bean>
  • <!-- 2 dao -->
  • <bean id="accountDao" class="com.coderap.dao.impl.AccountDaoImpl">
  • <property name="dataSource" ref="dataSource"></property>
  • </bean>
  • <!-- 3 service -->
  • <bean id="accountService" class="com.coderap.service.impl.AccountServiceImpl">
  • <property name="accountDao" ref="accountDao"></property>
  • <property name="transactionTemplate" ref="transactionTemplate"></property>
  • </bean>
  • <!-- 4 创建模板 -->
  • <bean id="transactionTemplate"
  • class="org.springframework.transaction.support.TransactionTemplate">
  • <property name="transactionManager" ref="txManager"></property>
  • </bean>
  • <!-- 5 配置事务管理器 ,管理器需要事务,事务从Connection获得,连接从连接池DataSource获得 -->
  • <bean id="txManager"
  • class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  • <property name="dataSource" ref="dataSource"></property>
  • </bean>
  • </beans>

这样以来,就手动为数据库操作加入了事务管理。

3.5. 工厂bean 生成代理:半自动

Spring提供管理事务的代理工厂beanTransactionProxyFactoryBean

  1. getBean()获得代理对象,即修改测试类,获取相应的代理对象:
  • package com.coderap;
  • import org.junit.Test;
  • import org.springframework.context.ApplicationContext;
  • import org.springframework.context.support.ClassPathXmlApplicationContext;
  • import com.coderap.service.AccountService;
  • public class TestApp {
  • @Test
  • public void demo01(){
  • String xmlPath = "applicationContext.xml";
  • ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
  • AccountService accountService = (AccountService) applicationContext.getBean("proxyAccountService");
  • accountService.transfer("jack", "rose", 1000);
  • }
  • }
  1. Spring配置文件中配置一个代理:
  • <?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:context="http://www.springframework.org/schema/context"
  • xmlns:aop="http://www.springframework.org/schema/aop"
  • xsi:schemaLocation="http://www.springframework.org/schema/beans
  • http://www.springframework.org/schema/beans/spring-beans.xsd
  • http://www.springframework.org/schema/aop
  • http://www.springframework.org/schema/aop/spring-aop.xsd
  • http://www.springframework.org/schema/context
  • http://www.springframework.org/schema/context/spring-context.xsd">
  • <!-- 1 datasource -->
  • <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  • <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
  • <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ee19_spring_day03"></property>
  • <property name="user" value="root"></property>
  • <property name="password" value="1234"></property>
  • </bean>
  • <!-- 2 dao -->
  • <bean id="accountDao" class="com.coderap.dao.impl.AccountDaoImpl">
  • <property name="dataSource" ref="dataSource"></property>
  • </bean>
  • <!-- 3 service -->
  • <bean id="accountService" class="com.coderap.service.impl.AccountServiceImpl">
  • <property name="accountDao" ref="accountDao"></property>
  • </bean>
  • <!-- 4 service 代理对象
  • 4.1 proxyInterfaces 接口
  • 4.2 target 目标类
  • 4.3 transactionManager 事务管理器
  • 4.4 transactionAttributes 事务属性(事务详情)
  • prop.key :确定哪些方法使用当前事务配置
  • prop.text:用于配置事务详情
  • 格式:PROPAGATION, ISOLATION, readOnly, -Exception, +Exception
  • 传播行为 隔离级别 是否只读 常回滚 异常提交
  • 例如:
  • <prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT</prop> 默认传播行为,和隔离级别
  • <prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly</prop> 只读
  • <prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT,+java.lang.ArithmeticException</prop> 有异常扔提交
  • -->
  • <bean id="proxyAccountService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
  • <property name="proxyInterfaces" value="com.coderap.service.AccountService"></property>
  • <property name="target" ref="accountService"></property>
  • <property name="transactionManager" ref="txManager"></property>
  • <property name="transactionAttributes">
  • <props>
  • <prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT</prop>
  • </props>
  • </property>
  • </bean>
  • <!-- 5 事务管理器 -->
  • <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  • <property name="dataSource" ref="dataSource"></property>
  • </bean>
  • </beans>

3.6. AOP 配置基于xml【掌握】

在Spring xml 配置AOP自动生成代理,进行事务的管理:

  1. 配置管理器;
  2. 配置事务详情;
  3. 配置AOP。
  • <?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:context="http://www.springframework.org/schema/context"
  • 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.xsd
  • http://www.springframework.org/schema/aop
  • http://www.springframework.org/schema/aop/spring-aop.xsd
  • http://www.springframework.org/schema/context
  • http://www.springframework.org/schema/context/spring-context.xsd
  • http://www.springframework.org/schema/tx
  • http://www.springframework.org/schema/tx/spring-tx.xsd">
  • <!-- 1 datasource -->
  • <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  • <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
  • <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ee19_spring_day03"></property>
  • <property name="user" value="root"></property>
  • <property name="password" value="1234"></property>
  • </bean>
  • <!-- 2 dao -->
  • <bean id="accountDao" class="com.coderap.dao.impl.AccountDaoImpl">
  • <property name="dataSource" ref="dataSource"></property>
  • </bean>
  • <!-- 3 service -->
  • <bean id="accountService" class="com.coderap.service.impl.AccountServiceImpl">
  • <property name="accountDao" ref="accountDao"></property>
  • </bean>
  • <!-- 4 事务管理 -->
  • <!-- 4.1 事务管理器 -->
  • <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  • <property name="dataSource" ref="dataSource"></property>
  • </bean>
  • <!-- 4.2 事务详情(事务通知) , 在aop筛选基础上,对ABC三个确定使用什么样的事务。例如:AC读写、B只读 等
  • <tx:attributes> 用于配置事务详情(属性属性)
  • <tx:method name=""/> 详情具体配置
  • propagation 传播行为 , REQUIRED:必须;REQUIRES_NEW:必须是新的
  • isolation 隔离级别
  • -->
  • <tx:advice id="txAdvice" transaction-manager="txManager">
  • <tx:attributes>
  • <tx:method name="transfer" propagation="REQUIRED" isolation="DEFAULT"/>
  • </tx:attributes>
  • </tx:advice>
  • <!-- 4.3 AOP编程,目标类有ABCD(4个连接点),切入点表达式 确定增强的连接器,从而获得切入点:ABC -->
  • <aop:config>
  • <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.coderap.service..*.*(..))"/>
  • </aop:config>
  • </beans>

3.7. AOP配置基于注解

  1. 配置事务管理器,将并事务管理器交予Spring:
  • <?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:context="http://www.springframework.org/schema/context"
  • 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.xsd
  • http://www.springframework.org/schema/aop
  • http://www.springframework.org/schema/aop/spring-aop.xsd
  • http://www.springframework.org/schema/context
  • http://www.springframework.org/schema/context/spring-context.xsd
  • http://www.springframework.org/schema/tx
  • http://www.springframework.org/schema/tx/spring-tx.xsd">
  • <!-- 1 datasource -->
  • <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  • <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
  • <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ee19_spring_day03"></property>
  • <property name="user" value="root"></property>
  • <property name="password" value="1234"></property>
  • </bean>
  • <!-- 2 dao -->
  • <bean id="accountDao" class="com.coderap.dao.impl.AccountDaoImpl">
  • <property name="dataSource" ref="dataSource"></property>
  • </bean>
  • <!-- 3 service -->
  • <bean id="accountService" class="com.coderap.service.impl.AccountServiceImpl">
  • <property name="accountDao" ref="accountDao"></property>
  • </bean>
  • <!-- 4 事务管理 -->
  • <!-- 4.1 事务管理器 -->
  • <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  • <property name="dataSource" ref="dataSource"></property>
  • </bean>
  • <!-- 4.2 将管理器交予spring
  • * transaction-manager 配置事务管理器
  • * proxy-target-class
  • true : 底层强制使用cglib 代理
  • -->
  • <tx:annotation-driven transaction-manager="txManager"/>
  • </beans>
  1. 在目标类或目标方法添加注解即可@Transactional
  • package com.coderap.service.impl;
  • import org.springframework.transaction.annotation.Isolation;
  • import org.springframework.transaction.annotation.Propagation;
  • import org.springframework.transaction.annotation.Transactional;
  • import com.coderap.dao.AccountDao;
  • import com.coderap.service.AccountService;
  • @Transactional(propagation=Propagation.REQUIRED , isolation = Isolation.DEFAULT)
  • public class AccountServiceImpl implements AccountService {
  • private AccountDao accountDao;
  • public void setAccountDao(AccountDao accountDao) {
  • this.accountDao = accountDao;
  • }
  • @Override
  • public void transfer(String outer, String inner, Integer money) {
  • accountDao.out(outer, money);
  • //断电
  • int i = 1/0;
  • accountDao.in(inner, money);
  • }
  • }

注:添加的注解为@Transactional(propagation=Propagation.REQUIRED , isolation = Isolation.DEFAULT)

4. Junit整合

将JUint与Spring整合,需要先导入jar包:spring-test-3.2.0.RELEASE.jar。然后使用注解进行以下的配置:

  1. 让Junit通知spring加载配置文件
  2. 让Spring容器自动进行注入
  • package com.coderap;
  • import org.junit.Test;
  • import org.junit.runner.RunWith;
  • import org.springframework.beans.factory.annotation.Autowired;
  • import org.springframework.test.context.ContextConfiguration;
  • import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  • import com.coderap.service.AccountService;
  • @RunWith(SpringJUnit4ClassRunner.class)
  • @ContextConfiguration(locations="classpath:applicationContext.xml")
  • public class TestApp {
  • @Autowired //与junit整合,不需要在spring xml配置扫描
  • private AccountService accountService;
  • @Test
  • public void demo01(){
  • // String xmlPath = "applicationContext.xml";
  • // ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
  • // AccountService accountService = (AccountService) applicationContext.getBean("accountService");
  • accountService.transfer("jack", "rose", 1000);
  • }
  • }

5. 整合web

  1. 导入jar包spring-web-3.2.0.RELEASE.jar
    spring-web.xml

  2. tomcat启动加载配置文件,只加载一次的方法有以下几种:

  • Servlet:init(ServletConfig)中可以进行配置;
  • Filter:过滤器的init(FilterConfig)方法,在web.xml注册过滤器自动调用初始化;
  • Listener:ServletContextListener,servletContext对象监听;

Spring提供监听器ContextLoaderListener,我们可以在web.xml中配置该监听器:

  • <!-- 配置spring 监听器,加载xml配置文件 -->
  • <listener>
  • <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  • </listener>

Spring会默认在初始化的时候加载容器。如果只配置监听器,将默认从/WEB-INF/applicationContext.xml加载xml,而由于我们的配置文件其实是在/WEB-INF/src/applicationContext.xml下,如果找不到文件会报错,所以还需要确定配置文件的位置,最终的web.xml文件中关于Spring的配置如下:

  • <?xml version="1.0" encoding="UTF-8"?>
  • <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
  • xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  • xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  • http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  • <!-- 确定配置文件位置 -->
  • <context-param>
  • <param-name>contextConfigLocation</param-name>
  • <param-value>classpath:applicationContext.xml</param-value>
  • </context-param>
  • <!-- 配置spring 监听器,加载xml配置文件 -->
  • <listener>
  • <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  • </listener>
  • </web-app>

配置了以上内容,我们就可以在ServletContext作用域中获取Spring容器:

  • package com.coderap.web.servlet;
  • import java.io.IOException;
  • import javax.servlet.ServletException;
  • import javax.servlet.http.HttpServlet;
  • import javax.servlet.http.HttpServletRequest;
  • import javax.servlet.http.HttpServletResponse;
  • import org.springframework.context.ApplicationContext;
  • import org.springframework.web.context.WebApplicationContext;
  • import org.springframework.web.context.support.WebApplicationContextUtils;
  • import com.coderap.service.AccountService;
  • public class HelloServlet extends HttpServlet {
  • public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  • // 从application作用域(ServletContext)获得spring容器
  • // 方式1: 手动从作用域获取
  • ApplicationContext applicationContext =
  • (ApplicationContext) this.getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
  • // 方式2:通过工具获取
  • ApplicationContext apppApplicationContext2 =
  • WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
  • //操作
  • AccountService accountService = (AccountService) applicationContext.getBean("accountService");
  • accountService.transfer("jack", "rose", 1000);
  • }
  • public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  • this.doGet(request, response);
  • }
  • }

6. SSH整合

6.1. jar整合

  • Struts:2.3.15.3
  • Hibernate:3.6.10
  • Spring:3.2.0

6.1.1. struts

struts-2.3.15.3\apps\struts2-blank\WEB-INF\lib

模板技术 ,一般用于页面静态化

  • freemarker:扩展名:*.ftl
  • velocity:扩展名 *.vm

6.1.2. Spring

  • 基础:4+1,beans、core、context、expression、commons-logging(struts已经导入)
  • AOP:AOP联盟、Spring AOP 、AspectJ规范、Spring Aspect
  • DB:JDBC、TX
  • 测试:test
  • Web开发:Spring Web
  • 驱动:MySQL
  • 连接池:C3P0
  • 整合Hibernate:Spring ORM

6.1.3. Hibernate

  • %h%\hibernate3.jar核心
  • %h%\lib\required必须
  • %h%\lib\jpaJPA规范(Java Persistent API,持久API),Hibernate注解开发@Entity@Id

6.1.3.1. 整合log4j

导入log4j...jar(struts已经导入),整合(过渡):slf4j-log4j12-1.7.5.jar

6.1.3.2. 二级缓存

核心:ehcache-1.5.0.jar

依赖:

  • backport-util-concurrent-2.1.jar
  • commons-logging(存在)

6.1.4. 整合包

Spring整合Hibernate: spring orm
Struts 整合Spring:struts2-spring-plugin-2.3.15.3.jar

删除重复jar包:javassist包是重复的

整合完毕后一共39个包。

6.2. Spring整合Hibernate:有hibernate.cfg.xml

6.2.1. 创建表

  • create table t_user(
  • id int primary key auto_increment,
  • username varchar(50),
  • password varchar(32),
  • age int
  • );

6.2.2. PO类

User.java文件:

  • package com.coderap.domain;
  • public class User {
  • private Integer id;
  • private String username;
  • private String password;
  • private Integer age;
  • public Integer getId() {
  • return id;
  • }
  • public void setId(Integer id) {
  • this.id = id;
  • }
  • public String getUsername() {
  • return username;
  • }
  • public void setUsername(String username) {
  • this.username = username;
  • }
  • public String getPassword() {
  • return password;
  • }
  • public void setPassword(String password) {
  • this.password = password;
  • }
  • public Integer getAge() {
  • return age;
  • }
  • public void setAge(Integer age) {
  • this.age = age;
  • }
  • }

User.hbm.xml文件:

  • <?xml version="1.0" encoding="UTF-8"?>
  • <!DOCTYPE hibernate-mapping PUBLIC
  • "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  • "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
  • <hibernate-mapping>
  • <class name="com.coderap.domain.User" table="t_user">
  • <id name="id">
  • <generator class="native"></generator>
  • </id>
  • <property name="username"></property>
  • <property name="password"></property>
  • <property name="age"></property>
  • </class>
  • </hibernate-mapping>

6.2.3. dao层

Spring提供HibernateTemplate用于操作PO对象,类似Hibernate Session对象。

UserDao.java文件:

  • package com.coderap.dao;
  • import com.coderap.domain.User;
  • public interface UserDao {
  • /**
  • * 保存
  • *
  • * @param user
  • */
  • public void save(User user);
  • }

UserDaoImpl.java文件:

  • package com.coderap.dao.impl;
  • import org.springframework.orm.hibernate3.HibernateTemplate;
  • import com.coderap.dao.UserDao;
  • import com.coderap.domain.User;
  • public class UserDaoImpl implements UserDao {
  • // 需要spring注入模板 ,底层使用session,session 有sessionFactory获得
  • private HibernateTemplate hibernateTemplate;
  • public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
  • this.hibernateTemplate = hibernateTemplate;
  • }
  • @Override
  • public void save(User user) {
  • this.hibernateTemplate.save(user);
  • }
  • }

6.2.4. Service层

UserService.java文件:

  • package com.coderap.service;
  • import com.coderap.domain.User;
  • public interface UserService {
  • /**
  • * 注册
  • * @param user
  • */
  • public void register(User user);
  • }

UserServiceImpl.java文件:

  • package com.coderap.service.impl;
  • import com.coderap.dao.UserDao;
  • import com.coderap.domain.User;
  • import com.coderap.service.UserService;
  • public class UserServiceImpl implements UserService {
  • private UserDao userDao;
  • public void setUserDao(UserDao userDao) {
  • this.userDao = userDao;
  • }
  • @Override
  • public void register(User user) {
  • userDao.save(user);
  • }
  • }

6.2.5. hibernate.cfg.xml

  • <?xml version="1.0" encoding="UTF-8"?>
  • <!DOCTYPE hibernate-configuration PUBLIC
  • "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
  • "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
  • <hibernate-configuration>
  • <session-factory>
  • <!-- 1基本4项 -->
  • <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
  • <property name="hibernate.connection.url">jdbc:mysql:///ee19_spring_day03</property>
  • <property name="hibernate.connection.username">root</property>
  • <property name="hibernate.connection.password">1234</property>
  • <!-- 2 配置方言 -->
  • <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
  • <!-- 3 sql语句 -->
  • <property name="hibernate.show_sql">true</property>
  • <property name="hibernate.format_sql">true</property>
  • <!-- 4 自动生成表(一般没用) -->
  • <property name="hibernate.hbm2ddl.auto">update</property>
  • <!-- 5本地线程绑定 -->
  • <property name="hibernate.current_session_context_class">thread</property>
  • <!-- 导入映射文件 -->
  • <mapping resource="com/coderap/domain/User.hbm.xml" />
  • </session-factory>
  • </hibernate-configuration>

6.2.6. applicationContext.xml

  • <?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" xmlns:context="http://www.springframework.org/schema/context"
  • xsi:schemaLocation="http://www.springframework.org/schema/beans
  • http://www.springframework.org/schema/beans/spring-beans.xsd
  • http://www.springframework.org/schema/tx
  • http://www.springframework.org/schema/tx/spring-tx.xsd
  • http://www.springframework.org/schema/aop
  • http://www.springframework.org/schema/aop/spring-aop.xsd
  • http://www.springframework.org/schema/context
  • http://www.springframework.org/schema/context/spring-context.xsd">
  • <!-- 1 加载hibenrate.cfg.xml 获得SessionFactory * configLocation确定配置文件位置 -->
  • <bean id="sessionFactory"
  • class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  • <property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
  • </bean>
  • <!-- 2创建模板 * 底层使用session,session 有sessionFactory获得 -->
  • <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
  • <property name="sessionFactory" ref="sessionFactory"></property>
  • </bean>
  • <!-- 3 dao -->
  • <bean id="userDao" class="com.coderap.dao.impl.UserDaoImpl">
  • <property name="hibernateTemplate" ref="hibernateTemplate"></property>
  • </bean>
  • <!-- 4 service -->
  • <bean id="userService" class="com.coderap.service.impl.UserServiceImpl">
  • <property name="userDao" ref="userDao"></property>
  • </bean>
  • <!-- 5 事务管理 -->
  • <!-- 5.1 事务管理器 :HibernateTransactionManager -->
  • <bean id="txManager"
  • class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  • <property name="sessionFactory" ref="sessionFactory"></property>
  • </bean>
  • <!-- 5.2 事务详情 ,给ABC进行具体事务设置 -->
  • <tx:advice id="txAdvice" transaction-manager="txManager">
  • <tx:attributes>
  • <tx:method name="register" />
  • </tx:attributes>
  • </tx:advice>
  • <!-- 5.3 AOP编程,ABCD 筛选ABC -->
  • <aop:config>
  • <aop:advisor advice-ref="txAdvice"
  • pointcut="execution(* com.coderap.service..*.*(..))" />
  • </aop:config>
  • </beans>

6.2.7. 测试

  • package com.coderap;
  • import org.junit.Test;
  • import org.junit.runner.RunWith;
  • import org.springframework.beans.factory.annotation.Autowired;
  • import org.springframework.test.context.ContextConfiguration;
  • import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  • import com.coderap.domain.User;
  • import com.coderap.service.UserService;
  • @RunWith(SpringJUnit4ClassRunner.class)
  • @ContextConfiguration(locations="classpath:applicationContext.xml")
  • public class TestApp {
  • @Autowired
  • private UserService userService;
  • @Test
  • public void demo01(){
  • User user = new User();
  • user.setUsername("jack");
  • user.setPassword("1234");
  • user.setAge(18);
  • userService.register(user);
  • }
  • }

6.3. Spring整合Hibernate:即替代hibernate.cfg.xml

用Spring整合Hibernate,就是将hibernate.cfg.xml文件中的所有内容一一整合到applicationContext.xml文件中:

6.3.1. 整合hibernate.cfg.xmlapplicationContext.xml文件中

  • <?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"
  • xmlns:context="http://www.springframework.org/schema/context"
  • xsi:schemaLocation="http://www.springframework.org/schema/beans
  • http://www.springframework.org/schema/beans/spring-beans.xsd
  • http://www.springframework.org/schema/tx
  • http://www.springframework.org/schema/tx/spring-tx.xsd
  • http://www.springframework.org/schema/aop
  • http://www.springframework.org/schema/aop/spring-aop.xsd
  • http://www.springframework.org/schema/context
  • http://www.springframework.org/schema/context/spring-context.xsd">
  • <!-- 1.1加载properties文件 -->
  • <!-- 1.2 配置数据源 -->
  • <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  • <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
  • <property name="jdbcUrl" value="jdbc:mysql:///ee19_spring_day03"></property>
  • <property name="user" value="root"></property>
  • <property name="password" value="1234"></property>
  • </bean>
  • <!-- 1.3 配置 LocalSessionFactoryBean,获得SessionFactory
  • * configLocation确定配置文件位置
  • <property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
  • 1,dataSource 数据源
  • 2,hibernateProperties hibernate其他配置项
  • 3,导入映射文件
  • mappingLocations ,确定映射文件位置,需要“classpath:” ,支持通配符,常用
  • <property name="mappingLocations" value="classpath:com/coderap/domain/User.hbm.xml"></property>
  • <property name="mappingLocations" value="classpath:com/coderap/domain/*.hbm.xml"></property>
  • mappingResources ,加载执行映射文件,从src下开始 。不支持通配符*
  • <property name="mappingResources" value="com/coderap/domain/User.hbm.xml"></property>
  • mappingDirectoryLocations ,加载指定目录下的,所有配置文件
  • <property name="mappingDirectoryLocations" value="classpath:com/coderap/domain/"></property>
  • mappingJarLocations , 从jar包中获得映射文件
  • -->
  • <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  • <property name="dataSource" ref="dataSource"></property>
  • <property name="hibernateProperties">
  • <props>
  • <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
  • <prop key="hibernate.show_sql">true</prop>
  • <prop key="hibernate.format_sql">true</prop>
  • <prop key="hibernate.hbm2ddl.auto">update</prop>
  • <prop key="hibernate.current_session_context_class">thread</prop>
  • </props>
  • </property>
  • <property name="mappingLocations" value="classpath:com/coderap/domain/*.hbm.xml"></property>
  • </bean>
  • <!-- 3 dao -->
  • <bean id="userDao" class="com.coderap.dao.impl.UserDaoImpl">
  • <property name="hibernateTemplate" ref="hibernateTemplate"></property>
  • </bean>
  • <!-- 4 service -->
  • <bean id="userService" class="com.coderap.service.impl.UserServiceImpl">
  • <property name="userDao" ref="userDao"></property>
  • </bean>
  • <!-- 5 事务管理 -->
  • <!-- 5.1 事务管理器 :HibernateTransactionManager -->
  • <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" >
  • <property name="sessionFactory" ref="sessionFactory"></property>
  • </bean>
  • <!-- 5.2 事务详情 ,给ABC进行具体事务设置 -->
  • <tx:advice id="txAdvice" transaction-manager="txManager">
  • <tx:attributes>
  • <tx:method name="register"/>
  • </tx:attributes>
  • </tx:advice>
  • <!-- 5.3 AOP编程,ABCD 筛选 ABC -->
  • <aop:config>
  • <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.coderap.service..*.*(..))"/>
  • </aop:config>
  • </beans>

6.3.2. 修改Dao,使用HibernateDaoSupport

首先让Dao继承HibernateDaoSupport,该类会自动注入HibernateTemplate模板:

  • package com.coderap.dao.impl;
  • import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
  • import com.coderap.dao.UserDao;
  • import com.coderap.domain.User;
  • // 底层需要SessionFactory,自动创建HibernateTemplate模板
  • public class UserDaoImpl extends HibernateDaoSupport implements UserDao {
  • @Override
  • public void save(User user) {
  • this.getHibernateTemplate().save(user);
  • }
  • }

由于HibernateTemplate模板会自动注入,所以配置applicationContext.xml文件中的模板配置也可以去掉了,但是HibernateDaoSupport的自动注入需要使用SessionFactory,所以需要手动为Dao注入SessionFactory

  • // HibernateDaoSupport源码相关
  • public final void setSessionFactory(SessionFactory sessionFactory) {
  • if (this.hibernateTemplate == null || sessionFactory != this.hibernateTemplate.getSessionFactory()) {
  • this.hibernateTemplate = createHibernateTemplate(sessionFactory);
  • }
  • }
  • protected HibernateTemplate createHibernateTemplate(SessionFactory sessionFactory) {
  • return new HibernateTemplate(sessionFactory);
  • }

从Spring配置文件applicationContext.xml中删除模板配置,给Dao注入SessionFactory

  • <!-- 3 dao -->
  • <bean id="userDao" class="com.coderap.dao.impl.UserDaoImpl">
  • <property name="sessionFactory" ref="sessionFactory"></property>
  • </bean>

6.4. Struts整合Spring:Spring创建Action

  1. 编写action类,并将其配置给Spring ,Spring可以注入Service:

首先编写Action类如下:

  • package com.coderap.web.action;
  • import com.coderap.domain.User;
  • import com.coderap.service.UserService;
  • import com.opensymphony.xwork2.ActionSupport;
  • import com.opensymphony.xwork2.ModelDriven;
  • public class UserAction extends ActionSupport implements ModelDriven<User> {
  • // 1 封装数据
  • private User user = new User();
  • @Override
  • public User getModel() {
  • return user;
  • }
  • // 2 service
  • private UserService userService;
  • public void setUserService(UserService userService) {
  • this.userService = userService;
  • }
  • //////////////////////////////////
  • /**
  • * 注册
  • * @return
  • */
  • public String register(){
  • userService.register(user);
  • return "success";
  • }
  • }

由于UserService使用了自动注入,所以需要在Spring中进行配置:

  • <!-- 6 配置action -->
  • <bean id="userAction" class="com.coderap.web.action.UserAction" scope="prototype">
  • <property name="userService" ref="userService"></property>
  • </bean>
  1. 编写struts.xml
  • <?xml version="1.0" encoding="UTF-8" ?>
  • <!DOCTYPE struts PUBLIC
  • "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
  • "http://struts.apache.org/dtds/struts-2.3.dtd">
  • <struts>
  • <!-- 开发模式 -->
  • <constant name="struts.devMode" value="true" />
  • <package name="default" namespace="/" extends="struts-default">
  • <!--
  • 此处的class从com.coderap.web.action.UserAction直接替换为了userAction简短类名,其底层自动从spring容器中使用getBean("userAction")通过名称获得内容
  • -->
  • <action name="userAction_*" class="userAction" method="{1}">
  • <result name="success">/message.jsp</result>
  • </action>
  • </package>
  • </struts>

此处的action中,可以直接从Spring容器中使用getBean("userAction")通过名称获得相应的对象的缘由如下:

我们已知的struts 配置文件有以下几种:

  • default.properties,常量配置文件
  • struts-default.xml,默认核心配置文件
  • struts-plugins.xml,插件配置文件
  • struts.xml,自定义核心配置文件

在配置常量的使用时,后面配置项,将覆盖前面的。

default.properties/org/apache/struts2/default.properties)文件中,此配置文件中确定了按照“名称”自动注入,但是并没有打开struts.objectFactory = spring配置项:

  • ### if specified, the default object factory can be overridden here
  • ### Note: short-hand notation is supported in some cases, such as "spring"
  • ### Alternatively, you can provide a com.opensymphony.xwork2.ObjectFactory subclass name here
  • # struts.objectFactory = spring
  • ### specifies the autoWiring logic when using the SpringObjectFactory.
  • ### valid values are: name, type, auto, and constructor (name is the default)
  • struts.objectFactory.spring.autoWire = name

但是在我们Struts整合Spring的时候,导入一个插件jar包,在该包中配置有一个插件的xml文件,其部分内容如下:

  • <!-- Make the Spring object factory the automatic default -->
  • <constant name="struts.objectFactory" value="spring" />

可以发现,这里已经将struts.objectFactory = spring配置项覆盖并打开了,那么之后的Action将由Spring创建,并按照名称自动注入。此处还需要注意的是,如果想要使用自动注入,要求在Action类中,必须提供Service名称与Spring配置文件一致。

  1. 表单jsp页面
  • <form action="${pageContext.request.contextPath}/userAction_register" method="post">
  • 用户名:<input type="text" name="username"/> <br/>
  • 密码:<input type="password" name="password"/> <br/>
  • 年龄:<input type="text" name="age"/> <br/>
  • <input type="submit" />
  • </form>
  1. web.xml 配置
  • 确定配置文件contextConfigLocation
  • 配置监听器ContextLoaderListener
  • 配置前端控制器StrutsPrepareAndExecuteFitler
  • <?xml version="1.0" encoding="UTF-8"?>
  • <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
  • xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  • xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  • http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  • <!-- 1 确定spring xml位置 -->
  • <context-param>
  • <param-name>contextConfigLocation</param-name>
  • <param-value>classpath:applicationContext.xml</param-value>
  • </context-param>
  • <!-- 2 spring监听器 -->
  • <listener>
  • <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  • </listener>
  • <!-- 3 struts 前端控制器 -->
  • <filter>
  • <filter-name>struts2</filter-name>
  • <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  • </filter>
  • <filter-mapping>
  • <filter-name>struts2</filter-name>
  • <url-pattern>/*</url-pattern>
  • </filter-mapping>
  • </web-app>

至此,SSH的整合就完成了。