大胃兄,哈,我还没仔细看呢。。而且对于EJB经验不多,不好意思讲啊:)
解决方案 »
- 【求助】java文件下载问题
- 抽奖程序思路
- java中,使用jacob操作word,我现在想用空格替换掉word中以“$”开始,并且以“$”结束的字符串,怎么做啊
- 怎样快速开始投入开发?
- 关于hibernate的问题
- 用Spring+Struts 写了个分页,想把具体类里的 一些代码封装到 父类,不知道父类 该怎么写,大家提供有什么思路吗?
- 关于jsp 安全验证的问题...
- 紧急!100分,Socket编程的问题.
- rmi的问题
- Session Bean 和 Entity Bean 合用遇到的问题
- 请问哪里有 java网络蜘蛛源码发展套件 下载java网络蜘蛛源码发展套件
- 在线求救:tag报一下错误!!!高分(200)
EJB层架构模式
================================================================================当我们开发人员第一次设计企业级JavaBean(EJB)系统时,面临的最困难的任务是选择正确的架构或者说逻辑分块以满足项目需求,这些需求包括:性能、可维护性和可移植性。这一章会讲到一些在当今实际应用的基本架构模式,具体的讲有如下几种:[会话面板模式] 作为最广泛使用的EJB设计模式,该模式表明如何正确的在你的系统中分割商务逻辑,以最大限度减轻客户端与服务器端的相互依赖,同时强制用例(use case)在单次网络调用和单个事务中执行。[消息面板模式] 消息面板模式处理的是何时以及怎样为那些本质上异步的用例划分逻辑。[EJB命令模式] 与会话面板模式相反,该模式提倡将商务逻辑放在轻量的、普通的Java命令bean中。使用该模式最大的好处是完全的将客户端与EJB本身分隔开来,并且在同一个网络调用和事务中执行用例。[数据传输对象工厂模式] 该模式反映出早先的将DTO创建/销毁逻辑放在实体bean中这种方式的弊端,建议将数据传输对象的创建/销毁逻辑集中到单个层中(通过会话bean或者普通的java工厂实现)。[通用属性访问模式] 该模式讨论何时以及怎样提供域内通用的接口来访问实体bean的属性以达到可维护性和性能的需求。[商务接口模式] 该模式展示了怎样实现一个能够提供编译期对远程/本地接口和EJB类的方法签名检查的接口实现机制。
--------------------------------------------------------------------------------
会话面板模式
--------------------------------------------------------------------------------EJB的客户端需要执行商务逻辑以完成一个用例。[一个EJB的客户端如何才能在单个事务和一次较大的网络调用中执行某个用例的商务逻辑呢?] * * *为了执行某个典型的用例的商务逻辑,通常会需要访问甚至修改服务器端的多个对象(如会话bean和实体bean)。问题是多次细化的会话/实体bean的调用会产生多次网络调用(以及可能的多个事务)的开销,同时造成代码难以维护,因为数据访问和工作流/商务逻辑被分散在不同的客户端。考虑一个在线银行场景,一个servlet收到请求,要它为Web客户端从一个账户往另一个账户划账。在这种情况下(如图1.1所示),这个servlet必须:检查确认用户是被授权的、从一个银行账户的实体bean中提取资金、将资金存到另一个银行账户实体bean中。<图略>当通过实体bean的本地和远程接口调用方法时,这个方案在严重的负载情况下并不适用,因为整个过程需要至少6次网络调用:3次用于找到正确的实体bean,另外3次用于实际上的划账。还有,因为实体bean是事务性的,每一次对它的调用都需要服务器端一个单独的事务,要求将远程对象与其后台的数据存储同步化,还需要应用服务器相应的维护工作。更糟的是这个方案并不保证客户存款的安全。如果存入过程失败,客户的存款已经提出,这样他的钱就丢失了。用户验证、提款、存款都是单独进行的,如果存款失败,取款的过程就不会被回滚,造成状态不连贯。这里的问题在于,当直接调用实体bean的方法时,每次方法调用都是单独的工作,属于单独的事务。一个解决方案是往实体bean中加入额外的逻辑来处理单个客户调用并执行多项操作。这个方案会引入维护问题,因为我们的实体bean层很可能会随着时间推移需要对其进行各种各样的操作。如果我们每次当需要提升性能的时候就往实体bean里面增加逻辑的话,很快我们的实体bean就会变得臃肿并且难以理解、维护和重用。我们这样做会经常将我们的程序逻辑(动)融合到我们的持久性逻辑(名词)中,这可不是什么好的应用程序设计。另一个方案是要求客户端通过Java事务处理API(JTA)划定一个总的、大型的事务。这将使每个对实体bean的方法调用都属于同一个事务,要么全有、要么全无的形式。如果存款失败,那么提款也会被回滚,客户的存款是安全的。然而,这个稍有改进的方案仍然有不少缺陷:[高网络开销] 我们仍然需要处理6次网络调用,这会减慢性能(除非使用本地接口)。[弱并发性] 如果客户端距离服务器非常远(比如applet或应用程序与远程的EJB系统交互,甚至通过Internet或者防火墙的情况),事务就会持续很长一段时间,这会导致过度的(对象)锁定,增加出现冲突和死锁的几率,削弱其他客户访问同一个实体bean实例的并发性。[高耦合度] 我们的客户端直接与实体bean的API通信,这将使客户端与实体bean紧紧地连在一起。如果未来实体bean层需要修改,我们同时也需要修改客户端。[弱重用性] 执行"划账"用例的商务逻辑直接被嵌入到客户端,于是被"陷入"在客户端中。其他类型的客户端(Java应用程序、applet、servlet等等)不能重用这个商务逻辑。对于任何严谨的应用程序设计和部署来说,像这样将表示逻辑与商务逻辑混合起来的做法都是不可取的。[弱可维护性] 使用JTA会造成处理事务的中间件逻辑和应用程序逻辑搅在一起。将这两者通过明确声明的事务分开会更清晰,这样我们才能在不影响商务原则的情况下修改我们的中间件。[各个开发角色的弱独立性] 一个在大型项目开发中通常的做法是将实现表示逻辑的程序员(如servlet/jsp的程序员)的开发任务同实现商务逻辑/中间件的程序员(EJB开发人员)的开发任务分开来。如果商务逻辑出现在客户端/表示层,明确的任务划分是不可能的。如果实现商务逻辑的程序员和实现表示逻辑的程序员都需要在表示层开发,他们很容易出现冲突。我们这样讨论下来发现,我们需要一个服务器端的抽象作为中介来缓冲对实体bean的调用。会话bean正是基于此目的而设计的。所以说:[将实体bean层包装在一个称之为会话面板的会话bean层中。客户端应该只能访问会话bean而不能访问实体bean。]会话面板模式将传统的Facade设计模式应用到EJB:完全将服务器端的对象模块向客户层隐藏起来,并把会话bean层作为客户端访问的唯一途径。图1.2说明了此方案是如何改进应用程序架构的。会话面板模式更增加了通过强制在单个网络调用中执行一个用例所带来的好处,并提供了一个清晰的层来封装用于完成用例的商务和工作流逻辑。会话面板模式通常是作为一个无状态会话bean的层实现的(尽管这个模式也能通过有状态的会话bean来实现)。<图略>为了说明这个方案如何运作以及它带来的好处,我们再回到先前的例子。我们的"划账"用例的商务逻辑现在被放在会话bean中,这个会话bean有一个方法:transferFunds(userpk, acountpk, acountpk, amount)。BankTeller会话bean在Users和Bank Accounts上处理成组的操作,如图1.3所示。由于BankTeller会话bean与User和Account实体bean密切相关,它应该固定的通过本地接口访问实体bean,以减少执行用例所需的网络开销至仅仅一个调用(客户端调用BankTeller)。并且,所有对实体bean层的更新都应在由BankTeller发起的事务中处理,在其发布描述文件中几乎所有时候都设置TX_REQUIRED。这样做有效的将整个用例包装在单个事务中,保证了所有对实体bean的更新都在BankTeller的transferFunds方法的执行引发的事务中完成。<图略>会话面板模式是当今使用的最基本的EJB模式。它不仅提供性能上的好处,同时还代表了一种标准的EJB系统架构:在J2EE应用程序中用一个会话bean层将客户端和服务器端分隔开来。这些会话bean包含了针对应用程序中所有用例的方法,也包含了相应的商务逻辑。对BankTeller例子再进一步,很显然除了简单的"划账"用例之外还有很多其他的用例。通过使用会话面板模式,会话bean被创建以将相似的功能的用例组合到单个的bean中。于是我们可以向BankTeller增加其他的辅助银行操作(如提款、存款、查询)。在这个银行应用程序中的其他地方,其他目的的用例也可以组合到会话bean中。例如,每个银行都有一个信贷部,模拟信贷部的那些用例并非跟BankTeller的用例特别相关,所以这些用例可以被组合到LoanServices会话bean中。同理,一个银行应用程序可能还需要一个会话bean来封装与投资相关的用例。通过运用会话面板模式,这个银行应用程序的架构布局可以如图1.4所示。<图略>
[相关模式]消息面板
数据传输对象
会话面板(Alur, et al., 2001)
会话面板(MartinFowler.com)
接分分~~