十大(或多或少)J2EE最佳实践

提供了本文的更新版本: 最佳Java EE最佳实践

在过去的五年中,已经有很多关于J2EE最佳实践的文章。 现在可能有10本书或更多书籍,以及数十篇文章,它们提供了有关如何编写J2EE应用程序的见解。 实际上,有太多的资源(通常带有相互矛盾的建议),迷宫般的导航已成为采用J2EE本身的障碍。 为了为进入这种迷宫的客户提供一些简单的指导,我们着手编制以下“十大”清单,列出我们认为是J2EE最重要的最佳实践。 不幸的是,10不足以捕获需要说的所有内容,尤其是当您将Web服务开发视为J2EE的一部分时。 因此,为了纪念J2EE的增长,我们决定将“前10名”列表改为“前12名”列表。

因此,事不宜迟,J2EE十大最佳实践(+ 2) ...

最佳做法

  1. 始终使用MVC。
  2. 在每一层应用自动化的单元测试和测试工具。
  3. 开发规格,而不是应用服务器。
  4. 从第一天开始计划使用J2EE安全性。
  5. 建立您所知道的。
  6. 每当使用EJB组件时,请始终使用Session Facades。
  7. 使用无状态会话Bean而不是有状态会话Bean。
  8. 使用容器管理的事务。
  9. 首选JSP作为表示技术的首选。
  10. 使用HttpSessions时,仅存储当前业务交易所需的状态,不能存储更多状态。
  11. 在WebSphere中,打开动态缓存并使用WebSphere servlet缓存机制。
  12. 由于程序员的生产力优势,首选CMP Entity bean作为O / R映射的首选解决方案。

1.始终使用MVC。

将业务逻辑(Java Bean和EJB组件)与表示形式(JSP,XML / XSLT)的控制器逻辑(Servlet / Struts操作)完全分开。 良好的分层可以掩盖大量的罪过。


这种做法对于成功采用J2EE至关重要,因此对于#1插槽没有竞争。 模型视图控制器(MVC)是设计好的J2EE应用程序的基础。 它只是将程序的工作分为以下几个部分:

  1. 负责业务逻辑的人员(模型-通常使用Enterprise Java™Bean或普通的旧Java对象实现)。
  2. 负责表示用户界面的人(视图-通常用JSP和标记库实现,但有时用XML和XSLT实现)。
  3. 负责应用程序导航的人员(控制器-通常用Java Servlet或诸如Struts控制器的关联类实现)。

关于J2EE,该主题有很多出色的评论; 特别是,我们将感兴趣的读者定向到[Fowler]或[Brown](请参阅参考资料 )进行全面,深入的报道。

如果不遵循基本的MVC体系结构,可能会出现许多问题。 大多数问题是由于在架构的“视图”部分中放置过多内容而引起的。 在小型应用程序中,使用JSP标记库执行数据库访问或在JSP中执行应用程序流控制之类的做法在小规模应用程序中相对常见,但是随着JSP变得越来越难以维护和调试,这些做法可能会在以后的开发中引起问题。

同样,我们经常看到视图层构造向业务逻辑的迁移。 例如,一个常见的问题是将用于视图构建的XML解析技术推入业务层。 业务层应该对业务对象进行操作,而不是对与视图绑定的特定数据表示形式进行操作。

但是,仅具有适当的组件并不能使您的应用程序正确分层。 找到具有所有三个servlet,JSP和EJB组件的应用程序是很普遍的,其中大多数业务逻辑是在servlet层中完成的,或者应用程序导航是在JSP中处理的。 您必须严格执行代码审查和重构,以确保仅在模型层中处理业务逻辑,应用程序导航仅是控制器层的工作范围,并且您的视图仅涉及将模型对象呈现为适当HTML和Javascript。 。

2.在每一层应用自动化的单元测试和测试工具。

不要只是测试您的GUI。 分层测试使调试和维护变得非常简单。


