第六章Spring与表现层集成回顾Spring是如何集成业务逻辑层的?通过接口——实现类的方式解耦业务层与其它层,主要是用到了控制反转(依赖注入)的办法通过AOP的方法,分离事务、日志等切面操作,让业务逻辑更为清晰Spring是如何集成持久层的?通过模板技术,让具体的持久层实现无须考虑如何获得连接,关闭连接(或指session)等繁琐操作,使程序员专心处理数据CURD操作如果使用了hibernate等持久层框架,DAO就不重要了表现层集成Spring可以与多种表现层技术实现集成,其实与表现层集成以我的理解就是业务逻辑如何被调用的问题,可以分以下几个方面与某种Web框架相集成,如Struts,DWR等与某种java桌面应用程序相集成,如Swing来调用业务逻辑与某种其它语言的应用程序集成,如.net的程序与Struts集成Spring与Struts集成有两种方式:A.使用Struts调用Spring。优点是直接了当,容易理解,缺点是无法使用Spring的依赖注入B.使用Spring来管理Struts中的Action。优点是可以为Action注入业务逻辑实现与Struts集成方法A.使用Struts调用Spring步骤:1.添加Spring提供的ContextLoaderListener和contextConfigLocation属性以指明Spring配置文件的位置,其原理是使用了ListenerServlet在Web工程加载的时候载入了ApplicationContext,并将其放入ServletContext中2.使用Spring提供的WebApplicationContextUtils从ServletContext中获取ApplicationContext3.利用ApplicationContext获取业务逻辑Bean4.使用业务逻辑Bean与Struts集成如果认为以上步骤3中的方式不够简便,可以选择将你的Action继承自Spring提供的XXXActionSupport基类与Struts集成方法B.使用Spring来管理Struts中的Action步骤:1.添加Spring提供的ContextLoaderListener和contextConfigLocation属性2.为所有Action添加类型为业务逻辑接口的属性和相应的Set方法,为注入做准备与Struts集成3.为struts-config.xml添加一个插件plug-inclassName=org.springframework.web.struts.ContextLoaderPlugInset-propertyproperty=contextConfigLocationvalue=/WEB-INF/classes/application_struts.xml,/WEB-INF/classes/application_aspectj.xml//plug-in管理StrutsActions的配置文件管理原有Beans的配置文件与Struts集成4.配置针对strutsaction的配置文件,默认路径放在WEB-INF下,默认名称为action-servlet.xmlbeanname=/transferActionclass=org.yihang.web.TransferActionpropertyname=accountServiceref=accountService//beanbean需要配置name属性,值为Action的路径和以前一样的方式注入业务逻辑bean与Struts集成5.为struts-config.xml配置,注意也可以选择第六步的方式controllerset-propertyproperty=processorClassvalue=org.springframework.web.struts.DelegatingRequestProcessor//controller与Struts集成6.将struts-config.xml中所有action的定义进行修改,注意也可以选择第五步的方式actionpath=/transferActiontype=org.yihang.web.TransferActionname=transferForminput=index.jspforwardname=successpath=/success.jsp/forward/actionactionpath=/transferActiontype=org.springframework.web.struts.DelegatingActionProxyname=transferForminput=index.jspforwardname=successpath=/success.jsp/forward/action替换与Struts集成最终简化办法,在方法B.的第2步后,在struts-config.xml中添加:controllerset-propertyproperty=processorClassvalue=org.springframework.web.struts.AutowiringRequestProcessor//controller使用spring2.0中的新特性,自动“织入”Action所需的业务逻辑Bean默认方式是根据业务逻辑Bean的类型织入的小结Spring和Struts的集成方式就是这些了,没有想象中的复杂,严格按照步骤做一定不会错但话说回来,集成web应用程序中的难点不在于此,而是在于事务及Session的管理SSH中结合难点事务何时开始,何时结束Session何时打开,何时关闭典型的两种做法A.一个request对应多个事务,每个事务用到一个session,也就是我们现在的做法B.一个request对应多个事务,但只用到一个session,这种做法在以前的课程里也讲过,叫做sessionperrequest模式,也可以称之为OpenSessionInViewA.做法的流程分析客户端发送请求,经过Action来调用业务逻辑方法A与业务逻辑方法B方法A开启Session_A,开始事务A,执行之(中间若有拦截器、Advice等,则根据事务属性可能开启新的事务和连接,下同)方法A执行成功,事务A提交,Session_A关闭方法B开启Session_B,开始事务B,执行之方法B执行成功,事务B提交,Session_B关闭最后返回响应B.做法的流程分析客户端发送请求,经过Action来调用业务逻辑方法A与业务逻辑方法B开启Session_A,方法A开始事务A,执行之(中间若有拦截器、Advice等,则根据事务属性可能开启新的事务或加入当前事务,下同)方法A执行成功,事务A提交方法B开始事务B,执行之方法B执行成功,事务B提交返回响应最后Session_A关闭B.做法的优势B.做法的优势在于有效地利用了Hibernate的一级缓存(因为没有重复打开关闭Session)但B.的做法仅能在持久层使用Hibernate或JPA(另外一种几乎和Hibernate完全一样的持久层技术)的情况下使用Spring如何实现做法B.一种做法是使用Spring提供的filter,其原理是使用过滤器Servlet在请求来时打开Session,在响应后关闭Sessionfilterfilter-nameOpenSessionInViewFilter/filter-namefilter-classorg.springframework.orm.hibernate3.support.OpenSessionInViewFilter/filter-class/filterfilter-mappingfilter-nameOpenSessionInViewFilter/filter-nameurl-pattern*.do/url-pattern/filter-mapping与DWR整合相当简单,整合仅仅涉及到远程Bean的生成方式,原来是每次new一个,现在是使用Spring的Bean工厂产生createjavascript=Remotecreator=newscope=requestparamname=classvalue=org.yihang.dwr.Remote/param/createcreatejavascript=Remotecreator=“springparamname=“beanName”value=“spring中Bean的ID//create注意它的去向