??xml version="1.0" encoding="utf-8" standalone="yes"?>99国产精品久久久久,欧美女v视频,日韩精品一区二区三区四区五区 http://www.aygfsteel.com/isoft/category/28620.html感悟人生Q领悟世界,创造生z,创新C会zh-cnThu, 03 Jan 2008 06:36:35 GMTThu, 03 Jan 2008 06:36:35 GMT60J2EE架构的最佛_?/title><link>http://www.aygfsteel.com/isoft/archive/2008/01/03/172475.html</link><dc:creator>梦򋹁星</dc:creator><author>梦򋹁星</author><pubDate>Thu, 03 Jan 2008 06:25:00 GMT</pubDate><guid>http://www.aygfsteel.com/isoft/archive/2008/01/03/172475.html</guid><wfw:comment>http://www.aygfsteel.com/isoft/comments/172475.html</wfw:comment><comments>http://www.aygfsteel.com/isoft/archive/2008/01/03/172475.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/isoft/comments/commentRss/172475.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/isoft/services/trackbacks/172475.html</trackback:ping><description><![CDATA[虽然许多文章曄讨论qJ2EE最佛_c那么,Z么我q要再写一文章呢Q本文究竟与以前的文章有何不同或者说比其他文章好在哪呢?<br />   首先Q本文的目标读者是正在从事技术工作的架构师。ؓ了避免浪费大家的才智Q我会避免讲qC些陈腐的最佛_践,例如“日常构徏Qbuild dailyQ?#8221;?#8220;试一切(test everythingQ?#8221;?#8220;l常集成Q?integrate oftenQ?MhU职架构师的目都有分工明确的、定义良好的团队l构。他们还行编码检查、构Z码(每日或在需要时Q、进行测试(单元、集成和pȝ的)、部|和配置/释放理而具备已记录的过E?br />   其次Q我蟩q通常Ҏ的最佛_践,例如“Z接口的设?#8221;?#8220;使用著名的设计模?#8221;以及“使用面向服务的架?#8221;{。相反,我将集中讲述我曾学过q且使用了若q年?Q不是很多)个方面的in-the-trench评。最后,本文的目的是让您思考一下自q架构Q提供工作代码示例或者解x案超Z本文的范围。下面就让我介绍一下这6课:<br /> <span style="color: #3366ff">1、切勿绕q服务器端验?br /> 2、安全ƈ非是附加?br /> </span><span style="color: #3366ff">3、国际化QI18NQ不再是U怸谈兵<br /> 4、在MVC表示中避免共同的错误<br /> 5、不要被POJO束缚住手?br /> 6、数据访问ƈ不能托管O/R映射</span> <br /> <br /> <strong>W?课:切勿l过服务器端验证<br /> </strong>  作ؓ一位Y仉问,我曾有机会不但设计ƈ实现了Web应用E序Q而且q评?审核了许多Web应用E序。在复杂的、ƈ且用JavaScript客户端封装的应用E序内,我经帔R到对用户输入信息执行大量查的Web面。即使HTML元素h数据有效性的属性也如此Q例如MAXLENGTH。只有在成功验证所有输入信息后Q才能提交HTML表单。结果,一旦服务器端收到通知表单Q请求)Q便恰当地执行业务逻辑?br />   在此Q您发现问题了么Q开发h员已l做了许多重要的假设。例如,他们假设所有的Web应用E序用户都同栯实。开发h员还假设所有用户将L使用他们试q的览器访问Web应用E序。还有很多其他的假设。这些开发h员忘C利用可以免费得到的工P通过命o行很Ҏ地模拟类似浏览器的行为。事实上Q通过在浏览器H口中键入适当的URLQ您可以发送Q?#8220;posted”表单Q尽如此,通过用q些面的GEThQ您很容易地Lq样?#8220;表单发?#8221;。但是,您不能阻止h们模拟甚臛_Z们自q览器来入R您的pȝ?br /> Ҏ的问题在于开发h员不能确定客L验证与服务器端验证的主要差别。两者的主要差别不在于验证究竟发生在哪里Q例如在客户端或者在服务器端。主要的差别在于验证背后的目的不同?br />   客户端验证仅仅是方便。执行它可ؓ用户提供快速反??使应用程序似乎做出响应,lh一U运行桌面应用程序的错觉?br />   另一斚wQ服务器端验证是构徏安全Web应用E序必需的。不在客户端一侧输入的是什么,它可以确保客L送往服务器的所有数据都是有效的?br />   因而,只有服务器端验证才可以提供真正应用程序的安全。许多开发h员陷入了错误感觉的圈套:只有在客Lq行所有数据的验证才能保安全。下面是说明此观点的一个常见的CZQ?br />   一个典型的d面拥有一个用来输入用户名的文本框和一个输入密码的文本框。在服务器端Q某人在接收servlet中可能遇C些代码,q些代码构成了下面Ş式的SQL查询Q?br /> "SELECT * FROM SecurityTable WHERE username = @#" + form.getParameter("username") + "@# AND password = @#" + form.getParameter("password") + "@#;"Qƈ执行q些代码。如果查询在l果集的某一行返回,则用L录成功,否则用户dp|?br />   W一个问题是构造SQL的方式,但现在让我们暂时忽略它。如果用户在用户名中输入“Alice@#--”会怎样呢?假设名ؓ“Alice”的用户已l在SecurityTable中,q时此用P更恰当的说法是黑客)成功地登录。我把扑ևZ么会出现q种情况的原因做为留l您的一道习题?br />   许多创造性的客户端验证可以阻止一般的用户从浏览器中这L录。但对于已经用了JavaScript的客LQ或者那些能够用其他类似浏览器E序直接发送命令(HTTP POST和GET命oQ的高用户Q或者说黑客Q来_我们又有什么办法呢Q服务器端验证是防止q种漏洞cd所必须的。这ӞSSL、防火墙{都z不上用Z?br /> <br /> <strong>W?课:安全q是附加物<br /> </strong>  如第1课所qͼ我曾有幸研究q许多Web应用E序。我发现所有的JavaServer PageQJSPQ都有一个共同的主题Q那是hcM下面伪代码的布局Q?br /> <br /> <%<br /> User user = <br /> session.getAttribute("User");<br /> if(user == null)<br /> {<br /> // redirect to <br /> // the logon page…<br /> } <br /> if(!user.role.equals("manager"))<br /> {<br /> // redirect to the<br /> // "unauthorized" page…<br /> }<br /> %><br /> <br /> <!-<br /> HTML, JavaScript, and JSP<br /> code to display data and<br /> allow user interaction --><br /> <br />   如果目使用诸如Strutsq样的MVC框架Q所有的Action Bean都会hcM的代码。尽最后这些代码可能运行得很好Q但如果您发C个bugQ或者您必须d一个新的角Ԍ例如Q?#8220;guest”或?#8220;admin”Q,q就会代表一场维护恶梦?br />   此外Q所有的开发h员,不管您多q轻Q都需要熟悉这U编码模式。当Ӟ您可以用一些JSP标签来整理JSP代码Q可以创Z个清除派生Action Bean的基本Action Bean。尽如此,׃与安全相关的代码会分布到多个地方Q所以维护时的恶梦仍旧存在。由于Web应用E序的安全是建立在应用程序代码的U别上(由多个开发h员)Q而不是徏立在架构U别上,所以Web应用E序q是很可能存在弱炏V?br />   很可能,Ҏ的问题是在项目接q完成时才处理安全性问题。最q作Z名架构师Q我曑֜一q多的时间里亲历了某一要实现项目的6个版本,而直到第四版时我们才提到了安全??即该项目会高度敏感的个h数据暴露于Web上,我们也没有注意到安全性。ؓ了更改发布计划,我们卷入了与目资助人及其管理h员的争斗中,以便在第一版中包含所有与安全相关的功能,q将一?#8220;业务”功能攑֜后箋的版本中。最l,我们赢得了胜利。而且׃应用E序的安全性相当高Q能够保护客LU有数据Q这一Ҏ们引以ؓ荣,我们的客户也非常高兴?br />   遗憾的是Q在大多数应用程序中Q安全性看hq未增加M实际的商业h|所以直到最后才解决。发生这U情冉|Qh们才匆忙开发与安全相关的代码,而丝毫没有考虑解决Ҏ的长期可l护性或者健壮性。忽视该安全性的另一个征兆是~Z全面的服务器端验证,如我在第1课中所qͼq一Ҏ安全Web应用E序的一个重要组成部分?br />   CQJ2EE Web应用E序的安全性ƈ非仅仅是在Web.xml 和ejb-jar.xml文g中用合适的声明Q也不是使用J2EE技术,如Java 认证和授权服务(Java Authentication and Authorization ServiceQJAASQ。而是l过深思熟虑后的设计,且实C个支持它的架构?br /> <br /> <strong>W?课:国际化(I18NQ不再是U怸谈兵</strong> <br />   当今世界的事实是许多p非母语的Z访问您的公共Web应用E序。随着电子政务的实行,׃它允思h们(某个国家的居民)在线与政府机构交互,所以这一点特别真实。这L例子包括换发驄或者R辆登记证。许多第一语言不是p的h们很可能访问这L应用E序。国际化Q即Q?#8220;i18n”Q因为在“internationalization”q个单词中,字母i和字母n之间一共有18个字母)使得您的应用E序能够支持多种语言?br />   昄Q如果您的JSP 面中有编码的文本Q或者您的Java代码q回编码的错误消息Q那么您要花费很多时间开发此Web应用E序的西班牙语版本。然而,在Web应用E序中,Z支持多种语言Q文本不是惟一必须“具体?#8221;的部分。因多图像中嵌有文字Q所以图形和囑փ也应该是可配|的。在极端的情况下Q图像(或者颜Ԍ在不同的文化背景中可能有完全不同的意思。类似地QQ何格式化数字和日期的Java代码也必L地化。但问题是:您的面布局可能也需要更攏V?br />   例如Q如果您使用HTML表格来格式化和显C单选项、应用程序题头或注脚Q则您可能必Mؓ每一U支持的语言更改每一栏的最宽度和表格其他可能的方面。ؓ了适应不同的字体和颜色Q您可能必须为每一U语a使用单独的样式表?br />   昄Q现在创Z个国际化的Web应用E序面的是架构挑战而不是应用程序方面的挑战。一个架构良好的Web应用E序意味着您的JSP面和所有与业务相关的(应用E序Ҏ的)Java代码都不知不觉地选择了本地化。要C的教训是Q不要因为Java、J2EE支持国际化而不考虑国际化。您必须从第一天vp住设计具有国际化的解x案?br /> <br /> <strong>W?课:在MVC表示中避免共同的错误</strong> <br />   J2EE开发已l够成熟,在表C层Q大多数目使用MVC架构的某些Ş式,例如Struts。在q样的项目中Q我常见到的现象是对MVC模式的误用。下面是几个CZ?br />   常见的误用是在模型层Q例如,在Struts的Action Bean中)实现了所有的业务逻辑。不要忘了,表示层的模型层仍然是表示层的一部分。用该模型层的正确Ҏ是调用适当的业务层服务Q或对象Qƈ结果发送到视图层(view layerQ。用设计模式术语来说QMVC表示层的模型应该作ؓ业务层的外观QFa?adeQ来实现。更好的Ҏ是,使用核心J2EE模式QCore J2EE PatternsQ中到的Business Delegate模式。这D自书中摘录的内容精彩地概述了将您的模型作ؓBusiness Delegate来实现的要点和优点:<br />   Business Delegate起到客户端业务抽象化的作用。它抽象化,q而隐藏业务服务的实现。用Business DelegateQ可以降低表C层客户端和pȝ的业务服?之间的耦合E度。根据实现策略不同,Business Delegate可以在业务服务API的实CQ保护客L不受可能的变动性媄响。这P在业务服务API或其底层实现变化Ӟ可以潜在地减必M改表C层客户端代码的ơ数?br />   另一个常见的错误是在模型层中攄许多表示cd的逻辑。例如,如果JSP面需要以指定方式格式化的日期或者以指定方式排序的数据,某些人可能将该逻辑攄在模型层Q对该逻辑来说Q这是错误的地方。实际上Q它应该在JSP面使用的一lhelpercM。当业务层返回数据时QAction Bean应该数据{发给视图层。这P无需创徏模型和视图之间多余的耦合Q就能够灉|支持多个视图层(JSP、Velocity、XML{)。也使视图能够确定向用户昄数据的最x式?br />   最后,我见q的大多数MVC应用E序都有未充分应用的控制器。例如,l大多数的Struts应用E序创Z个基本的Actionc,q完成所有与安全相关的功能。其他所有的Action Bean都是此基cȝzcR这U功能应该是控制器的一部分Q因为如果没有满_全条Ӟ则首先调用不应该到达Action BeanQ即Q模型)。记住,一个设计良好的MVC架构的最强大功能之一是存在一个健壮的、可扩展的控制器。您应该利用该能力以加强自己的优ѝ?br /> <br /> <strong>W?课:不要被POJO束缚住手?/strong><br />   我曾目睹许多目Z使用Enterprise JavaBean而用Enterprise JavaBean。因为EJBgl项目带来优感和妄自尊大的表现Q所以有时它是显L要素Qcoolness factorQ。而其他时候,它会使J2EE和EJB引vh。记住,J2EE和EJB不是同意词。EJB只是J2EE 的一部分QJ2EE 是包含JSP、servlet、Java 消息服务QJMSQ、Java数据库连接(JDBCQ、JAAS?Java理扩展QJMXQ和EJB在内的一pd技术,同样也是有关如何共同使用q些技术徏立解x案的一l指导原则和模式?br />   如果在不需要用EJB的情况下使用EJBQ它们可能会影响E序的性能。与老的Web服务器相比,EJB一般对应用服务器有更多的需求。EJB提供的所有增值服务一般需要消耗更大的内存和更多的CPU旉。许多应用程序不需要这些服务,因此应用服务器要与应用程序争源?br />   在某些情况下Q不必要C用EJB可能使应用程序崩溃。例如,最q我遇到了一个在开源应用服务器上开发的应用E序。业务逻辑装在一pd有状态会话beanQEJBQ中。开发h员ؓ了在应用服务器中完全用q些bean?#8220;钝化”费了很大的劲。客L要求应用E序部v在某一商用应用服务器上Q而该服务器是客户端技术栈的一部分。该应用服务器却不允许关?#8220;钝化”功能。事实上Q客L不想改变与其合作的应用服务器的设M|。结果,开发商到了很大的ȝ。(gQ有的事情是开发商自己都不能给Zؓ什么将代码用EJBQ而且q是有状态会话beanQ实现的好理由。不仅仅是开发商会遇到性能问题Q他们的E序在客户那里也无法工作?br />   在Web应用E序中,无格式普通Java 对象QPOJOQ是EJB强有力的竞争者。POJO是轻量的,不像EJB那样负担额外的负担。在我看来,对许多EJB的优点,例如对象入池Q估计过高。POJO是您的朋友,不要被它束缚住手脚?br /> <br /> <strong>W?课:数据讉Kq不能托O/R映射</strong> <br />   我曾参与q的所有Web应用E序都向用户提供从其他地方存取的数据Qƈ且因此需要一个数据访问层。这q不是说所有的目都需要标识ƈ建立q样一个层Q这仅仅说明q样层的存在不是隐含的就是明的。如果是隐含的数据层Q数据层是业务对象(卻I业务服务Q层的一部分。这适用于小型应用程序,但通常与大一些项目所接受的架构指导原则相抵触?br />   MQ数据访问层必须满或超Z下四个标准:<br />   h透明?<br />   业务对象在不知道数据源实现的具体l节情况下,可以使用数据源。由于实现细节隐藏在数据讉K层的内部Q所以访问是透明的?br />   易于q移<br />   数据讉K层应用E序很容易迁Ud其他数据库实现。业务对象不了解底层的数据实玎ͼ所以迁UM仅涉及到修改数据讉K层。进一步地_如果您正在部|某U工厂策略,您可以ؓ每个底层的存储实现提供具体的工厂实现。如果是那样的话Q迁Ud不同的存储实现意味着为应用程序提供一个新的工厂实现?br />   量减少业务对象中代码复杂?<br />   因ؓ数据讉K层管理着所有的数据讉K复杂性,所以它可以化业务对象和使用数据讉K层的其他数据客户端的代码。数据访问层Q而不是业务对象,含有许多与实现相关的代码Q例如SQL语句Q。这L开发h员带来了更高的效率、更好的可维护性、提高了代码的可L等一pd好处?br />   把所有的数据讉K集中在单独的层上<br />   ׃所有的数据讉K操作现在都委托给数据讉K层,所以您可以这个单独的数据讉K层看做能够将应用E序的其他部分与数据讉K实现怺隔离的层。这U集中化可以使应用程序易于维护和理?br />   注意Q这些标准都不能明确地调出对O/RQ对象到关系Q映层的需求。O/R映射层一般用O/R映射工具创徏Q它提供对象对关pL据结构的查看和感知(look-and-feelQ。在我看来,在项目中使用O/R映射与用EJBcM。在大多数情况下Qƈ不要求它。对于包含中{规模的联合以及多对多关pȝ关系型数据库来说QO/R映射会变得相当复杂。由于增加O/R 映射解决Ҏ本n的内在复杂性,例如延迟加蝲Qlazy loadingQ、高速缓冲等Q您ؓ您的目带来更大的复杂性(和风险)?br />   Zq一步支持我的观点,我将指出按照Sun Microsystem所普及的实体BeanQO/R映射的一U实玎ͼ的许多失败的试Q这是自1.0版以来一直折h的难题。在SUN的防卫措施中Q一些早期的问题是有关EJB规范的开发商实现的。这依次证明了实体Bean规范自n的复杂性。结果,大多数J2EE架构师一般认Z实体Bean中脱d来是一个好L?br />   大多数应用程序在处理他们的数据时Q只能进行有限次数的查询。在q样的应用程序中Q访问数据的一U有效方法是实现一个数据访问层Q该层实现执行这些查询的一pd服务Q或对象、或APIQ。如上所qͼ在这U情况下Q不需要O/R映射。当您要求查询灵zL时QO/R映射正合适,但要CQ这U附加的灉|性ƈ不是没有代h的?br />   像我承诺的那样Q在本文中,我尽量避免陈腐的最佛_c相反,关于J2EE目中每一位架构师必须做出的最重要的决定,我集中讲解了我的观点。最后,您应该记住:J2EEq某种具体的技术,也不是强行加入到解决Ҏ中的一些首字母~写。相反,您应该在适当的时机,恰当的地方,使用合适的技术,q循J2EE的指导原则和J2EE中所包含的比技术本w重要得多的实践?br /> <br /> <br /> <strong><span style="font-size: 14pt"><strong>JAVA 12个最重要的J2EE最佛_?/strong><br /> </span></strong> <p><span style="color: #3366ff">1、始l?MVC 框架?br /> 2、在每一层都应用自动单元试和测试管理?<br /> 3、按照规范来q行开发,而不是按照应用服务器来进行开发?<br /> 4、从一开始就计划使用 J2EE 安全性?br /> 5、创建您所知道的?<br /> 6、当使用 EJB lgӞ始终使用会话 Facades?<br /> 7、用无状态会?beanQ而不是有状态会?bean. <br /> 8、用容器管理的事务?<br /> 9、将 JSP 作ؓ表示层的首选?br /> 10、当使用 HttpSession Ӟ量只将当前事务所需要的状态保存其中,其他内容不要保存?HttpSession 中?br /> 11、在 WebSphere 中,启动动态缓存,q?WebSphere servlet ~存机制?<br /> 12、ؓ了提高程序员的工作效率,?CMP 实体 bean 作ؓ O/R 映射的首选解x案?/span></p> <p><strong><br /> 1. 始终使用 MVC 框架?/strong><br /> MVC 框架可以业务逻辑QJava beans ?EJB lg)、控制器逻辑QServlets/Struts 动作Q、表C层QJSP、XML/XSLTQ清晰地分离开来。良好的分层可以带来许多好处?/p> <p>MVC 框架对于成功使用 J2EE 是如此重要,以致没有其他最佛_践可以与其相提ƈ论。模?视图-控制器(MVCQ是设计 J2EE 应用E序的基。MVC 您的程序代码简单地划分下面几个部分Q?/p> <p>负责业务逻辑的代码(x型——通常使用 EJB 或者普通的 Java 对象来实玎ͼ?/p> <p>负责用户界面昄的代码(卌䏀—通常通过 JSP 及标记库来实玎ͼ有时也?XML ?XSLT 来实玎ͼ?/p> <p>负责应用E序程的代码(x制器——通常使用 Java Servlet 或像 Struts 控制器这LcL实现Q?/p> <p>如果您不遵@基本?MVC 框架Q在开发过E中׃出现许多的问题。最常见的问题就是在视图部分d了太多的成分Q例如,可能存在使用 JSP 标记来执行数据库讉KQ或者在 JSP 中进行应用程序的程控制Q这在小规模的应用程序中是比较常见的Q但是,随着后期的开发,q样做将会带来问题,因ؓ JSP 逐步变得来难以维护和调试?/p> <p>cM圎ͼ我们也经常看到将视图层构建到业务逻辑的情c例如,一个常见的问题是在构徏视图时用的 XML 解析技术直接应用到业务层。业务层应该对业务对象——而不是绑定到视图的特定数据表C行操作?/p> <p>然而,只是h合适的lgq不一定意味着可以使您的应用程序得到合适的分层。我们常常见C些应用程序包?servlet、JSP ?EJB lg所有这三项Q然而,其主要的业务逻辑却是?servlet 层实现的Q或者应用程序导航是?JSP 中处理的。您必须q行严格的代码检查ƈ重构您的代码Q以保应用E序的业务逻辑只在模型层(Model layerQ进行处理,应用E序D只通过控制器层QController layerQ进行处理,而您的视图(ViewsQ只是将传递过来的模型对象?HTML ?JavaScript 的Ş式表C出来?/p> <p><strong><br /> 2. 在应用程序的每一层都使用自动单元试和测试管理?/strong><br /> 不要只是试您的囑Ş用户界面QGUI)。分层的试使测试及l护工作变得极其单?/p> <p>在过ȝ几年中,在方法学领域有了相当大的革新Q例如新出现的被UCؓ AgileQ例?SCRUM [Schwaber] 和极限编E?[Beck1]Q的轻量U方法现在已l得C很普遍的应用。几乎所有的q些Ҏ中的一个共同的特征是它们都提倡用自动的试工具Q这些工具可以帮助开发h员用更少的时间进行回归测?(regression testing)Qƈ可以帮助他们避免׃不充分的回归试造成的错误,因此可以用来提高E序员的工作效率。实际上Q还有一U被UCؓ Test-First Development [Beck2] 的方法,q种Ҏ甚至提倡在开发实际的代码之前先~写单元试。然而,在您试代码之前Q您需要将代码分割成一些可试的片断。一?#8220;大惔?#8221;是难以测试的Q因为它不是只实C个简单的易于识别的功能。如果您的每个代码片断实现多个方面的功能Q这L代码难以保证其完全的正性?/p> <p>MVC 框架Q以?J2EE 中的 MVC 实现Q的一个优点就是元素的lg化能够(实际上,相当的简单)Ҏ的应用程序进行单元测试。因此,您可以方便地对实?bean、会?bean 以及 JSP 独立~写试用例Q而不必考虑其他的代码。现在有许多用于 J2EE 试的框架和工具Q这些框架及工具使得q一q程更加单。例如,JUnitQ是一U由 junit.org 开发的开放源代码工具Q和 CactusQ由 Apache 开发的开放源代码工具Q对于测?J2EE lg都非常有用。[Hightower] 详细探讨了如何在 J2EE 中用这些工兗?/p> <p>管所有这些详qC怎样d地测试您的应用程序,但是我们仍然看到一些h认ؓ只要他们试?GUIQ可能是Z Web ?GUIQ或者是独立?Java 应用E序Q,则他们就全面地测试了整个应用E序。GUI 试很难辑ֈ全面的测试,有以下几U原因。首先,使用 GUI 试很难d地测试到pȝ的每一条\径,GUI 仅仅是媄响系l的一U方式,可能存在后台q算、脚本和各种各样的其他访问点Q这也需要进行测试。然而,它们通常q不h GUI。第二,GUI U的试是一U非常粗_度的测试。这U测试只是在宏观水^上测试系l的行ؓ。这意味着一旦发现存在问题,则与此问题相关的整个子系l都要进行检查,q得找?bugQ缺P是非常困难的事情。第三,GUI 试通常只有在整个开发周期的后期才能很好地得到测试,q是因ؓ只有q那个时?GUI 才得到完整的定义。这意味着只有在后期才可能发现潜在?bug。第四,一般的开发h员可能没有自动的 GUI 试工具。因此,当一个开发h员对代码q行更改Ӟ没有一U简单的Ҏ来重新测试受到媄响的子系l。这实际上不利于q行良好的测试。如果开发h员具有自动的代码U单元测试工P开发h员就能够很容易地q行q些工具以确保所做的更改不会破坏已经存在的功能。最后,如果d了自动构建功能,则在自动构徏q程中添加一个自动的单元试工具是非常容易的事情。当完成q些讄以后Q整个系l就可以有规律地q行重徏Qƈ且回归测试几乎不需要h的参与?/p> <p>另外Q我们必d调,使用 EJB ?Web 服务q行分布式的、基于组件的开发得测试单个的lg变得非常必要。如果没?#8220;GUI”需要测试,您就必须q行低Qlower-levelQ测试。最好以q种方式开始测试,省得当您分布式的组件或 Web 服务作ؓ您的应用E序的一部分Ӟ您不得不p心思重新进行测试?/p> <p>MQ通过使用自动的单元测试,能够很快地发现系l的~陷Qƈ且也易于发现q些~陷Q得测试工作变得更加系l化Q因此整体的质量也得以提高?/p> <p><strong><br /> 3. 按照规范来进行开发,而不是按照应用服务器来进行开发?br /> </strong>要将规范熟记于心Q如果要背离规范Q要l过慎密的考虑后才可以q样做。这是因为当您背规则的时候,您所做的事情往往q不是您应该做的事情?/p> <p>当您要背?J2EE 可以允许您做的事情的时候,q很Ҏ让您遭受不q。我们发现有一些开发h员钻研一?J2EE 允许之外的东西,他们认ؓq样做可?#8220;E微”改善J2EE的性能Q而他们最l只会发现这样做会引起严重的性能问题Q或者在以后的移植(从一个厂商到另一个厂商,或者是更常见的从一个版本到另一个版本)中会出现问题。实际上Q这U移植问题是如此严重Q以?[Beaton] 此原则UCؓUL工作的基本最佛_c?/p> <p>现在有好几个地方如果不直接?J2EE 提供的方法肯定会产生问题。一个常见的例子是开发h员通过使用 JAAS 模块来替?J2EE 安全性,而不是用内|的遵@规范的应用程序服务器机制来进行验证和授权。要注意不要q J2EE 规范提供的验证机Ӟ如果q了此规范Q这是pȝ存在安全漏洞以及厂商兼容性问题的主要原因。类似地Q要使用 servlet ?EJB 规范提供的授权机Ӟq且如果您要偏离q些规范的话Q要保使用规范定义?APIQ例?getCallerPrincipal()Q作为实现的基础。通过q种方式Q您能够利用厂商提供的强安全性基设施Q其中,业务要求需要支持复杂的授权规则?/p> <p>其他常见的问题包括用不遵@ J2EE 规范的持久性机Ӟq得事务管理变得困难)、在J2EEE序中用不适当的J2SE ҎQ例如线E或 singletonQ,以及使用您自qҎ解决E序到程序(program-to-programQ的通信Q而不是?J2EE 内在支持的机Ӟ例如 JCA、JMS ?Web 服务Q。当您将一个遵?J2EE 的服务器UL到其他的服务器上Q或者移植到相同服务器的新版本上Q上q的设计选择会造成无数的问题。唯一要背规范的情况是,当一个问题在规范的范围内无法解决的时候。例如,安排执行定时的业务逻辑?EJB2.1 出现之前是一个问题,在类DL情况下,我们当有厂商提供的解x案时׃用厂商提供的解决ҎQ例?WebSphere Application Server Enterprise 中的 Scheduler 工具Q,而在没有厂商提供的解x案时׃用第三方提供的工兗如果用厂商提供的解决ҎQ应用程序的l护以及其UL到新的规范版本将是厂商的问题Q而不是您的问题?/p> <p>最后,要注意不要太早地采用新技术。太q于热衷采用q没有集成到 J2EE 规范的其他部分或者还没有集成到厂商的产品中的技术常会带来灾难性的后果。支持是关键的——如果您的厂商不直接支持一U特定的?JSR 中提出的技术,但此技术还没有?J2EE 所接受Q那么您׃应该采用此技术。毕竟,我们中的大多Ch从事解决业务问题Q而不是推q技术的发展?/p> <p><strong><br /> 4. 从一开始就计划使用 J2EE 安全性?/strong> <br /> 启用 WebSphere 安全性。这使您?EJB ?URL 臛_可以让所有授权用戯问。不要问Z么——照着做就是了?/p> <p>在与我们合作的客户中Q一开始就打算启用 WebSphere J2EE 安全性的֮是非常少的,q一点一直让我们感到吃惊。据我们估计大约只有 50% 的顾客一开始就打算使用此特性。例如,我们曾与一些大型的金融机构Q银行、代理等{)合作q,他们也没有打启用安全性。幸q的是,q种问题在部|之前的查时得以解?</p> <p>不?J2EE 安全性是危险的事情。假设您的应用程序需要安全性(几乎所有的应用E序都需要)Q您敢打赌您的开发h员能够构建出自己的安全性系l,而这个系l比您从 J2EE 厂商那里买来的更好。这可不是个好的赌注Qؓ分布式的应用E序提供安全性是异常困难的。例如,您需要用网l安全加密o牌控制对 EJB 的访问。以我们的经验看来,大多数自己构建的安全性系l是不安全的Qƈ且有重大的缺Pq产品pȝ极其脆弱?/p> <p>一些不使用 J2EE 安全性的理由包括Q担心性能的下降,怿其他的安全性(例如 Netegrity SiteMinderQ可以取?J2EE 安全性,或者是不知?WebSphere Application Server 安全Ҏ及功能。不要陷入这些陷׃中,其是,管?Netegrity SiteMinder q样的品能够提供优U的安全特性,但是仅仅其自w不可能保护整个 J2EE 应用E序。这些品必M J2EE 应用E序服务器联合v来才可能全面C护您的系l?/p> <p>其他的一U常见的不?J2EE 安全性的原因是:Z角色的模型没有提供够的_度讉K控制以满_杂的业务规则。尽事实是q样的,但这也不应该成ؓ不?J2EE 安全性的理由。相反地Q应该将 J2EE 验证?J2EE 角色与特定的扩展规则l合h。如果复杂的业务规则需要做出安全性决{,那就~写相应的代码,其安全性决{要Z可以直接使用的以及可靠的 J2EE 验证信息Q用?ID 和角Ԍ?/p> <p><strong><br /> 5. 创徏您所知道的?/strong></p> <p>反复的开发工作将使您能够逐渐地掌握所有的 J2EE 模块。要从创建小而简单的模块开始而不是从一开始就马上涉及到所有的模块?/p> <p>我们必须承认 J2EE 是庞大的体系。如果一个开发小l只是开始?J2EEQ这很难一下子p掌握它。在 J2EE 中有太多的概念和 API 需要掌握。在q种情况下,成功掌握 J2EE 的关键是从简单的步骤开始做赗?/p> <p>q种Ҏ可以通过在您的应用程序中创徏而简单的模块来得到最好的实现。如果一个开发小l通过创徏一个简单的域模型以及后端的持久性机Ӟ也许使用的是 JDBCQ?q且对其q行了完整的试Q这会增Z们的自信心,于是他们会用该域模型去掌握使用 servlet ?JSP 的前端开发。如果一个开发组发现有必要?EJBQ他们也会类似地开始在容器理的持久?EJB lg之上使用单的会话 FacadesQ或者用基?JDBC 的数据访问对象(JDBC-based Data Access ObjectsQDAOQ,而不是蟩q这些去使用更加复杂的构造(例如消息驱动bean和JMSQ?/p> <p>q种Ҏq不是什么新ҎQ但是很有开发组以这U方式来培养他们的技能。相反地Q多数开发组׃试马上构建所有的模块Q同时涉?MVC 中的视图层、模型层和控制器层,q样做的l果是他们往往会陷入进度的压力之中。他们应该考虑一些敏PAgileQ开发方法,例如极限~程QXPQ,q种开发方法采用一U增量学习及开发方法。在 XP 中有一U称?ModelFirst 的过E,q个q程涉及到首先构建域模型作ؓ一U机制来l织和实现用户场景。基本说来,您要构徏域模型作为您要实现的用户场景的首要部分,然后在域模型之上构徏一个用L面(UIQ作为用户场景实现的l果。这U方法非帔R合让一个开发组一ơ只学到一U技术,而不是让他们同时面对很多U情况(或者让他们d多书Q,q会令他们崩溃的?/p> <p>q有Q对每个应用E序层重复的开发可能会包含一些适当的模式及最佛_c如果您从应用程序的底层开始应用一些模式如数据讉K对象和会?FacadesQ您׃应该在您的JSP和其他视囑֯象中使用域逻辑?/p> <p>最后,当您开发一些简单的模块Ӟ在开始的初期可以对您的应用E序q行性能试。如果直到应用程序开发的后期才进行性能试的话Q这往往会出现灾难性的后果?/p> <p><strong><br /> 6. 当?EJB lgӞ始终使用会话 Facades?/strong> <br /> 决不要将实体 bean 直接暴露lQ何用L型。对实体 bean 只可以用本?EJB 接口QLocal EJB interfacesQ?/p> <p>当?EJB lgӞ使用一个会?Facades 是一个确认无疑的最佛_c实际上Q这个通用的实践被q泛地应用到M分布式的技术中Q包?CORBA、EJB ?DCOM。从Ҏ上讲Q您的应用程序的分布“交叉区域”是底层化,对小块的数据׃多次重复的网l中l造成的时间消耗就少。要辑ֈq个目的的方法就是:创徏大粒度的 Facades 对象Q这个对象包含逻辑子系l,因而可以通过一个方法调用就可以完成一些有用的业务功能。这U方法不但能够降低网l开销Q而且?EJB 内部通过为整个业务功能创Z个事务环境也可以大大地减对数据库的讉Kơ数?/p> <p>EJB 本地接口Q从 EJB 2.0 规范开始用)为共存的 EJB 提供了性能优化Ҏ。本地接口必被您的应用E序昑ּ地进行访问,q需要代码的改变和防止以后配|?EJB 旉要应用程序的改变。由于会?Facades 和它包含的整?EJB 对于彼此来说都应该是本地的,我们对会?Facades 后面的实?bean 使用本地接口。然而,会话 Facades 本n的实玎ͼ典型例子如无状态会?beanQ应该设计ؓq程接口?/p> <p>Z性能的优化,可以一个本地接口添加到会话 Facades。这样做利用了这样一个事实:在大多数情况下(臛_?Web 应用E序中)Q您?EJB 客户端和 EJB 会共同存在于同一?Java 虚拟机(JVMQ中。另外一U情况,如果会话 Facades 在本地被调用Q可以?J2EE 应用服务器配|优化(configuration optimizationsQ,例如 WebSphere 中的“No Local Copies”。然而,您必L意到q些可供选择的方案会交互方法从按g递(pass-by-valueQ改变ؓ按引用传递(pass-by-referenceQ。这可能会在您的代码中生很微妙的错误。当您要利用q些ҎӞ您应该在一开始就考虑其可行性?/p> <p>如果在您的会?Facades 中用远E接口(而不是本地接口)Q您也可以将同样的会?Facades ?J2EE 1.4 中以兼容的方式作?Web 服务来配|。这是因?JSR 109QJ2EE 1.4 中的 Web 服务部v部分Q要求用无状态会?bean 的远E接口作?EJB Web 服务?EJB 实现的接口。这样做是值得的,因ؓq样做可以ؓ您的业务逻辑增加客户端类型的数量?/p> <p><strong><br /> 7. 使用无状态会?beanQ而不是有状态会?bean?/strong> <br /> q样做可以您的pȝl得起错误的l止。?HttpSession 存储和用L关的状态?/p> <p>以我们的观点看来Q有状态会?bean 的概念已l过时了。如果您仔细对其考虑一下,一个有状态会?bean 实际上与一?CORBA 对象在体pȝ构上是完全相同的Q无非就是一个对象实例,l定C个服务器Qƈ且依赖于服务器来理其生命周期。如果服务器关闭了,q种对象也就不存在,那么q个 bean 的客L的信息也׃存在?/p> <p>J2EE 应用服务器ؓ有状态会?bean 提供的故障{U(failoverQ能够解决一些问题,但是有状态的解决Ҏ没有无状态的解决Ҏ易于扩展。例如,?WebSphere Application Server 中,Ҏ状态会?bean 的请求,是通过寚w|无状态会话的成员集群q行q加蝲来实现。相反地QJ2EE 应用服务器不能对有状?bean 的请求进行^衡加载。这意味着您的集群中的服务器的加蝲q程会是不均衡的。此外,使用有状态会?bean 会再添加一些状态到您的应用服务器上Q这也是不好的做法。这样就增加了系l的复杂性,q且在出现故障的情况下问题变得复杂化。创建健壮的分布式系l的一个关键原则是量使用无状态行为?/p> <p>因此Q我们徏议对大多数应用程序用无状态会?bean Ҏ。Q何在处理旉要用的与用L关的状态应该以参数的Ş式传送到 EJB 的方法中Qƈ且通过使用一U机制如 HttpSession 来存储它Q或者从持久性的后端存储Q例如通过使用实体 bean)作ؓ EJB 事务的一部分来进行检索。在合适的情况下,q个信息可以~存到内存中Q但是要注意在分布式的环境中保存q种~存所潜在的挑战性。缓存非帔R合于只L据?/p> <p>MQ您要确保从一开始就要考虑到可伸展性。检查设计中的所有设惻Iq且考虑到当您的应用E序要在多个服务器上q行Ӟ是否也可以正常运行。这个规则不但适合上述情况的应用程序代码,也适用于如 MBean 和其他管理界面的情况下?/p> <p><strong><br /> 8. 使用容器理的事务?/strong></p> <p>学习一?J2EE 中的两阶D|交事务,q且使用q种方式Q而不是开放您自己的事务管理。容器在事务优化斚w几乎L比较好的?/p> <p>使用容器理的事务(CMTQ提供了两个关键的优势(如果没有容器支持q几乎是不可能的Q:可组合的工作单元和健壮的事务行ؓ?/p> <p>如果您的应用E序代码昑ּC用了开始和l束事务Q也怋?javax.jts.UserTransaction 或者甚x本地资源事务Q,而将来的要求需要组合模块(也许会是代码重构的一部分Q,q种情况下往往需要改变事务代码。例如,如果模块 A 开始了一个数据库事务Q更新数据库Q随后提交事务,q且有模?B 做出同样的处理,误虑一下当您在模块 C 中尝试用上qC个模块,会出C么情况呢Q现在,模块 C 正在执行一个逻辑动作Q而这个动作实际上调用两个独立的事务。如果模?B 在执行中p|了,而模?A 的事务仍然能被提交。这是我们所不希望出现的行ؓ。如果,相反圎ͼ模块 A 和模?B 都?CMT 的话Q模?C 也可以开始一?CMTQ通常通过配置描述W)Qƈ且在模块 A 和模?B 中的事务是同一个事务的隐含部分Q这样就不再需要复杂的重写代码的工作了?/p> <p>如果您的应用E序在同一个操作中需要访问多U资源,您就要用两阶段提交事务。例如,如果?JMS 队列中删除一个消息,q且随后更新Zq条消息的纪录,q时Q要保证q两个操作都会执行或都不会执行就变得ؓ重要。如果一条消息已l从队列中被删除Q而系l没有更C此消息相关的数据库中的纪录,那么q种pȝ是不E_的。一些严重的客户及商业纠Uh自不一致的状态?/p> <p>我们时常看到一些客户应用程序试囑֮C们自q解决Ҏ。也怼通过应用E序的代码在数据库更新失败的时?“撤销”寚w列的操作。我们不提倡这样做。这U实现要比您最初的惌要复杂得多,q且q有许多其他的情况(惌一下如果应用程序在执行此操作的q程中突然崩溃的情况Q。作为替代的方式Q应该用两阶段提交事务。如果您使用 CMTQƈ且在一个单一?CMT 中访问两阶段提交的资源(例如 JMS 和大多数数据库)QWebSphere 会处理所有的复杂工作。它确保整个事务被执行或者都不被执行Q包括系l崩溃、数据库崩溃或其他的情况。其实现在事务日志中保存着事务状态。当应用E序讉K多种资源的时候,我们怎么使用 CMT 事务的必要性都不ؓq?/p> <p><strong><br /> 9. ?JSP 作ؓ表示层的首选?/strong></p> <p>只有在需要多U表C出类型,q且输出cd被一个单一的控制器及后端支持时才?XML/XSLT?/p> <p>我们常听C些争Qؓ什么您选择 XML/XSLT 而不?JSP 作ؓ表示层技术。选择 XML/XSLT 的h的观ҎQJSP“ 允许您将模型和视图؜合在一?#8221;Q?XML/XSLT 不会有这U问题。遗憄是,q种观点q不完全正确Q或者至不像白与黑那样分的清楚。实际上QXSL ?XPath 是编E语a。XSL 是图灵完成的QTuring-completeQ,管它不W合大多Ch定义的编E语aQ因为它是基于规则的Qƈ且不具备E序员习惯的控制工具?/p> <p>现在的问题是既然l予了这U灵zL,开发h员就会利用这U灵zL。尽每个h都认?JSP 使开发h员容易在视图中加?#8220;cM模型”的行为,而实际上Q在 XSL 中也有可能做Z些同L事情。尽从 XSL 中进行访问数据库q样的事情会非常困难Q但是我们曾l见到过一些异常复杂的 XSLT 样式表执行复杂的转换Q这实际上是模型代码?/p> <p>然而,应该选择 JSP 作ؓ首选的表示技术的最基本的原因是QJSP 是现在支持最q泛的、也是最被广泛理解的 J2EE 视图技术。而随着自定义标记库、JSTL ?JSP2.0 的新Ҏ的引入Q创?JSP 变得更加ҎQƈ且不需要Q?Java 代码Q以及可以将模型和视图清晰的分离开。在一些开发环境中Q如 WebSphere StudioQ加入了?JSPQ包括对调试的支持)的强大支持,q且许多开发h员发C?JSP q行开发要比?XLS 单,一些支?JSP 的图形设计工具及其他特征Q尤其在 JSF q样的框架下Q得开发h员可以以所见即所得的方式q行 JSP 的开发,而对?XSL 有时不容易做到?/p> <p>最后一个要谨慎考虑使用 JSP 的原因是速度问题。在 IBM 所作的Ҏ XSL ?JSP 相对速度的性能试昄Q在大多数情况下QJSP 在生成同L HTML 的时候,要比 XSL 快好几倍,甚至使用~译q的 XSL 也是如此。尽多数情况下q不是问题,但在性能要求很高的情况下Q这׃成ؓ问题?/p> <p>然而,q也不能_您永q也不要使用 XSL。在一些情况下QXSL 能够表示一l固定的数据Qƈ且可以基于不同的样式表来以不同的方式昄q些数据的能力是昄视图的最佌x案。然而,q只是一U例外的情况Q而不是通用的规则。如果您只是生成 HTML 来表达每一个页面,那么在大多数情况下,XSL 是一U不必要的技术,q且Q它l您的开发h员所带来的问题远比它所能解决的问题多?/p> <p><strong><br /> 10. 当?HttpSession Ӟ量只将当前事务所需要的状态保存其中,其他内容不要保存?HttpSession 中?/strong></p> <p>启用会话持久性?/p> <p>HttpSessions 对于存储应用E序状态信息是非常有用的。其 API 易于使用和理解。遗憄是,开发h员常帔R忘了 HttpSession 的目的——用来保持暂时的用户状态。它不是L的数据缓存。我们已l见到过太多的系lؓ每个用户的会话放入了大量的数据(辑ֈ兆字节)。那好了Q如果同时有 1000 个登录系l的用户Q每个用h?1MB 的会话数据,那么需?1G 或者更多的内存用于q些会话。要使这?HTTP 会话数据较小一些,不然的话Q您的应用程序的性能会下降。一个大U比较合适的数据量应该是每个用户的会话数据在 2K-4K 之间Q这不是一个硬性的规则Q?K 仍然没有问题Q但是显然会?2K 时的速度要慢。一定要注意Q不要 HttpSession 变成数据堆积的场所?/p> <p>一个常见的问题是?HttpSession ~存一些很Ҏ再创建的信息Q如果有必要的话。由于会话是持久性的Q进行不必要的序列化以及写入数据是一U很奢侈的决定。相反地Q应该用内存中的哈希表来缓存数据,q且在会话中保存一个对此数据进行引用的关键字。这P如果不能成功d到另外的应用服务器的话,可以重新创建数据?/p> <p>当谈及会话持久性时Q不要忘记要启用q项功能。如果您没有启用会话持久性,或者服务器因ؓ某种原因停止了(服务器故障或正常的维护)Q则所有此应用服务的当前用L会话会丢失。这是g令h非常不高兴的事情。用户不得不重新dQƈ且重新做一些他们曾l已l做q的事情。相反地Q如果启用了会话持久性,WebSphere 会自动将用户Q以及他们的会话Q移到另外一个应用服务器上去。用L至不知道会有q种事情的发生。我们曾l见到过一些品系l因为存在于本地代码中o人难以忍受的 bugQ不?IBM 的代码!Q而突然崩溃的情况Q这q种情况下,上述功能仍然可以q行良好?/p> <p><strong><br /> 11. ?WebSphere 中,使用动态缓存,q?WebSphere servlet ~存机制.</strong></p> <p>通过使用q些功能Q系l性能可以得到很大的提高,而开销是很的。ƈ且不影响~程模型?/p> <p>通过~存来提高性能的好处是众所周知的事情。遗憄是,当前?J2EE 规范没有包括一U用?servlet/JSP ~存的机制。然而,WebSphere 提供了对面以及片断~存的支持,q种支持是通过其动态缓存功能来实现的,q且不需要对应用E序作出M改变。其~存的策略是声明性的Q而且光|是通过 XML 配置描述W来实现的。因此,您的应用E序不会受到影响Qƈ保持?J2EE 规范的兼Ҏ和UL性,同时q从 WebSphere ?servlet ?JSP 的缓存机制中得到性能的优化?/p> <p>?servet ?JSP 的动态缓存机制得到的性能的提高是显而易见的Q这取决于应用程序的Ҏ。Cox ?Martin [Cox] 指出对一个现有的 RDFQ资源描q格式)站点摘要 (RSS)servletQ当使用动态缓存时Q其性能可以提高 10%。请注意q个实验只涉及到一个简单的 servletQ这个性能的增镉K可能q不能反映一个复杂的应用E序?/p> <p>Z更多地提高性能Q将 WebSphere servlet/JSP l果~存?WebSphere 插g ESI Fragment 处理器、IBM HTTP Server Fast Response Cache Accelerator (FRCA) ?Edge Server ~存功能集成在一赗对于繁重的Zd的工作负P通过使用q些功能可以得到许多额外的好处?/p> <p><strong><br /> 12. Z提高E序员的工作效率Q将 CMP 实体 bean 作ؓ O/R 映射的首选解x?</strong></p> <p>通过 WebSphere 框架Qreadahead、缓存、隔ȝ别等Q优化性能。如果可能,有选择的应用一些模式来辑ֈ提高性能的目的,例如 Fast-Lane 阅读?[Marinescu]?/p> <p>对象/关系QO/RQ映是使用 Java 创徏企业U的应用E序的基。几乎每?J2EE 应用E序都需要一些类型的 O/R 映射。J2EE 厂商提供一U?O/R 映射机制Q这U机制在不同的厂商间是可UL的,高效的,q且能够被一些标准及工具很好地支持。这是 EJB 规范中的 CMPQ容器管理的持久性)部分?/p> <p>早期?CMP 实现以表C佛_不支持许?SQL l构而著U。然而,随着 EJB 2.0 ?2.1 规范的出玎ͼ以及被一些厂商所采纳Qƈ且随着?IBM WebSphere Studio Application Developer 的出玎ͼq些问题已经不再是问题了?/p> <p>CMP EJB lg现在已经被广泛地应用于许多高性能的应用程序中。WebSphere 包括一些优化功能以提高 EJB lg的性能Q优化功能包括:对生命周期的~存?read-ahead 能力。这两者优化功能都是配|时的选项Qƈ且不需要对应用E序q行修改或者媄响可UL性?/p> <p>处于~存状态的生命周期~存 CMP 状态数据ƈ提供Z旉的无效性。从处于~存状态的生命周期得到的性能提高可以辑ֈ选项 A 的缓存性能Qƈ且仍然可以ؓ您的应用E序提供可展性。Read-ahead 能力和容器管理的关系l合使用。这个特性通过在相同的查询中随意地索相关的数据作ؓ父数据而减与数据库的交互。如果相关的数据要通过使用q发的查询来讉K的话Q这U方法可以得到性能的改q。[Gunther]提供了详l的描述以及通过q些Ҏ得到的性能提高的细节?/p> <p>此外Qؓ了完全优化您?EJB lgQ当指定隔离U别时要特别注意。尽可能使用最低的隔离U别Qƈ且仍然保持您的数据的完整性。较低的隔离U别可以提供最佳的性能Qƈ且可以降低出现数据库死锁的危险?/p> <p>q是目前最有争议的最佛_c已l有大量的文章赞?CMP EJBQ同L贬斥C不绝于耟뀂然而,q里最基本的问题是数据库开发是困难的。当您开始用Q何持久性解x案之前,您需要掌握查询以及数据库锁定如何工作q些基础知识。如果您选择使用 CMP EJBQ您要确保您已经通过一些书c(例如 [Brown] ?[Barcia]Q知道如何用它们。在锁定及争用方面有一些微妙的交互难以理解Q但是,在您耗费一定的旉及努力后会将其掌握的?/p> <p><strong><br /> l束?/strong></p> <p>在这个简短的摘要中,我们已经向您介绍?J2EE 中的核心模式和最佛_践,q?J2EE 开发成ZU可理的过E。尽我们ƈ没有l出所有在实践中用这些模式的必要l节Q但是我们希望能够给您够的指点和指|以帮助您军_下一步要做什么?/p> <img src ="http://www.aygfsteel.com/isoft/aggbug/172475.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/isoft/" target="_blank">梦򋹁星</a> 2008-01-03 14:25 <a href="http://www.aygfsteel.com/isoft/archive/2008/01/03/172475.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ض</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">½</a>| <a href="http://" target="_blank">żҿ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ѯ</a>| <a href="http://" target="_blank">ƺ</a>| <a href="http://" target="_blank">֣</a>| <a href="http://" target="_blank">ʯ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ׯ</a>| <a href="http://" target="_blank">Ƽ</a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ͼƬ</a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">³</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">΢ɽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Զ</a>| <a href="http://" target="_blank">ɰ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ϫ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">կ</a>| <a href="http://" target="_blank">γ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>