目前已在过去几年中为自称敏捷新的轻量级方法已经相当换血的方法学领域(如SCRUM [Schwaber的]和极限编程[Beck1在相关主题 )变得更加普遍。 几乎所有这些方法的标志之一是,它们提倡使用自动化测试工具,以帮助开发人员减少回归测试的时间,并避免因回归测试不足而导致的错误,从而提高程序员的工作效率。 实际上,一种称为“测试优先开发” [Beck2]的做法通过提倡在实际代码本身的开发之前编写单元测试来使这种做法更进一步。 但是,在测试代码之前,需要将其隔离为可测试的片段。 很难测试“大泥球”,因为它没有执行单个易于识别的功能。 如果代码的每个段都执行多项操作,则很难测试每一位的正确性。

MVC体系结构(以及MVC的J2EE实现)的优点之一是,元素的组件化使得有可能(实际上相对容易)分段测试应用程序。 因此,您可以轻松编写测试以在其余代码库之外分别测试Entity Bean,Session Bean和JSP。 有许多用于J2EE测试的框架和工具使此过程更加容易。 例如,Junit是由junit.org开发的开源工具,而Cactus是Apache联盟的开源项目,对测试J2EE组件都非常有用。 [Hightower]详细讨论了这些工具在J2EE中的使用。

尽管有很多有关深度测试应用程序的重要信息,但我们仍然看到许多项目认为,如果他们测试GUI(可能是基于Web的GUI或独立的Java应用程序),那么他们已经对整个应用程序进行了全面测试。 GUI测试很少。 有几个原因。 首先,使用GUI测试,很难测试通过系统的每条路径。 GUI只是影响系统的一种方式。 可能有后台作业,脚本和各种其他访问点也需要进行测试。 但是,它们通常没有GUI。 其次,在GUI级别上的测试非常粗糙。 它在系统的宏级别上测试系统的行为。 这意味着,如果发现问题,则必须考虑整个子系统,从而使发现已确定的错误变得困难。 第三,GUI测试通常不能很好地完成,直到完全定义了GUI的开发周期的后期。 这意味着直到很晚才可以系统地发现潜在的错误。 第四,一般的开发人员可能无法使用自动GUI测试工具。 因此,当开发人员进行更改时,该开发人员没有简单的方法来重新测试受影响的子系统。 这实际上不利于进行良好的测试。 如果开发人员可以访问自动代码级单元测试,则开发人员可以轻松地运行它们以确保所做的更改不会破坏现有功能。 最后,如果完成了自动构建,则向自动构建过程添加自动化单元测试套件相当容易。 这样,可以定期(通常每晚)重建该系统,并在很少的人工干预下进行回归测试。

另外,我们必须强调,使用EJB和Web服务进行的基于组件的分布式开发绝对必要地测试您的单个组件。 如果没有要测试的“ GUI”,则必须退回到较低级别的测试。 最好以这种方式开始,当需要将应用程序的一部分作为分布式组件或Web服务公开时,不必麻烦您进行流程的改进以包括那些测试。

总之,通过使用自动化的单元测试,可以更快地发现缺陷,更易于发现缺陷,可以使测试更加系统化,从而提高了总体质量。

3.开发规格,而不是应用服务器。

认真了解规格并在仔细考虑后才偏离规格。 仅仅因为您可以做某事并不意味着您应该做。


尝试在J2EE允许您执行的操作的边缘进行操作很容易使您感到悲伤。 我们发现开发人员尝试了一些他们认为比J2EE允许的工作“稍微好一点”的工作,从而陷入困境,却发现这会导致性能或迁移(从一个供应商到另一个供应商,或更常见的是从版本)。 实际上,这是迁移的问题,因此[Beaton]将此原则称为迁移工作的主要最佳实践。

在很多地方,没有采取最直接的方法肯定会引起问题。 如今,开发人员通常通过使用JAAS模块来接管J2EE安全性,而不是依靠内置的符合规范的应用服务器机制来进行身份验证和授权。 谨防超出J2EE规范提供的身份验证机制。 这可能是安全漏洞和供应商兼容性问题的主要来源。 同样,依赖于servlet和EJB规范提供的授权机制,并且在需要超越它们的地方,请确保使用规范的API(例如getCallerPrincipal())作为实现的基础。 这样,您将能够利用供应商提供的强大安全基础结构,并在业务需求需要时支持更复杂的授权规则。

其他常见问题包括使用未绑定到J2EE规范中的持久性机制(使事务管理变得困难),依赖于不适当的J2SE工具(例如J2EE程序中的线程或单例),以及“滚动自己的”解决方案以进行程序间通信而不是停留在JCA,JMS或Web服务等受支持的机制之内。 从一台符合J2EE的服务器迁移到另一台服务器,甚至迁移到同一服务器的新版本时,这种设计选择都不会造成困难。 在J2EE之外使用元素通常会引起细微的可移植性问题。 您唯一一次应该偏离规范的情况是,存在明显的问题无法在规范内解决。 例如,在引入EJB 2.1之前,安排定时业务逻辑的执行是一个问题。 在这种情况下,我们建议您在可能的情况下使用供应商提供的解决方案(例如WebSphere®Application Server Enterprise中的Scheduler工具),或者在不可用的情况下使用第三方工具。 这样,维护和迁移到更高规范版本就成为供应商的问题,而不是您自己的问题。

最后,过早采用新技术时要小心。 在将技术集成到其余的J2EE规范或供应商的产品中之前,过分地采用该技术通常会带来灾难。 支持至关重要-如果您的供应商不直接支持JSR中提出但尚未被J2EE接受的特定技术,则您可能不应该追求它。 毕竟,除了极少数的例外,我们大多数人都在解决业务问题,而不是为了纯粹的乐趣而发展技术。

4.从第一天开始计划使用J2EE安全性。

打开WebSphere安全性。 将所有EJB和URL锁定到至少所有经过身份验证的用户。 甚至不问-只需这样做。


我们一直感到惊讶,我们最初与之打交道的客户中有多少人计划开启WebSphere的J2EE安全性。 我们估计大约有50%的客户最初计划使用此功能。 例如,我们已经与多家计划不启动安全性的大型金融机构(银行,经纪公司等)合作; 幸运的是,此问题在部署之前已得到修复。

不利用J2EE安全性是危险的游戏。 假设您的应用程序需要安全性(几乎所有功能都需要这样做),您敢打赌,您的开发人员可以构建比从J2EE供应商那里购买的安全性更好的安全性基础结构。 那不是一个好选择。 保护分布式应用程序非常困难。 例如,您需要使用网络安全加密令牌来控制对EJB的访问。 根据我们的经验,大多数本地安全基础结构都不安全。 具有明显的弱点,使生产系统非常脆弱。 (有关更多信息,请参阅[Barcia]的第18章。)

不使用J2EE安全性的原因包括:担心性能下降,相信其他安全产品(例如Netegrity SiteMinder)可以解决此问题,或者对WebSphere Application Server安全性的特性和功能不了解。 不要掉入这些陷阱。 尤其是,尽管像SiteMinder这样的产品提供了出色的安全功能,但仅靠它们本身无法保护整个J2EE应用程序。 他们必须与J2EE应用服务器协同工作,以保护系统的所有方面。

不使用J2EE安全性的另一个常见原因是基于角色的模型不能提供足够的粒度访问控制来满足复杂的业务规则。 尽管这通常是正确的,但这并不是避免J2EE安全的原因。 而是将J2EE身份验证模型和J2EE角色与您的特定扩展规则结合使用。 如果需要复杂的业务规则来做出安全决策,请编写代码以执行该决策,并基于容易获得且可信赖的J2EE身份验证信息(用户的ID和角色)来做出决策。

5.建立您所知道的。

迭代开发使您可以逐渐掌握J2EE的所有动态部分。 通过您的应用程序构建小的垂直切片,而不是一次完成所有操作。


面对现实,J2EE很大。 如果开发团队只是从J2EE开始,那么尝试一次全部学习就太困难了。 有太多的概念和API需要掌握。 在这种环境下成功的关键是采用小的,受控的步骤进行J2EE。

通过在应用程序中构建小的垂直切片,可以最好地实现此方法。 一旦团队通过构建简单的域模型和后端持久性机制(也许使用JDBC)建立了信心,并对该模型进行了全面测试,他们便可以着手掌握使用该域模型的Servlet和JSP的前端开发。 。 如果开发团队发现了对EJB的需求,那么他们可以从容器管理的持久性EJB组件或基于JDBC的数据访问对象(DAO)之上的简单Session Facades开始,然后再转向消息驱动Bean和JMS等更复杂的结构。

这种方法并不是什么新鲜事物,但是实际上很少有团队以这种方式来培养自己的技能。 取而代之的是,大多数团队都试图通过一次构建所有内容来安排压力—他们同时攻击MVC中的View层,Model层和Controller层。 相反,请考虑一些新的敏捷开发方法,例如极限编程(XP),这些方法可以促进这种增量式学习和开发。 在XP中经常使用一种称为ModelFirst [Wiki]的过程 ,该过程涉及首先构建域模型,作为组织和实现用户故事的机制。 基本上,您将域模型构建为所实现的第一组用户故事的一部分,然后作为实现更高版本的用户故事的结果,在其之上构建一个UI。 这非常适合让团队一次学习一种技术,而不是让他们同时参加十二门课(或让他们阅读十二本书),而这可能会让人感到不知所措。

同样,每个应用程序层的迭代开发也促进了适当模式和最佳实践的应用。 如果从应用程序的较低层开始并应用数据访问对象和会话外观等模式,则不应以JSP和其他View对象中的域逻辑结束。

最后,当您在垂直的垂直切片中进行开发时,可以更轻松地尽早开始对应用程序进行性能测试。 正如[Joines]所说的那样,将性能测试推迟到应用程序开发周期的末尾肯定会带来灾难。

6.每当您使用EJB组件时,请始终使用Session Facades。

切勿将实体bean直接暴露给任何客户端类型。 仅对实体类型使用本地EJB接口。


使用会话外观是使用EJB组件的最佳实践之一。 实际上,对于任何分布式技术,包括CORBA,EJB和DCOM,都广泛倡导通用做法。 基本上,应用程序的分布“横截面”越低,针对小块数据进行多次重复的网络跃迁所造成的开销浪费的时间就越少。 完成此操作的方法是创建非常大的外观对象,这些对象包装逻辑子系统,并且可以在单个方法调用中完成有用的业务功能。 这不仅将减少网络开销,而且在EJB中,还可以通过为整个业务功能创建单个事务上下文来显着减少数据库调用的次数。 (此被详细描述在[布朗]描述。阿卢尔]具有这种模式的规范表示,但它也被在[福勒](其概括它不仅仅是的EJB)和[马里内斯库]。见描述相关主题 。)

