springhibernate集成:集成 Flex Spring Hibernate 构建应用程序

  RIA(Rich Internet Application)—— 富 Internet 应用以其良好客户体验得到越来越广泛应用银行电信等领域已有诸多成功案例Adobe Flex 是最具有代表性基于 Flash RIA 技术通过对 Flex 以及当前流行 Spring、Hibernate J2EE 开源框架进行集成使客户既能获得到用户体验又能获得 J2EE 应用高稳定性高可扩展性和可移植性从某种意义上来说RIA 是未来 Web 应用发展方向作为本文读者您应该非常熟悉 J2EE 开发、Spring、Hibernate 框架并且对 Flex、ActionScript 有了解

  引言

  RIA(Rich Internet Application)—— 富 Internet 应用是种融入了传统桌面应用系统功能和特性 Web 应用系统RIA 结合了桌面应用反应快、交互性强优点和传统 Web 应用易于部署和维护特性从而为用户提供了更加健壮表现力更加丰富 Web 应用Adobe Flex 是当前流行基于 Flash RIA 开源框架您可以利用 Flex 基于 XML MXML、ActionScript 以及 SWC 文件(Flex 组件库)创建包含丰富图表、3D 特效、动画、音频以及视频用户界面而所有 Flex 组件将会由 Flex 编译器编译生成 SWF 2进制文件在 Flash Player 中运行

  Spring 是个轻量级 J2EE 开源应用框架Spring 基于两大核心特性控制反转(Inversion of ControlIOC)和面向方面编程(Aspect-Oriented ProgrammingAOP)插件式架构降低了应用组件的间耦合性借助于 XML 配置文件Spring 容器可以轻松地帮助您管理应用组件以及它们的间依赖性同时 Spring 还提供事务管理框架、DAO 支持、支持主流 O/R Mapping 框架集成、支持各种标准 J2EE 组件技术集成(JavaMail/EJB/JMS/Web Service 等)、支持各种视图技术(Web 视图和非 Web 视图)集成

  Hibernate 是 Java 平台上种成熟、全功能 O/R Mapping(对象 / 关系映射)开源框架Hibernate 在分层 J2EE 架构中位于数据持久化层它封装了所有数据访问细节使业务逻辑层可以专注于实现业务逻辑Hibernate 使用 O/R Mapping 将对象模型中对象映射到基于 SQL 关系数据模型中去通过使用 HQL(Hiberante Query Language)实现 Java 对象持久化使得您可以应用面向对象思维方式操纵数据库另外Hibernate O/R Mapping 还提供延迟加载、分布式缓存Cache等高级特性这样有利于缩短开发周期和降低开发成本

  有关举例

  本文样例是比较流行在线宠物商店应用场景分为两个部分:

  demo_client:Flex 项目主要由 Flex 实现用户界面生成和对用户动作响应处理

  demo_central:Java Web 项目主要由 Spring 实现业务逻辑、由 Hibernate 实现数据库读写访问控制以及由 BlazeDS 提供 Flex 访问远程对象接口在本文中 Spring、BlazeDS 和 Hibernate 所依赖 Jar 包均拷贝到 demo_central 项目 WebContent/WEB-INF/lib 目录下部署到 Tomcat 上

  开发环境

  Eclipse 3.3.1.1

  Web Tools Platform(WTP) for eclipse

  Adobe Flex Builder 3

  Tomcat v6.0

  MySQL v5.1

  集成 Flex 和 Spring

  如何将 Flex 和 Spring 进行集成使 Flex 前端能够和 Java EE 后端进行通信? Flex 通过远程思路方法和实时通信技术实现异步通信Flex 通信协议主要有 3种:HttpService、WebService 和 RemoteObjectRomoteObject 协议作为 Flex 提供最快通信方式通过集成 BlazeDS利用 AMF(Action Message Format) 2进制协议使得 Flex 前端能轻松和 Java EE 后端进行数据交互它是 Flex 集成 Spring 首选通信协议

  BlazeDS

  BlazeDS 是 Adobe Live-Cycle Service 免费开源版本它使用 AMF 2进制协议通过 AMF 管道构建了 Flex 和 Spring 进行数据通信桥梁BlazeDS 可以实现 Flex 对 Java 对象远程BlazeDS 可以部署运行在大多数 Web 应用服务器上如 Tomcat、Websphere、JBoss 以及 Weblogic在本文中我们将 BlazeDS 部署在 Tomcat 上BlazeDS 所依赖 jar 包如清单 1 所示:


清单 1. BlazeDS 依赖 Jar 包
 flex-messaging-common.jar 
 flex-messaging-core.jar 
 flex-messaging-opt.jar 
 flex-messaging-proxy.jar 
 flex-messaging-remoting.jar 
 backport-util-concurrent.jar 
 cfgatewayadapter.jar 
 commons-httpclient-3.0.1.jar 
 commons-codec-1.3.jar 
 commons-logging.jar 
 concurrent.jar 
 xalan.jar 


  在 web.xml 部署描述符文件中添加 HttpFlexSessionHttpFlexSession 是 BlazeDS 个监听器负责监听 Flex 远程请求


清单 2. 定义 HttpFlexSession
 <listener> 
   <listener->flex.messaging.HttpFlexSession</listener-> 
 </listener> 


  SBI 和 Spring

  现在我们需要引入 Spring BlazeDS Integration(SBI)SBI 项目是 SpringSource 发布开源项目

  它是目前比较成熟用于集成 Flex 和 Spring 思路方法SBI 和 Spring 所依赖 Jar 包如清单 3 所示:


清单 3. SBI 和 Spring 依赖 Jar 包
 org.springframework.flex-1.0.0.M2.jar(SBI) 
 spring-beans.jar 
 spring-context.jar 
 spring-context-support.jar 
 spring-core.jar 
 spring-tx.jar 
 spring-webmvc.jar 
 spring.jar 


  MessageBroker 是 SBI 个组件职责是处理 Flex 远程请求MessageBroker 由 Spring 容器进行管理而不是由 BlazeDS在 Web.xml 中添加 DispatcherServlet 允许 Spring 自行管理 MessageBroker


清单 4. DispatcherServlet 配置
 <servlet> 
   <servlet-name>Spring MVC Dispatcher Servlet</servlet-name> 
   <servlet-> 
     org.springframework.web.servlet.DispatcherServlet 
   </servlet-> 
   <init-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>/WEB-INF/applicationContext.xml</param-value> 
   </init-param> 
   <load-on-startup>1</load-on-startup> 
 </servlet> 


  接下来需要在 BlazeDS 主配置文件 services-config.xml 中添加个管道定义以支持 DispatcherServlet 对 Flex 请求映射


清单 5. 在 services-config.xml 中定义管道
 <channel-definition id="my-amf" ="mx.messaging.channels.AMFChannel"> 
   <endpo url= 
     "http://{server.name}:{server.port}/{context.root} 
     /spring/messagebroker/amf" 
     ="flex.messaging.endpos.AMFEndpo"/> 
 </channel-definition> 


  在 Spring 配置文件 applicationContext.xml 中引入 HandlerMapping 通过 MessageBrokerHandlerAdapter 将所有 Servlet 请求 URL 映射到由 Spring 容器管理 MessageBroker

  因此需要定义如下两个 Bean:


