Spring 3.1, Struts 2, Hibernate 3.5集成

  今天终于把SSH集成出来了!但回首这过程,好像相当漫长。从对每个框架的基本知识学习,到对测试框架进行HelloWorld的测试,再到Spring与Hibernate的集成,最后再把Struts集成上去。这过程很美好,消退了内心的浮躁,认识到了自己的肤浅,也见识到了许多优秀的开源库。

  首先是基础知识的学习。极力推荐这几本书:《hibernate实战》(Java Persistence with Hibernate, Gavin King 著),《Struts 2 权威指南》(李刚),《spring揭秘》(王福强)。

  对于单个框架的测试,比较简单。在Struts 2中,有5个是必须要引入的:commons-logging-1.1.1.jar,freemarker-2.3.18.jar,ognl-3.0.3.jar,struts2-core-2.3.1.1.jar,xwork-core-2.3.1.1.jar。另外,还需要javassist-3.7.ga.jar,commons-io-2.1.jar,commons-lang-2.6.jar,commons-fileupload-1.2.2.jar 这四个包。在Hibernate中,需要引入的包有:hibernate3.jar,antlr-2.7.6.jar,commons-collections-3.1.jar,dom4j-1.6.1.jar,javassist-3.9.0.GA.jar,slf4j-api-1.5.8.jar以及数据库连接包。在Spring中,org.springframework.core-3.1.1.jar, org.springframework.beans-3.1.1.jar, org.springframework.context-3.1.1.jar, org.springframework.asm-3.1.1.jar, org.springframework.expression-3.1.1.jar, commons-logging-VERSION.jar。

 

Spring与Hibernate集成

  首先,这过程需要添加一些额外的jar包,包括:org.springframework.jdbc-3.1.1.jar, org.springframework.orm-3.1.1.jar,org.springframework.transaction-3.1.1.jar,org.springframework.aop-3.1.1.jar以及五个需要另外下载的commons-dbcp-1.4.jar,commons-pool-1.6.jar,aopalliance-1.0.jar,aopalliance-alpha1.jar和aspectjweaver-1.5.2.jar。

  然后配置文件。在这个时候,可以不用hibernate.cfg.xml(Hibernate的配置文件)文件,但实体类映射文件还是需要的(xxx.hbm.xml)。而原来Hibernate配置文件的信息可以配置到spring配置文件记录的数据源中。

    <!-- 配置数据源 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName">
            <value>com.mysql.jdbc.Driver</value>
        </property>
        <property name="url">
            <value>jdbc:mysql://localhost/dbname</value>
        </property>
        <property name="username">
            <value>username</value>
        </property>
        <property name="password">
            <value>password</value>
        </property>
    </bean>

接下来是SessionFactory的配置,并且实体类映射文件以及Hibernate其他属性的映射也在这里配置

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <!-- <property name="configLocation"> <value>classpath:hibernate.cfg.xml</value>
            </property> -->
        <property name="dataSource">
            <ref bean="dataSource" />
        </property>

   <!-- 映射文件 -->
        <property name="mappingResources">
            <list>
                <value>entities/Admin.hbm.xml</value>
                <value>entities/UserToMessage.hbm.xml</value>
                <value>entities/Family.hbm.xml</value>
                <value>entities/Message.hbm.xml</value>
                <value>entities/User.hbm.xml</value>
            </list>
        </property>

  <!-- Hibernate的其他属性 -->
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.jdbc.batch_size">10</prop>
                <prop key="hibernate.current_session_context_class">thread</prop>
            </props>
        </property>
    </bean>

然后是事务管理器

    <!-- 配置事务管理器 -->
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory">
            <ref bean="sessionFactory" />
        </property>
    </bean>

接着是事务的传播特性,这里name属性将会与类函数名匹配,允许使用正则表达式表示,如add*指函数名以add开头的函数

    <!-- 配置事务的传播特性 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="add*" propagation="REQUIRED" />
            <tx:method name="del*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" />
            <tx:method name="*" propagation="SUPPORTS" read-only="true" />
        </tx:attributes>
    </tx:advice>

最后是切面的声明,这里指定哪些类的哪些方法参与事务,下例指mysql.spring.services包下所有类的所有方法,并且使用上面指定的事务的传播特性。

    <aop:config>
        <aop:pointcut expression="execution(* mysql.spring.services.*.*(..))"
            id="allServiceMethod" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="allServiceMethod" />
    </aop:config>

这时,Spring对Hibernate的集成基本完成。接下来,只需要为你的数据库操作类进行配置就可以了,比如:

    <bean id="serviceTemplate" abstract="true">
        <property name="sessionFactory">
            <ref bean="sessionFactory"/>
        </property>
    </bean>
    
    <bean id="adminService" class="mysql.spring.services.AdminService"
    parent="serviceTemplate">
    
    </bean>

我们可以先定义一个bean模板,但这个模板没有对应的类,所以需要abstract属性来指定其不需要实例化。mysql.spring.services.AdminService类的bean配置就可以通过parent属性来获得模板bean的属性。在上例中,mysql.spring.services.AdminService类需要用到SessionFactory,这里使用了setter注入方法进行注入。

在此时,Spring和Hibernate的合体已经完成。但在某些情况下,会出现一些特殊的异常。比如,出现Unable to locate Spring NamespaceHandler for XML schema namespace [http://cxf.apache.org/jaxws]这样的异常。这时,你需要去看看用到的org.springframework.*.jar包下的META-INF目录,看它是否有spring.handler; spring.tooling; spring.schemas这三个文件(基本上都有的),补上正确的文件就可以修复这种异常。

 

Struts 2的加入

  引入Struts 2 也需要带入一些包:org.springframework.web-3.1.1.jar和struts2-spring-plugin-2.3.1.2.jar。首先编写好需要的action类,并且在struts.xml文件中配置好。接下来,就要修改web.xml文件,struts.xml文件以及Spring的配置文件了。

  在web.xml文件中,我们需要加上<context-param>标签来指定Spring配置文件的路径,这里指的是以applicationContext开头的配置文件在Java类目录下。还有加上一个监听器,这样就可以在服务器(Tomcat)启动时就产生一个BeanFactory实例。

<context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath*:applicationContext-*.xml</param-value>
  </context-param>
  <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  在Spring的配置文件中,定义好action类,其中adminModel只是actions.AddAdminAction所依赖的一个类

    <bean id="addAdminAction" class="actions.AddAdminAction" scope="prototype">
        <property name="adminModel">
            <ref bean="adminModel"/>
        </property>
    </bean>

  在struts.xml文件中,有三个地方需要修改:1. 加上一个<constant>标签;2. 修改action的class属性,不再是指定action类,而是要与Spring配置文件中对应bean的id属性相同;3. 修改action的name属性,它必须要与前台的action属性相同

    <constant name="struts.objectFactory" value="spring" />

        <action name="addAdmin" class="addAdminAction">
            <result>/lrbanner.jsp</result>
        </action>

  比如有这么一个jsp文件:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
  <form action="addAdmin" method="post">

    name: <input type="text" id="name" name="name" />

    <input type="submit" value="submit" />

  </form>
</body>
</html>

  到这里,一个简单的SSH框架已经建好。这是本人第一次接触这框架,有什么地方不对希望大家提出来。总的来说,觉得Spring可以一层一层地把东西都配置进去,hibernate的终点是SessionFactory,而最终的终点是BeanFactory。还有,就是Java精妙的反射机制,cglib也相当给力。

posted @ 2012-05-09 22:10  move1977  阅读(359)  评论(0)    收藏  举报