作为EJB 2.0规范的一部分引入的EJB本地接口,为同一位置的EJB提供了性能优化。 本地接口必须由您的应用程序显式调用,这需要更改代码并阻止以后无需应用程序更改即可分发EJB的能力。 因为Session Facade和它包装的实体EJB应该彼此是本地的,所以我们建议对Session Facade后面的实体bean使用本地接口。 但是,Session Facade本身的实现(通常是无状态会话Bean)应设计用于远程接口。

为了优化性能,可以将本地接口添加到Session Facade。 这利用了这样一个事实,即在大多数情况下,至少在Web应用程序中,您的EJB客户端和EJB将位于同一JVM中。 另外,如果在本地调用会话外观,则可以使用J2EE应用服务器配置优化,例如WebSphere“ No Local Copies”。 但是,您必须知道这些替代方法将交互的语义从“按值传递”更改为“按引用传递”。 这可能会导致代码中的细微错误。 要利用这些选项,您应该从一开始就计划这种可能性。

如果为Session Facade使用远程接口(而不是本地接口),则还可以通过J2EE 1.4兼容方式将同一Session Facade作为Web服务公开。 (这是因为J2EE 1.4的Web服务部署部分JSR 109要求您使用无状态会话Bean的远程接口作为EJB Web服务和EJB实现之间的接口。)这样做通常是可取的,因为这样做可以增加业务逻辑的客户端类型数量。

