本文将介绍 Java™ Platform, Enterprise Edition (Java EE 5) 的一种设计方法,它利用了 Enterprise JavaBeans™ (EJB) 3.0 新的 Java Persistence API (JPA)。JPA 提供了一种标准的对象关系映射解决方案,该解决方案避免了依赖第三方框架(如 Hibernate)。您将看到示例应用程序的详细内容,其中验证了本方法并阐明关键设计决定。
期待已久的下一版本 Java EE 5 即将发布。Java EE 5 许多新功能都包含经过修补的 EJB 架构,其突出特性之一是 JPA。由于具有容器内和容器外持久性选项,JPA 为 J2EE 架构师带来一系列全新设计选择。本文将着重介绍容器内应用程序的设计,此类应用程序依赖 EJB 容器提供企业服务,如事务处理和安全性。
我将使用您熟悉的PetStore应用程序进行测试,以证明JPA的功能以及它如何向传统 J2EE 设计模式发起挑战。本应用程序比较琐碎,所以不提供详尽的实现细节。我将用代码摘录对设计注意事项进行说明。本文假设您熟悉EJB 3.0基本概念和对象关系(OR)映射基本概念。
设计概述
示例PetStore应用程序是基于Web的电子交易应用程序,它实现以下用例:
浏览产品
查找产品
维护账户
维护购物车
创建订单
本应用程序被设计为具有三个主要逻辑层的多层Java EE应用程序:
表示层(并非本文的重点)使用Struts框架。
服务层是一种简单的服务facade,将所有工作委托给其协作者。服务层的目的是分离服务供应与服务实现。
数据访问层是一系列作为无状态会话 bean 实现的粗粒度 Data Access Objects(DAO)。出于持久性的需要,它们都依赖Java持久性实体管理器。
应用程序域模型由EJB 3.0实体bean表示并用于层间的通信。当域对象离开数据访问层时,它与实体管理器脱离。当重新进入数据访问层时,它需要重新连接到实体管理器。
注释似乎是Java 5的一个广泛采用的特性,JPA也不例外。注释可用于指定OR映射 —— 在dW文档和教程中您经常可以看到 —— 而PetStore应用程序出于相同目的使用它们。然而值得一提的是您还能通过映射文件的方式指定OR映射。本文稍后的OR映射 一节将探讨并比较这两种可选方式。
我在Jboss应用服务器中开发并部署PetStore应用程序。我使用商用数据库完成大多数开发工作并将应用程序后端移植到PostgreSQL数据库。
本案例分析的目的之一是符合设计标准,允许高度可测试的实现。如测试一节所见,您能够使用一系列测试技术来测试PetStore应用程序。
PetStore应用程序充分利用了这一事实:它是规则的We应用程序。主要优点是所有层能够运行在相同的JVM中,免除了组件分发的需要。本文的 远程处理一节简要介绍了为应用程序添加远程处理功能的方法。
服务层
服务层被设计为服务facade。它由PetStoreService这一无状态会话bean实现。Bean要完全依靠其协作者来提供Web服务。
因为简化的PetStore要求被限定于从数据库检索数据并把数据存储于数据库,惟一的协作者就是 DAO。真正的应用程序能够调用Web服务,通过RMI/IIOP或资源适配器访问其他应用程序,并生成电子邮件消息等。所有此类型的功能都需要其他协作者支持。
可通过@EJB或@Resource注释注入协作者或通过@PostConstruct方法注入协作者:
清单 1. 使用@EJB注入协作者
1
2 @EJB(beanName = “AccountDao”)
3 AccountDao accountDao; 清单 2. 使用 @PostConstruct 注入协作者
1 MessageSource messageSource;
2 @PostConstruct
3 public void init() {
4 messageSource = new MessageSourceImpl(“exceptions”);
5 }
选择bean实现类的测试策略的主要因素是类完全依赖协作者来提供服务。这意味着类和协作者的交互作用需要被验证。正如您在测试一节看到的,模仿对象方法完全满足该目标。
数据访问层
数据访问层被设计为一系列粗粒度的DAO。DAO 被实现为无状态会话bean,一个bean 对应一个逻辑域:AccountDao、OrderDao 和 ProductDao。
每个bean都要把实体管理器注入到其中:
1 @PersistenceContext(unitName = “manager1”)
2 protected EntityManager em;
这是应用程序中持久性调用类(persistence-aware)最多的层。它广泛使用全新的Enterprise JavaBeans Query Language(EJB QL)。所有持久性相关的行动都在该层发生,例如:
1 profile = (UserProfile) em.createQuery(
2 “from UserProfile up where up.login = :login”).setParameter(
3 “login”, login).getSingleResult();
下面是另一个例子:
1 em.persist(account);
事实上这些类是持久性调用类(persistence-aware),需要一种容器内测试策略,这将在 测试 一节进行描述。
我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。
我原创,你原创,我们的内容世界才会更加精彩!
【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】
微信公众号
TechTarget
官方微博
TechTarget中国
相关推荐
-
内存数据网格提供商一头扎进Java
10年的时间里,应用性能解决方案提供商Alachisoft一直在用NCache(针对N-Tier和网格计算.NET应用的内存计算和数据网格产品)为.NET社区服务。
-
遇到这样一个问题:通过java service wrapper部署应用,wrapper进程占用的内存会一直升高, 直到把内存吃完应用崩溃,但是这个wrapper
遇到这样一个问题:通过java service wrapper部署应用,wrapper进程占用的内存会一直升高 […]
-
Google App Engine for Java 对于目前中国需要学习吗?
-
前无古人后无来者的Java平台
开发人员一直在致力于保持Java的活力,经过20年后,我们感觉从来没有更好的、更令人激动的时刻如同Java社区一样。