270 likes | 401 Views
第九章. Spring 与 Struts 、 Hibernate 的集成. 回顾. 在线购书系统中,要求不修改 BookBizImpl 代码的情况下使用“后置通知”增加如下功能: 对买书的用户进行返利:每买一册书返利 3 元。 即:每调用一次 buy 方法打印: “ [ 销售返利 ][ 时间 ] 用户名 : 返利 3 元。” 问题: 1 、什么是后置通知? 2 、如何编写配置文件, 将 RakeOffAdvice 织入到 BookBiz 中。. public class RakeOffAdvice implements AferReturningAdvice{
E N D
第九章 Spring与Struts、Hibernate的集成
回顾 • 在线购书系统中,要求不修改BookBizImpl代码的情况下使用“后置通知”增加如下功能: • 对买书的用户进行返利:每买一册书返利3元。 • 即:每调用一次buy方法打印:“[销售返利][时间]用户名:返利3元。” 问题: 1、什么是后置通知? 2、如何编写配置文件, 将RakeOffAdvice织入到BookBiz中。 • public class RakeOffAdvice implements AferReturningAdvice{ • public void afterReturning(Object returnValue,Method m, • Object[] args,Object target) throws Throwable{ • ... ... • } • }
预习检查 • 如何使用Spring简化Hibernate编码? • Spring如何与Struts集成? • 什么是声明式事务?
本章任务 • 使用Spring依赖注入组装后台代码 • 给业务逻辑层添加事务支持
本章目标 • 掌握Spring与Struts的集成 • 掌握Spring与Hibernate的集成 • 学会使用Spring实现声明式事务
Spring与Hibernate集成 使现有Java EE技术更易用 Spring的目标 使用Hibernate的繁琐步骤 • 使用Spring简化Hibernate编程 import org.springframework.orm.hibernate3.support.HibernateDaoSupport; public class FwxxDAOHibImpl extends HibernateDaoSupport implements FwxxDAO{ public void add(FWXX fwxx) { super.getHibernateTemplate().add(fwxx); } // ... 其他持久化方法的实现 } 使用Spring对Hibernate支持
Spring与Hibernate集成 public class FwxxDAOHibImpl extends HibernateDaoSupport implements FwxxDAO { ... ... public FWXX get(int fwid) { return (FWXX) super.getHibernateTemplate().get(FWXX.class, fwid); } public List search(final FWXX condition){ return super.getHibernateTemplate().executeFind( new HibernateCallback() { public Object doInHibernate(Session s) throws HibernateException { Criteria c = s.createCriteria(FWXX.class); if (null!=condition) { // 构造Criteria查询条件的代码 ... ... } c.addOrder(Order.asc("custCode")); return c.list(); } }); } } • 使用Spring简化Hibernate编程 在这里构造查询条件
Spring与Hibernate集成 • Session在哪里创建? • 配置数据源和SessionFactory • 使用Spring 依赖注入,只需配置,无需编码 FwxxDAOHibImpl中 如何创建session的? HibernateDaoSupport提供了 setSessionFactory方法 Spring提供了LocalSessionFactoryBean 用于创建SessionFactory,但需要通过 setDataSource设置数据源 数据源 (DataSource)
Spring与Hibernate集成 dataSource sessionFactory fwxxDAO fwxxBiz fwxxAction • 依赖注入顺序 • 配置数据源 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.microsoft.jdbc.sqlserver.SQLServerDriver" /> <property name="url" value="jdbc:microsoft:sqlserver://localhost;DatabaseName=epet;SelectMethod=cursor" /> <property name="username" value="sa" /> <property name="password" value="pwd" /> </bean> 数据库连接信息
Spring与Hibernate集成 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mappingResources"> <list> <value>com/aptech/jb/entity/USER.hbm.xml</value> <value>com/aptech/jb/entity/FWXX.hbm.xml</value> ... </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect"> org.hibernate.dialect.SQLServerDialect </prop> <prop key="hibernate.show_sql">true</prop> </props> </property> </bean> • 配置SessionFactory 注入dataSource Hibernate映射文件列表 Hibernate属性 演示示例:Spring与Hibernate集成
小结 • 继承自HibernateDaoSupport实现UserDAO接口。 package com.aptech.jb.dao; public interface UserDAO{ public User get(int id); public void add(User item); public void del(int id); public void update(User item); public List search(final User condition); }
使用Spring重新组装Web程序 • 使用Spring管理依赖 • Web应用中组件间的依赖关系 • 组装 • sessionFactory注入到DAO中 • DAO注入到Biz/Service中:首先增加setter方法,去掉代码中对接口实现的依赖 dataSource <bean id="fwxxDAO" class="com.aptech.jb.dao.hibimpl.FwxxDaoHibImpl"> <property name="sessionFactory" ref ="sessionFactory" /> </bean> sessionFactory fwxxDAO fwxxBiz fwxxAction <bean id="fwxxBiz" class="com.aptech.jb.biz.impl.FwxxBizImpl"> <property name="fwxxDAO" ref ="fwxxDAO" /> </bean>
使用Spring重新组装Web程序 请求 ActionServlet Action • 与Struts集成 • 回顾:Struts机制 • 我们用Spring创建Action,告诉Struts到Spring的Bean工厂中去取 Action Bean是由 Struts创建的
使用Spring重新组装Web程序 • 与Struts集成 • 步骤1. 在struts-config.xml配置插件 <?xml version="1.0" encoding="GBK"?> <struts-config> ... ... <message-resources parameter="com.aptech.jb.ApplicationResources" /> <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"> <set-property property="contextConfigLocation" value="classpath:applicationContext.xml" /> </plug-in> </struts-config> Spring配置文件路径
使用Spring重新组装Web程序 • 与Struts集成 • 步骤2. 修改Action Bean配置 <?xml version="1.0" encoding="GBK"?> <struts-config> <action name="fwxxForm" path="/fwxx" parameter="operate" scope="request" type="org.springframework.web.struts.DelegatingActionProxy"> <forward name="list" path="/list.jsp" /> <forward name="detail" path="/detail.jsp" /> <forward name="modify" path="/modify.jsp" /> <forward name="error" path="/error.jsp" /> </action> </struts-config> 修改type属性
使用Spring重新组装Web程序 • 与Struts集成 • 步骤3. 在Spring配置文件中配置Action Bean,将Biz注入 name属性与Struts配置中path属性相同 <bean name="/fwxx" class="com.aptech.jb.web.action.FwxxAction"> <property name="fwxxBiz" ref="fwxxBiz" /> </bean> 演示示例:Spring与Struts集成
小结 dataSource sessionFactory fwxxDAO fwxxBiz fwxxAction • 写出fwxx相关的从dataSource到fwxxAction的所有接口和类,并在Spring配置文件中配置。 在此基础上,增加user相关类的配置。 提示: dataSource和sessionFacotory的配置可以重用
声明式事务 散布在系统中的事务处理代码 独立于系统代码之外 AOP方式 传统方式 传来传去的Connection / Session对象 采取声明、配置的方式给系统提供事务支持 • 事务管理 • 在业务逻辑层控制事务 • 采取AOP的方式实现声明式事务 事务控制是企业应用系统开发中重要问题 一个业务过程通常需要多次数据库操作
声明式事务 事务管理器 <bean id="myHibTransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> 事务管理器 myHibTransactionManager 代理Bean fwxxBiz 注入 被代理的Bean fwxxBizTarget 被代理的Bean <bean id="fwxxBizTarget" class="com.aptech.jb.biz.impl.FwxxBizImpl"> <property name="fwxxDAO" ref ="fwxxDAO" /> </bean> 代理 原Bean 通知(Advice) • 1.x的方式 • 回顾:Spring中AOP的配置方式 • 配置思路: • 配置代码:
声明式事务 • 配置代码: 代理类 <bean id="fwxxBiz" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager" ref="myHibTransactionManager"/> <property name="target" ref="fwxxBizTarget" /> <property name="transactionAttributes"> <props> <prop key="add*">PROPAGATION_REQUIRED </prop> <prop key="del*">PROPAGATION_REQUIRED </prop> <prop key="update*">PROPAGATION_REQUIRED </prop> <prop key="do*">PROPAGATION_REQUIRED </prop> <prop key="*">PROPAGATION_REQUIRED,readOnly</prop> </props> </property> </bean> 被代理的Bean 声明事务属性 演示示例:使用Spring 1.x配置声明式事务 含义:对add、del、update、do打头的方法要求在事务环境中运行,对其他方法在只读事务中运行
声明式事务 系统中存在多个 业务逻辑对象时 反反复复地定义target和代理bean 反反复复地声明事务 • 1.x的方式 • 存在问题 • 解决办法:定义baseTransProxy 定义为“抽象的” <bean id="baseTransProxy" abstract="true" class="..."> <property name="transactionManager" ref="myHibTransactionManager"/> <property name="transactionAttributes"> <props> ... ... </props> </property> </bean> 没有注入target
声明式事务 • “继承自”baseTransProxy <!-- Target --> <bean id="fwxxBizTarget" class="com.aptech.jb.biz.impl.FwxxBizImpl"> <property name="fwxxDAO" ref="fwxxDAO" /> </bean> <bean id="userBizTarget" class="com.aptech.jb.biz.impl.UserBizImpl"> <property name="userDAO" ref="userDAO" /> </bean> <!-- Biz --> <bean id="fwxxBiz" parent="baseTransProxy"> <property name="target" ref=" fwxxBizTarget" /> </bean> <bean id="userBiz" parent="baseTransProxy"> <property name="target" ref=" userBizTarget" /> </bean> 定义target 定义代理bean
声明式事务 • 2.0的方式 • 添加Spring 2.0到项目 1、添加Spring 2.0的jar包 2、添加Spring 2.0配置文件 <?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/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"> ... </beans>
声明式事务 事务管理器 myHibTransactionManager 事务通知 txAdvice 切面 bizMethods 通知者(advisor) • 2.0的方式 • 优势: • 配置思路: 更简洁易懂 非侵入式
声明式事务 • 2.0的方式 • 配置代码: <tx:advice id="txAdvice" transaction-manager="myHibTransactionManager"> <tx:attributes> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="del*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="do*" propagation="REQUIRED" /> <tx:method name="*" propagation="SUPPORTS" read-only="true" /> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="bizMethods" expression="execution(* com.aptech.jb.biz.*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="bizMethods" /> </aop:config> 声明事务属性 应用于biz层的所有类的所有方法 将事务属性和应用范围关联
总结 • 使用Spring如何简化了Hibernate编码? • Spring如何与Struts集成? • 如何使用Spring实现声明式事务? (1.x的方式,2.x的方式)