7.使用无状态会话Bean而不是有状态会话Bean。

这使您的系统更适合故障转移。 使用HttpSession来存储用户特定的状态。


在我们看来,有状态会话bean是一个想法,它的时代已经过去了。 如果您考虑一下,从结构上来说,有状态会话Bean与CORBA对象完全相同-单个对象实例绑定到单个服务器,该服务器的生命周期取决于该服务器。 如果服务器关闭,对象值将丢失,因此该bean的所有客户端都将失去运气。

提供有状态会话Bean故障转移的J2EE应用服务器可以解决某些问题,但是有状态解决方案的可伸缩性不如无状态解决方案。 例如,在WebSphere Application Server中,对无状态会话Bean的请求在已部署无状态会话Bean的集群的所有成员之间进行负载平衡。 相反,J2EE应用程序服务器无法平衡对有状态Bean的请求的负载。 这意味着负载可能会不均衡地分布在群集中的服务器之间。 另外,使用有状态会话Bean会将状态推送到应用程序服务器,这是不希望的。 它增加了系统复杂性,并使故障情况变得复杂。 健壮的分布式系统的关键原理之一是尽可能的无状态行为。

因此,我们建议为大多数应用程序选择无状态会话bean方法。 处理所需的任何特定于用户的状态都应作为EJB方法的参数传递(并通过HttpSession之类的机制存储在EJB外部),或作为EJB事务的一部分从持久后端存储中检索(例如通过使用实体Bean)。 在适当的情况下,此信息可以缓存在内存中,但要注意在分布式环境中保持缓存一致所带来的潜在挑战。 缓存最适合只读数据。