清单 6. 定义 HandlerMapping 实现 Servlet 请求映射
 <bean ="org.springframework.web.servlet. 
        handler.SimpleUrlHandlerMapping"> 
   <property name="mappings"> 
     <value> 
        /*=springManagedMessageBroker 
     </value> 
   </property> 
 </bean> 
 <bean ="org.springframework.flex.messaging.servlet. 
        MessageBrokerHandlerAdapter"/> 


  最后将定义 MessageBrokerFactoryBean 工厂 Bean 用于创建 MessageBroker并为您 Service Bean 提供绑定服务


清单 7. 定义 MessageBrokerFactoryBean
 <bean id="springManagedMessageBroker"   
   ="org.springframework.flex. 
       messaging.MessageBrokerFactoryBean" /> 


  在完成上述配置后启动 Tomcat 将发布 demo_central然后在浏览器中输入 http://localhost:8080/demo_central/spring/messagebroker/amf 并回车浏览器就会显示个空白 Web 页面这时我们就成功地对 Flex 和 Spring 进行了集成

  集成 Spring 和 Hibernate

  通过集成 Spring 和 Hibernate 3您能在 Spring 容器管理下通过 O/R Mapping 进行面向对象数据持久化在本文中我们使用 MySQL 数据库Hibernate 所需要 Jar 包如清单 8 所示:


清单 8. Hibernate 依赖 Jar 包
 hibernate3.jar 
 hibernate-annotations.jar 
 hibernate-commons-annotations.jar 
 mysql-connector-java-5.0.8-bin.jar 


  首先定义 Hibernate.properties 创建 Hibernate 参数设置以及数据库连接信息


清单 9. Hibernate.properties
 jdbc.driverClassName=com.mysql.jdbc.Driver 
 jdbc.url=jdbc:mysql://localhost/pet_store 
 jdbc.username=username 
 jdbc.password=password 
 hibernate.show_sql=true 
 hibernate.format_sql=true 
 hibernate.transaction.factory_= 
 org.hibernate.transaction.JDBCTransactionFactory 
 hibernate.dialect=org.hibernate.dialect.MySQLDialect 
 hibernate.c3p0.min_size=5 
 hibernate.c3p0.max_size=20 
 hibernate.c3p0.timeout=1800 
 hibernate.c3p0.max_statements=50 


  创建 HibernateContext.xml 配置文件对 Hibernate 进行配置并将其纳入 Spring 容器管理在这里我们使用基于 Java 5 注解 Hibernate 注解(Hibernate Annotations)实现对关系型数据库映射以代替传统 hbm.xml 映射文件这样不仅可以大大简化 Hibernate 映射配置而且利用 Java 元数据可以提高性能声明 SessionFactory 为 AnnotationSessionFactoryBean 将注解应用于 Hibernate 实体类中声明 RequiredAnnotationBeanPostProcessor 作为 BeanPostProcessor 实现它将强制 Bean 声明那些被 Spring 注解设置成 Required 属性否则将无法通过 XML 验证最后定义个类型为 HibernateTransactionManager txManager Bean并将它注入到 <tx:annotation-driven> transaction-manager 属性这样就能够在 Spring Bean 中应用 Hibernate 事务注解了HibernateContext.xml 如清单 10 所示:


清单 10. HibernateContext.xml
 <beans 
   xmlns="http://www.springframework.org/schema/beans" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   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" 
   default-lazy-init="true"> 
   
   <bean id="propertyConfigurer" 
    ="org.springframework.beans.factory. 
       config.PropertyPlaceholderConfigurer"> 
     <property name="location"> 
        <value> 
          WEB-INF/hibernate.properties 
        </value> 
     </property> 
  </bean> 
  
 
  <bean id="sessionFactory" 
     ="org.springframework.orm.hibernate3. 
       annotation.AnnotationSessionFactoryBean"> 
  <property name="annotatedClasses"> 
     <list> 
       <value>com.psdemo.core.do.Client</value> 
       <value>com.psdemo.core.do.Product</value> 
     </list> 
  </property> 
 
  <property name="hibernateProperties"> 
     <props> 
       <prop key="hibernate.show_sql"> 
         ${hibernate.show_sql} 
       </prop> 
       <prop key="hibernate.format_sql"> 
         ${hibernate.format_sql} 
       </prop> 
       ...... 
       <prop key="hibernate.connection.driver_"> 
         ${jdbc.driverClassName} 
       </prop> 
       <prop key="hibernate.connection.url"> 
         ${jdbc.url} 
       </prop> 
       <prop key="hibernate.connection.username"> 
         ${jdbc.username} 
       </prop> 
       <prop key="hibernate.connection.password"> 
         ${jdbc.password} 
       </prop> 
     </props> 
  </property> 
  </bean> 
 
  <bean ="org.springframework.beans.factory. 
     annotation.RequiredAnnotationBeanPostProcessor"/> 
 
  <bean id="txManager" 
     ="org.springframework.orm. 
     hibernate3.HibernateTransactionManager"> 
     <property name="sessionFactory"> 
       <ref local="sessionFactory"/> 
     </property> 
  </bean> 
 
  <tx:annotation-driven transaction-manager="txManager"/> 


清单 11. Hiberante 实体类 Client.java
 package com.psdemo.core.do; 
 import java.io.Serializable; 
 import javax.persistence.*; 
 @Entity 
 @Table(name="client") 
 
 public  Client implements Serializable{ 
   private  final long serialVersionUID = 2L; 
 
   @Id 
   @Column(name="username") 
   private String username; 
 
   @Column(name="password") 
   private String password; 
 
   public String getUsername{ 
      username; 
   } 
 
   public void Username(String username){ 
     this.username = username; 
   } 
 
   public String getPassword{ 
      password; 
   } 
 
   public void Password(String password){ 
     this.password = password; 
   } 
 } 


  最后我们需要在 web.xml 部署描述符 contextConfigLocation 参数中装入 HibernateContext.xml 配置文件这时我们就成功完成了 Spring 和 Hibernate 集成通过 Spring 容器管理 HibernateHibernate 实现数据持久化管理

  Java EE 服务器端

  通过 Spring 对 Flex 以及 Hibernate 集成现在我们就可以在服务器端声明和定义业务逻辑对象和数据访问对象了

  在 hibernateContext.xml 定义数据访问对象 DAO注入 SessionFactory


清单 12. 在 hibernateContext 定义 DAO
 <bean id="clientDao" 
   ="com.psdemo.core.dao.hibernate.ClientDaoImpl"> 
   <property name="sessionFactory" ref="sessionFactory"/> 
 </bean> 


清单 13. ClientDaoImpl.java
 public  ClientDaoImpl extends HibernateDaoSupport 
              implements ClientDao { 
   @Override 
   public Client authenticateUser(String userName, 
                  String password){ 
     String paramNames =  String{"userName", "password"}; 
     String values =  String{userName, password}; 
     List results = this.getHibernateTemplate. 
       findByNamedParam("from Client as c 
       where c.username=:userName 
       and c.password=:password", 
       paramNames, values); 
     Iterator iter = results.iterator; 
     (iter.hasNext){ 
         (Client)iter.next; 
     }{ 
         null; 
     }  
   } 
 } 


  在 applicationContext.xml 中定义 Service 并开放其 BlazeDS 远程服务注入 DAO


清单 14. 定义 Service 并开放其 Flex 远程服务
 <bean id="clientservice" 
   ="org.springframework.flex.messaging. 
      remoting.FlexRemotingServiceExporter"> 
   <property name="messageBroker" 
        ref="springManagedMessageBroker"/> 
   <property name="service" ref="clientService"/> 
 </bean> 
 
 <bean id="clientService" 
   ="com.psdemo.core.services.ClientServiceImpl"> 
   <property name="clientDao"> 
     <ref bean="clientDao"/> 
   </property> 
 </bean> 


  Flex 客户端

  Cairngorm

  Cairngorm 是 Adobe 设计个针对 Flex 开发者构建 RIA 应用轻量级开源框架Cairngorm 通过设计模式实现了 MVC(Model-View-Controller)微型架构使得开发人员可以交付具有可重用性、可维护性中大型 RIA 应用在本文中我们使用 Cairngorm2.2.1为了引入 Cairngorm需要把它库文件 Cairngorm.swc 拷贝到 Flex 项目 libs 目录中


图 1. 将 cairngorm.swc 添加到 Flex 项目库


  Cairngorm 是个事件驱动框架其编程模型主要由以下几个组件构成:

  值对象(Value Object):值对象是个映射 Spring 实体类对象 ActionScript 类对象它将从 Server 端传输数据提供给可视化视图对象


清单 15. 值对象 ClientVO.as
 package com.psdemo.client.model.vo 
 { 
   [Bindable] 
 
   [RemoteClass(alias="com.psdemo.core.do.Client")] 
   public  ClientVO 
   { 
     public var username:String; 
     public var password:String; 
   } 
 } 


  前端控制器(Front Controller):前端控制器负责绑定由用户触发事件并将事件映射到相应命令


清单 16. 前端控制器 PMainController.as
 public  PMainController extends FrontController 
 { 
   public function PController 
   { 
     addCommand(AuthenticateUserEvent.EVENT_AUTH_USER, 
           AuthenticateUserCommand); 
     addCommand(GetProductsEvent.EVENT_GET_PRODUCTS, 
           GetProductsCommand); 
   } 
 } 


  业务代理(Business delegate):利用 Responder 处理由服务器端返回数据


清单 17. 业务代理 ClientDelegate.as
 public  ClientDelegate 
 { 
   private var responder:IResponder; 
   private var service:Object; 
  
   public function ClientDelegate(responder:IResponder) 
   { 
     this.service = ServiceLocator.getInstance. 
             getService("clientservice"); 
  this.responder = responder; 
   } 
  
   public function authenticateUser(userName:String, password:String) 
   { 
     var call:AsyncToken = service.authenticateUser(userName, password); 
  call.addResponder(responder); 
   } 
  
   public function addClient(clientVO:ClientVO):void 
   { 
     var call:AsyncToken = service.addClient(clientVO); 
     call.addResponder(responder); 
   } 
 } 


Tags:  springhibernate事务 springhibernate配置 springhibernate整合 springhibernate集成

延伸阅读

最新评论

发表评论