Struts2,Spring,Hibernate各自的职责
MVC由Struts2负责实现。
系统的组件都由Spring集中管理。采用依赖注入来管理系统中各组件的依赖关系。避免个组件之间的硬编码组合。提高可扩展性。
持久化解决方案借助Hibernate ORM框架实现,通过Hibenater,以面向对象的方式进行持久化操作。
一.整合Struts2和Spring
Struts2整合Spring需要Spring的插件包struts2-spring-plugin-x-x-x.jar。Struts2内置了该包。
Spring插件通过覆盖Struts2的ObjectFactory来增强核心框架对象的创建。当创建一个对象时,它会使用Struts2配置文件中的class属性去和Spring配置文件中的id属性进行关联。如果能找到,则由Spring创建,否则由Struts2框架自身创建,然后由Spring来装配。
1.为Web应用配置Struts2框架
web.xml配置
<?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <!-- struts2控制器 --> <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>
2.安装Spring插件
为了让Struts2框架与Spring整合起来,还应该在Web应用中增加Struts2的Spring插件。
将Spring插件包struts2-spring-plugin-x-x-x.jar和spring.jar放到WEB-INF/lib目录下。即完成了Spring插件的安装。
该插件中包含了一个struts-plugin.xml文件,该文件包含如下代码行:
<constant name=”struts.objectFactory” value=”spring”>
安装了Spring插件后,系统默认使用Spring容器作为Struts2的装配器,即Action又Spring负责装配其属性。
为保证Spring容器在Web应用时立即完成Spring容器的初始化。
需在web.xml文件中配置Spring监听器:
<linster> <linster-class> org.springframework.web.context.ContextLoaderListener </linster-class> </linster>
经过以上配置,Spring IoC容器会在Web应用启动时初始化,且成为Struts2框架默认的objectFactory。
3.添加Spring核心配置文件
在Web应用的WEB-INF/lib文件夹下配置Spring的核心配置文件。默认文件名为 applicationContext.xml。
ContentLoaderListener初始化Spring容器时,ContextLoaderListener默认加载系统WEB-INF/lib路径下的applicationContext. xml文件,无需增加额外的配置。
Spring 2.5 的核心配置文件
<?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:p="http://www.springframework.org/schema/p" 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-2.5.xsd > ...... </beans>
以上所有步骤完成了Struts2+Spring的基本配置。其他配置均在以上基础上进行。Hibernate的使用由Spring负责管理。
二.实现持久层
1.装配数据源
如果持久层选择用Hibernate,则首先需要装配数据源,数据源由Spring IoC管理。Spring配置片段如下:
<!-- 定义数据源Bean --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <!-- 指定连接数据库驱动 --> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <!-- 指定连接数据库URL --> <property name="url" value=“jdbc:mysql://localhost:3306/数据源名?useUnicode=true&characterEncoding=utf-8"> </property></property> <!-- 指定连接数据库的用户名 --> <property name="username" value="root"></property> <!-- 指定连接数据库的密码 --> <property name="password" value="root"></property> <!-- 指定连接数据库连接池的最大连接数 --> <property name="maxPoolSize " value="20 "></property> <!-- 指定连接数据库连接池的最小连接数 --> <property name="minPoolSize " value="1 "></property> <!-- 指定连接数据库连接池的初始化连接数 --> <property name="initialPoolSize " value="1 "></property> <!-- 指定连接数据库连接池的最大空闲时间--> <property name="maxIdleTime " value="20 "></property> </bean>
2.管理Hiernate SessionFactory
Hibernate的SessionFactory是Hibernate持久化操作的基础对象,SessionFactory是整个数据库经过编辑后的内存镜像。通常对应一个底层数据库。进行Hibernate操作之前必须完成SessionFactory的初始化。
在SSH中,SessionFactory由Spring创建并管理。使用SessionFactory需要数据库连接对象。所以需要把数据源Bean配置给SessionFactory。
以下是在Spring中配置SessionFactory Bean配置片段:
<!-- 定义了Hibernate的SessionFactory--> <bean id="sessionFactory " class="org.springframework.orm.hibernate3.localSessionFactory"> <!-- 装配数据源 --> <property name="dateSource" ref=”dateSource”></property> <property name="mappingResources" > <!--列出所有的Hibernate映射文件--> <list> <value>Test hbm.xml</value> <!-- 其它映射文件 --> </list> </property> <property name="username" value="root"> <props> <prop key=”hibernate.dialect”>org.hibernate.dialect.MySQLDialect</prop> <prop key=”show_sql”>true </prop> <prop key=”hibernate.hbm2ddl.auto”>update</prop> <prop key=”hibernate.jdbc.batch_size”>20</prop> </props> </property> </bean>
通过Spring配置文件中增加如上的配置片段,就可以自动创建Hibernate的SessionFactory。
3.编写实体类(entity)
4.编写映射文件
一旦提供了映射文件Hibernate就可以理解POJO与对应表之间的关系了。
注:由于人们对Hibernate的使用存在误区。在实际开发中,很多情况下都是先有表再有映射对象。但Hibernate使用应该是先建立对象,再有映射表。
根据MVC架构和DAO设计模式,使用Struts2与Spring DAO(Hibernate)模块编写实际代码。
5.DAO
Spring容器管理SessionFactory。Spring对SessionFactory的初始化后,SessionFactoy就一直处于Spring容器管理下。当DAO组件需要进行持久化访问时,Spring容器负责将SessionFactory注入对应的DAO组件。
5.1. DAO接口
通过DAO接口,让系统中的业务逻辑组件面向DAO接口编程,让系统的业务逻辑组件依赖DAO接口,而是依赖于具体的类。从而提高解耦。
面向接口编程是一种良好的习惯,能让系统的个组件之间的依赖提升到接口层次,避免类层次的直接耦合。一旦系统需要重构,需要带动系统中的某个组件时,只要该组件的接口不会改变,依赖该组件上层组件也无需改变,从而提供了更好的复用。
5.2. 实现DAO组件
DAO组件实现了DAO接口,用以完成系统实际的CURD操作。
Spring框架为Hibernate持久化访问的DAO组件提供了HibernateDAOSupport基类, 该基类可以很方便的实现DAO组件。
DAO组件需要继承HibernateDAOSupport类,实现对应的DAO接口。
public class XxxDaoImpl extends HibernateDaoSupport implements XxxDao{
//CURD
}
5.3. 配置DAO组件
用Spring将装配好的SessionFactory注入DAO组件。
DAO组件的父类HibernateDaoSupport中包含了对SessionFactory的setter方法。
配置片段如下:
<!--配置系统DAO组件--> <bean id=” xxxDao” class=”. XxxDaoImpl”> <property name=”sessionFactory” ref=”sessionFactory”> </bean>
经过上面的配置后,系统DAO组件就可以正常运行了。
三.实现业务逻辑层(Biz或Service)
系统的业务逻辑组件所包含的方法取决于系统的业务需求,用户的每个业务请求通常都应该提供一个与之对应的业务逻辑方法
1. 定义业务逻辑组件接口(Biz或Service)
系统的业务逻辑也采用接口和实现分离份额规则,让业务逻辑组件接口定义该接口应该包含的功能(定义方法),而实现类提供该组件的实现。
public interface UserManger{
//…
}
2. 提供业务逻辑组件实现类
依赖底层DAO组件提供的持久化操作,业务逻辑组件可以更加专注于业务逻辑的实现,无需理会底层的持久化实现。
因为系统的业务逻辑组件依赖DAO组件,这种依赖是一种松耦合的依赖,是接口层次的依赖。且以业务逻辑组件不需要直接定位DAO,无需理会DAO组件的实例化过程。Spring容器负责DAO组件的实例化,并把DAO组件实例注入业务逻辑组件,从而实现业务逻辑组件和DAO组件的高层次解耦。
让业务逻辑组件可以接受Spring容器注入DAO组件,必须为业务逻辑组件提供对应的setter方法。
public class UserMangerImpl implements UserManger{
private UserDao userDao;
public void setUser(UserDao userdao){
this. userDao= userDao;
}
//实现UserDao的方法
….
}
3. 异常处理
业务逻辑方法处理底层持久异常的哲学:业务逻辑方法捕捉底层持久层异常,并抛出新异常。
这种异常处理哲学是为了保证持久层异常不会扩散到系统的表现层,从而提高系统安全性;业务逻辑方法抛出一个新异常,新异常里包装的是系统的提示信息。
在实际系统中,业务逻辑方法抛出的应该是用户自定义异常,从而为浏览者提供更丰富的提示信息。除此之外,还应该通过日志记录系统的底层异常,记录底层异常的目的是为系统维护提供更多有用的提示信息。
4. 配置以业务逻辑组件
首先将业务逻辑组件部署在spring容器中。
还应配置该业务逻辑组件所需要的DAO组件。
配置片段如下:
<bean id=”mgr” class=”org.xxxxxx. UserMangerImpl”> <property name=”userDao” ref=”userDao”> </bean>
在Spring配置了业务逻辑组件之后,还需要为业务逻辑方法增加事务控制。因为用户的业务逻辑方法对应用户的一次业务请求。通常,用户的每次业务请求都是逻辑不可分的。因此应该为该方法增加增加事务控制。
四.Action的装配
Action有两种整合方式。
1.通过Spring生成Action。通过Spring注入的形式装配Action的属性。
2.通过Struts2生产Action。默认情况下由Spring按Name的形式自动装配Action的属性。
1. 方法一
Spring生成Action 。好处:Action对象存在与Spring容器中,便于单元测试。
首先通过Spring配置文件来配置Action。
配置片段如下:
<bean id="LoginAction" class="action.LoginAction" scope="protptype"> <property name="loginDao" ref="LoginDao"/> </bean>
<bean>的class属性值为类的全限定名。
通过scope="property"配置。为每个请求创建一个Action实例。
在struts.xml或者等效的Struts2配置文件中配置Action时。
配置片段如下:
<action name="loginAction" class="LoginAction"> <result name="success">/index.jsp</result> </action>
注意:Spring配置文件的<bean>元素的class属性值与struts.xml的<action>元素的id或name属性值需要一致。
2. 方法二
利用struts-spring-plugin插件自动初始化Action。只需要在struts.xml中配置action即可,不需要在Spring配置文件中配置Action。
Spring容器为Struts2的Action依赖注入业务逻辑组件时,默认采用byName的自动装配策略。在这种自动装配策略下所有Action无需显示配置依赖的业务逻辑组件,假如Action需要一个名为”abc”的Bean,只要为该Action提供一个setAbc的setter方法。Spring可以根据名字来将abc Bean依赖注入该Action组件。
这种方式没有指定Action的作用域。Spring插件为每个请求创建一个Action实例。
当Action组件获得了业务逻辑组件引用后,就可以调用业务逻辑组件的业务逻辑方法来处理用户请求。
默认情况下,插件使用by name的方式装配,通过增加Struts2常量来修改匹配方式:设置方式:struts.objectFactory.spring.autoWire = typeName。
typeName的值如下:
name:相当于spring配置的autowrie="byName"(默认)
type:相当于spring配置的autowrie="byType"
auto:相当于spring 配置的autowrie="autodetect"
constructor: 相当于spring配置的autowrie="constructor"
附:
http://zhangyq-qq.iteye.com/blog/1764723
http://wenku.baidu.com/view/d4e63000763231126edb1135.html
http://wenku.baidu.com/view/d06d51c60c22590102029d76.html
http://blog.csdn.net/sunjunlong/article/details/7692559
http://yiwentiger.iteye.com/blog/1586137