通常,您应该确保从第一天开始就计划可伸缩性。 检查设计中的所有假设,看看您的应用程序是否可以在多台服务器上运行,这些假设是否仍然成立。 该规则不仅适用于上述情况下的应用程序代码,还适用于MBean和其他管理接口等情况。

避免有状态性不仅仅是基于IBM工具套件的假定局限性的IBM / WebSphere建议。 这是基本的J2EE设计原则。 请参阅[Jewell],以了解Tyler Jewell对有状态bean的尖酸刻薄的观点,这些观点与上述陈述相呼应。

8.使用容器管理的事务。

了解两阶段提交事务如何在J2EE中工作并依靠它们,而不是开发自己的事务管理。 容器几乎总是会在事务优化方面做得更好。


使用容器管理的事务(CMT)具有两个关键优势,如果没有容器支持,这些优势几乎是无法获得的:可组合的工作单元和强大的事务行为。

如果您的应用程序代码明确地开始和结束事务(也许使用javax.jts.UserTransaction,甚至使用本机资源事务),那么将来对模块的需求(可能是重构的一部分)通常需要更改事务代码。 例如,如果模块A开始数据库事务,更新数据库然后提交事务,而模块B做同样的事情,请考虑当您尝试同时使用模块C中的两个模块时会发生什么。现在,模块C正在执行以下操作:单个逻辑操作实际上导致了两个独立的事务发生。 如果模块B在操作过程中发生故障,则模块A的工作仍将提交。 这不是所需的行为。 相反,如果模块A和模块B都使用CMT,则模块C也可以启动CMT(通常通过部署描述符隐式启动),并且模块A和B中的工作将隐式属于同一工作单元,而无需进行任何操作。复杂的返工。

如果您的应用程序需要在同一操作中访问多个资源,则需要两阶段提交事务。 例如,如果从JMS队列中删除了一条消息,然后根据该消息在数据库中更新了一条记录,则这两种操作都会发生-或两者都不发生很重要。 如果从队列中删除了该消息,然后系统在未更新数据库的情况下发生了故障,则该系统不一致。 不一致的状态导致严重的客户和业务影响。

我们偶尔会看到客户端应用程序试图实现自己的解决方案。 如果数据库更新失败,则应用程序代码可能会尝试“撤消”队列操作。 我们不建议这样做。 实现比您最初想象的要复杂得多,并且有很多极端的情况(想象一下,如果应用程序在此过程中崩溃,将会发生什么)。 而是使用两阶段提交事务。 如果您使用CMT并在单个CMT中访问具有两阶段提交功能的资源(例如JMS和大多数数据库),那么WebSphere将负责这项工作。 它将确保事务完全完成或完全没有完成,包括失败情况,例如系统崩溃,数据库崩溃或其他情况。 该实现在事务日志中维护事务状态。 如果应用程序访问多个资源,我们不能足够强调依赖CMT事务的需求。

9.首选JSP作为表示技术的首选。

仅当您具有必须由单个控制器和后端支持的多种演示输出类型时,才使用XML / XSLT。


对于为什么您应该选择XML和XSLT作为基于JSP的表示技术,我们经常听到一个普遍的争论。 这是因为JSP过多地“允许您混合模型和视图”,并且XML / XSLT从某种程度上摆脱了这个问题。 不幸的是,这不是真的,或者至少不是看起来的那样黑白。 实际上,XSL和XPath是编程语言。 实际上,即使XSL可能不符合大多数人对编程语言的定义,因为它是基于规则的,并且不具备程序员可能习惯的所有控制功能,因此XSL是图灵完备的。

问题在于,鉴于这种灵活性,开发人员将可以利用它。 尽管每个人都同意JSP使开发人员可以轻松地在视图中进行“模型式”行为,但实际上,可以在XSL中完成某些相同的事情。 尽管很难(即使不是不可能)执行诸如从XSL调用数据库之类的操作,但我们已经看到了一些难以置信的复杂XSLT样式表,它们执行困难的转换仍然相当于模型代码。

但是,人们选择JSP作为表示技术的首选的最基本的原因只是因为它是可用的,得到最好支持和理解的J2EE视图技术。 鉴于引入了自定义标记库,JSTL和新的JSP 2.0功能,构建不需要任何Java代码且将模型和视图完全分开的JSP变得越来越容易。 像WebSphere Studio这样的开发环境中内置了对JSP的大量支持(包括调试支持),许多开发人员发现使用JSP进行开发比使用XSL进行开发更容易-主要是由于JSP是基于过程的,而不是基于规则的。 尽管WebSphere Studio支持XSL开发,但是图形布局工具和其他支持JSP的功能(尤其是在诸如JSF之类的框架中)使开发人员更容易以WYSIWYG的方式进行工作-使用XSL很难做到。

仔细考虑使用JSP的最终原因是速度之一。 在IBM进行的性能测试中,通过比较XSL和JSP的相对速度表明,即使使用编译的XSL,在大多数情况下,JSP产生与等效XSL转换相同HTML输出的速度也要快几倍。 尽管这通常不是问题,但在性能至关重要的情况下,它可能会产生问题。

这并不是说您永远不应该使用XSL。 在某些情况下,XSL能够对固定数据集进行单一表示并根据不同的样式表以几种不同方式之一进行呈现(请参阅[Fowler] ),这是呈现视图的最佳解决方案。 但是,这种要求通常是例外而不是规则。 如果您只为每个页面生成一个HTML呈现,那么在大多数情况下,XSL是过大的,它将给您的开发人员造成比解决更多的问题。

10.使用HttpSessions时,仅存储当前业务交易所需的状态,不能存储更多的状态。

启用会话持久性。


HttpSession非常适合存储有关应用程序状态的信息。 该API易于使用和理解。 不幸的是,开发人员常常忽略了HttpSession的意图-维护临时用户状态。 它不是任意数据缓存。 我们已经看到太多的系统会为每个用户的会话放置大量数据(兆字节)。 好吧,如果有1000个登录用户,每个用户都有一个1 MB的HTTP会话,则仅用于会话的内存为1 GB或更多。 保持这些HTTP会话较小。 否则,应用程序的性能将受到影响。 良好的经验法则是在2K-4K以下。 这不是硬性规定。 8K仍然可以,但显然比2K慢。 只需密切注意它,并防止HttpSession成为“可能”使用的数据的垃圾场。

一个常见的问题是使用HttpSessions缓存易于重新创建的信息(如果需要)。 由于会话是持久的,因此这是一个非常昂贵的决定,迫使不必要的序列化和数据写入。 而是使用内存中的哈希表来缓存数据,并仅在会话中保留数据的键。 如果用户故障转移到另一个应用程序服务器,这将允许重新创建数据。 (有关更多信息,请参见[Brown2] 。)

说到会话持久性,请不要忘记启用它。 如果未启用会话持久性,则如果由于任何原因(服务器故障或常规维护)而使服务器停止,当前在该应用程序服务器上的任何用户都将丢失其会话。 这带来了非常不愉快的体验。 他们必须重新登录并重做所有正在处理的事情。 相反,如果启用了会话持久性,那么WebSphere将自动将用户(及其会话)透明地移动到另一个应用程序服务器。 他们甚至都不知道发生了什么。 效果如此之好,以至于我们看到生产系统由于本机代码(不是IBM代码!)中的令人讨厌的错误而经常崩溃,但提供了足够的服务。

11.在WebSphere中,打开动态缓存并使用WebSphere servlet缓存机制。

性能提升是可观的; 开销最小。 编程模型不受影响。


缓存提高性能的优点已广为人知。 不幸的是,当前的J2EE规范不包括用于servlet / JSP缓存的机制。 但是,WebSphere通过其动态高速缓存功能提供了对页面和片段高速缓存的支持,而无需更改应用程序。 缓存策略是声明式指定的,配置是通过XML部署描述符进行的。 因此,您的应用程序不受影响,保持了J2EE规范的可移植性,同时受益于WebSphere Servlet和JSP缓存提供的性能优化。

取决于应用程序的特性,从Servlet和JSP的动态缓存获得的性能提升可能是可观的。 Cox和Martin [Cox]展示了将动态缓存应用于现有RDF(资源描述格式)站点摘要(RSS)Servlet最多10倍的性能优势。 请认识到该实验涉及一个简单的servlet,并且这种数量级的改进可能无法反映出更复杂的应用程序组合。

为了获得额外的性能,WebSphere servlet / JSP结果缓存与WebSphere插件ESI片段处理器,IBM HTTP Server快速响应缓存加速器(FRCA)和边缘服务器缓存功能集成在一起。 对于基于读取的繁重工作负载,通过利用这些功能可以获得显着的额外好处。 (参见性能增益中描述[Willenborg]和[Bakalova]在相关主题 。)

12.由于程序员提高了生产率,因此首选CMP Entity Bean作为O / R映射的首选解决方案。

通过WebSphere框架优化性能(预读,缓存选项,隔离级别等)。 如有必要,有选择地应用诸如Fast-Lane阅读器[Marinescu]之类的模式来实现性能目标。


对象/关系(O / R)映射是使用Java构建企业级应用程序的基础。 几乎每个J2EE应用程序都需要某种类型的O / R映射。 J2EE供应商提供了一种O / R映射机制,该机制可在各个供应商之间移植,高效并得到标准和工具的良好支持。 这是EJB规范的CMP(容器管理的持久性)部分。

早期的CMP实现因表现不佳且不支持许多SQL构造而享有(也许)应有的声誉。 但是,随着EJB 2.0和2.1规范被供应商开发和采用,并且出现了诸如IBM WebSphere Studio Application Developer之类的工具,这些担忧不再像以前那样有效。

CMP EJB组件现已广泛用于许多高性能应用程序中。 WebSphere包括用于增强EJB组件性能的优化,包括缓存中的生存期和预读功能。 这两个优化都是部署选项,不需要修改应用程序或影响可移植性。

缓存中的生存时间缓存CMP状态数据,并提供基于时间的失效。 高速缓存方法中的生命周期可提高性能,而方法A的高速缓存性能仍可为您的应用程序提供在集群中扩展的功能。 预读功能与容器管理的关系结合使用。 此功能通过有选择地在与父数据相同的查询中检索关联数据,从而最大程度地减少了数据库交互。 如果通常将通过后续查询访问关联的数据,则可提供性能优势。 [Gunther]提供了详细的描述,并详细介绍了这些功能可能带来的性能改进。

另外,要完全优化EJB组件,请在指定隔离级别时密切注意。 使用尽可能低的隔离级别,同时仍保持数据完整性。 较低的隔离级别可提供最佳性能,并降低数据库死锁的风险。

这是迄今为止最有争议的最佳做法。 编写卷的目的是赞扬CMP EJB,并谴责它们。 但是,这里的基本问题是数据库开发很困难。 在开始使用任何持久性解决方案之前,您需要具有有关查询和数据库锁如何工作的基本知识。 如果选择使用CMP EJB,请确保通过[Brown]和[Barcia]之类的书对它们的使用有所了解。 锁定和争用中存在一些微妙的交互,这些交互很难理解,但是只要花费足够的时间和精力,就可以掌握。

结论

在这个简短的摘要中,我们为您介绍了可以使J2EE开发成为可管理的工作的核心模式和最佳实践。 尽管我们并未展示将这些模式付诸实践的所有必要细节,但我们希望已为您提供了足够的指导和指导,以帮助您确定下一步的工作。

致谢

感谢所有首先记录了这些模式和最佳实践的人(我们在下面提供了参考),也感谢John Martinek,Paul Ilechko,Bill Hines,Dave Artus和Roland Barcia在审阅本文方面的帮助。


翻译自: https://www.ibm.com/developerworks/websphere/techjournal/0405_brown/0405_brown.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值