再译:wiring your web application...中的难点、疑点

1、Building non-trivial web applications with Java is no trivial task.

2、where the business logic will reside

3、how to enforce a consistent design across all application layers

4、Each application layer should be isolated from other layers but allow an interface for communication between them.

5、Assembling a model that can be presented in a view.

6、 type coupling

7、“allow”的使用: In particular, the Hibernate framework allows object-to-relational persistence and query service for Java.

8、This is not the correct place because it leads to tightly coupled applications and code that can be hard to maintain over time.

9、“allow”的使用:This layer allows developers to stop building and maintaining unnecessary data transfer objects, or DTOs, to match their domain objects.

10,,This model allows Java developers to work with objects naturally in an OO fashion without additional coding.

11. allows for easier maintenance when troubleshooting

12.Inversion of control is a simple concept that allows objects to accept other objects that are created at a higher level.

13.Since Hibernate works with POJOs we will use our domain objects for persistence.

14.Here is the interface for the business service object that is stubbed for a DAO object dependency

[转]2005年IT人士生存状态

来源:《世界商业评论》ICXO.COM   发表时间:2006-01-03 12:19 

 

网易原代理CEO孙德棣离去的脚步声尚在人间回荡,嗒嗒声还在耳边萦绕,天堂居然又传来噩耗:“我们万分痛心地通知您,前任IBM大中华区政府及公众事业部总经理李清平先生,由于突发心肺衰竭,抢救无效,于今天凌晨四点在北京中医院不幸去世,享年46岁。”

  消息传出,人们已经不再如孙德棣去世时那么感性,当初各大网站不约而同地以头条加以祭奠的讣告没有再现,在经过一次又一次的打击后,大家已经从原来的感性伤怀,转而变为理性的反省。在IT世界网一位朋友告诉我李清平先生去世的消息时,我也没有当初的感伤,无语之余,兴起了盘点今年IT人士生存状态念头。

  薪酬呈两极分化 中低层工资不升反降

  其实IT行业员工的工资并没有想象得那样高。一位高校管理学教授曾列了一个各行各业工资比较公司,据他分析,以上海为例,IT行业的平均工资仅仅2400元左右,其水平远远低于其他热门行业。并且,与其他行业不同的是,IT行业工资很少提升,即使有提升幅度也非常小。

  其实,IT行业不仅平均工资水平不高,波动幅度也非常之大,IT内部各行业之间、高层与中低层之间的薪酬差距,无法以里计。调查显示,在IT行业中,月薪上万元的,比例非常之小;月薪在5000-8000元的,通信设备以及手机制造业占14.3%,计算机硬件行业占11.25%,计算机软件行业占48.75%,互联网及电子商务行业、电子及微电子技术行业、电信运营商及服务行业占25.6%;月薪在3000-5000元的,通信设备以及手机制造业占9.7%,计算机硬件行业占16.8%,计算机软件行业占46.5%,互联网及电子商务行业、电子及微电子技术行业、电信运营商及服务行业占27%;月薪范围在3000元以下的,通信设备以及手机制造业占4.7%,计算机硬件行业占26.7%,计算机软件行业占35.3%,互联网及电子商务行业、电子及微电子技术行业、电信运营商及服务行业占33.2%。

  就目前来说,网络安全、网络游戏、软件测试工程师和研究人员是IT行业的需求热点,也是工资待遇较高的岗位。

  而在高层与中低层之间,差距更为明显。据一份针对深圳地区IT界人士薪酬的调查显示,企业高管的平均工资在12000元以上,人数占2%;中层管理人员的工资在8000元左右,人数占13%;而基层人员只有3000元左右,人数却占了85%。

  从以上数据我们可以看出,在不同行业和不同职位,薪资相差很大。那些拿高工资的人数所占比例也非常小,大部分员工还是拿着较低的工资。并且,由于IT行业除了级别变动所产生的工资变动外,工资年增幅是非常小的,按物价折算后,中低层员工的工资呈现不升反降的趋势。

  当然,也有人表示,由等级带来的大幅工资差别,可以给年轻人更多的压力和动力,刺激他们努力拼搏,积极向上。

  西门子索尼启动IT裁员热潮 下岗成IT人口头禅

  6月27日上午,西门子上海移动通信有限公司召开全体员工大会,会上宣布裁员80%。其实,早在明基宣布收购西门子手机业务前两天,上海方面的工作已陷入全面停顿,员工们都在积极“申请”被“裁掉”,以期望拿到N+X的补偿。最初,西门子方面裁掉的主要是市场销售人员,没有涉及到技术人员。然而,在裁员的压力下,出现700多的技术人员集体辞职现象,为安抚大家,西门子和明基方面一致表示不再裁员。明基总裁李?耀在接受媒体采访时曾表示,明基在收购西门子手机部门之后两年内不裁员。然而,在商言商,当收购最终确认后,150多人的销售队伍还是被无情地抛弃了。

  其实,明基之所以接下国际巨头们不愿考虑的西门子手机业务烂摊子,主要就是看中了西门子的手机技术,而技术人员显然是这次并购的关键。如果700多名研发人员集体辞职的话,明基按协议虽可获得西门子核心技术的所有权,但依然没有太大的意义。

  无独有偶,此后不久,索尼新任CEO霍华德?斯丁格也向外界公布酝酿已久的战略调整方案,将对15项业务进行缩减、整合或退出,还将在全球关闭11家工厂,到2007财年末在全球裁员1万人,并削减约合18亿美元的支出。幸运的是,索尼中国方面表示,这次调整在中国不仅没有裁员计划,反而根据业务的继续拓展将会相应增加人员。

  西门子裁员是因为手机业务不理想,还有迹可循,索尼裁员更让员工忧心,因为这种因战略调整发生的裁员实在很难把握。对IT人士来说,不得不面对的可能就是这种难以预料的被迫离职。

  今年以来,除西门子和索尼以外,IBM、爱立信、摩托罗拉、甲骨文、日本先锋公司、松下、柯达、三洋电子、奥林巴斯、UT斯达康等大批国际企业都实施了裁员。裁员风波弥漫于业界,令业界人士惶惶不可终日。“UT斯达康的裁员计划则涉及了中国员工近800人,这对习惯了安稳生活的中国员工来讲,无疑是一场风暴。”当斯达康确定裁员后,其内部一位人士表示。

  而由裁员引发的员工忠诚度下降也是不争的事实。或许真像一位朋友所说的,当IT裁员成为一种文化,IT人员的下岗、待业、跳槽和由此而生的纠纷,都成了不可避免的负面现象。然而,对企业来说,要承担由此而来的成本;而对员工来说,更是要承受由前途不可知性所带来的生理和心理压力。

孙德棣李清平奔赴天堂 见证IT人工作压力

  9月21日,门户网站不约而同地用黑色字体做成

  专题,掀起了集体悼念刚刚与世长辞的网易代理首席执行官、年仅38岁的孙德棣。据网易内部人士介绍,近年以来,孙德棣一直靠打点滴坚持工作的。其压力之巨大,志向之高远,令人慨叹。其实,早在去年4月15日,网易就曾公布孙德棣因病休养的消息。但是,面对公司业务压力,孙德棣选择了带病工作。

  孙德棣过世尚不足三月,没想到李清平居然又走向了天堂。孙德棣走后,博客网CEO方兴东曾表示“人生如狗”,他引述国外一位作者的说法:“互联网的时间尺度是以狗年来计算的,我们的一年相当于普通人的7年。”他认为应该警惕互联网的节奏,因为“使命和理想很重要,但是生命依然高于一切”。而一位业外人士的话更让人警醒,他表示:“其实IT行业的工资并不是天生就比别的行业高,按时间进行等价计算的话,IT人的工资并不高,而按八小时工作制外应看作是加班来算的话,则不是不高,而是很低了。”在笔者看来,这种说法值得肯定。它让我们意识到,其实IT界人士的工资并不是像我们想象的那样高,因此,为了维持高工资而玩命工作的做法并不可取。

  当初刚开始实行八小时工作制的时候,人们无不高兴异常,因为在生活改善以后,终于有了消遣和娱乐的时间。但是,随着时间的推移,大家逐渐习惯了八小时工作制的事实,忘记了八小时工作制实施的初衷,曾经的激动、兴奋都已不复存在。随之而来的,便是对工作时间的回归,在大家潜意识里,八小时工作制好像成了变相的提高工作。对IT行业来说,八小时工作制早就名存实亡,各种名义的加班让我们疲于奔命。

  作为IT行业的评论人士,笔者每天下班之余都挂在网上,因此得以见证IT人士的在线时间。据一项调查显示,IT行业内普遍存在着工作超负荷现象。每天工作8小时以上者的比例高达77.8%,其中每天工作11小时以上者比例竟有22.5%.95%的公司白领处于亚健康状态,尤其是高科技行业、IT行业人士。如此的操劳带来的就是过劳死、疾病和亚健康。

  北京协和医院张医生指出,IT人士长期接触电脑,很容易带来肥胖、下肢静脉曲张、颈椎病、腰椎间盘突出、神经衰弱等疾病。而且由于激烈的就业竞争,使他们长期高强度、超负荷的劳心劳力,精神总是处于高度紧张的状态。

  孙德棣走后,王峻涛特地严格了公司的规章制度,没有特殊或重大事件,所有员工都不得加班。“我决定今天改一改,提前一小时回家,看看天会不会真的塌下来。”王峻涛说:“其实事情永远是做不完的,钱也是永远赚不完的。换一个角度来看,IT业界的机会也是最多的。错过了一个,也很快会涌现出下一个。”

  我想什么时候每个IT业的老板都能这样对待员工,每一位IT员工都能这样对待自己了,IT行业也就成熟了。

  华为联想引领国际化潮流 中国IT人走向世界

  国内企业中,华为无疑是国际化的代表。华为有一条内部定律,那就是只要是国际通讯大展,华为一个不落都要参加。每年几乎要参加20多个大型国际展览,每年在参展上的投入至少是一个亿。2005年上半年,华为实现全球销售额330亿元人民币,国际销售达24亿美元多。当前,华为成功入选英国电信(BT)“二十一世纪网络”的名单;与全球著名电信运营商Telefónica在西班牙马德里的首相府正式签署协议,双方还将携手拓展拉美地区市场;与沃达丰正式签署全球采购框架协议,华为将参与沃达丰的移动网络建设,这是中国通讯设备制造商第一次进入全球电信业最顶级“俱乐部”;近日,马来西亚电信宣布,将与华为携手开发用于通信业内的软件及应用产品。已在海外开疆拓土近10年的华为,无疑是中国企业国际化的排头兵和领航人。

  如果说华为是老牌国际化的代表,那么联想则是新兴国际化企业的典型。近日,上任尚不到一年的原总裁兼CEO沃德离职,原戴尔高级副总裁阿梅里奥接任。就在业界议论纷纷之时,联想内部已经表示,这是联想国际化、尤其是开发亚洲市场的首选。随着2006年都灵冬奥会的日益临近,联想目前已经启动了奥运战略,据说,联想的Lenovo品牌将在冬奥会期间正式推向国际市场。而此前,联想笔记本宽屏暨寒促策略发布会在香港迪士尼乐园隆重上市。据媒体披露,这是联想首次在大陆市场以外召开寒促发布会,其实是联想放出了攻占亚太市场的信号。

  而联想收购IBM PC可能更具有国际意义,毕竟这对国内企业来说还是首例。而联想据此走向国际的战略路线图,对国内企业更是具有较大的借鉴意义。众所周知,华为收购马可尼、海尔收购美国美泰,都曾遭遇所在国政府的堵截,因此,联想收购IBM PC的战略意义远大于实践意义。正因为此,柳传志才成为中国第一位荣获“推动美中关系杰出贡献人士”称号,而在由《中国企业家》举办的“2005最具影响力企业领袖”评选中,他也由去年的第二上升到第一位。IDC中国区总裁万宁就表示,联想目前已经算是国际化公司了。

  其实,近年来中国IT行业整体上正处于走出去的高峰期,包括像百度等互联网企业赴海外上市,其实都属于国际化的范畴。而随着国内IT企业的国际化步伐加大,国内IT行业人士也日益跨出国门,走上了与国际接轨的康庄大道。

  高级人才成香饽饽 “软件蓝领”奇缺

  据人力资源调研机构报告显示,IT业求职人员现状与用人需求存在严重的结构失衡,需求量明显呈金字塔型分布:高级IT人才相对缺乏,中端的研发设计销售人员略多,最为欠缺的是一大批从事低端开发和操作的所谓“数字蓝领”、“软件蓝领”。

  当然,这也不是中国IT行业的特色,蓝领奇缺是世界IT业面临的共性问题,无论是在软件大国美国和印度,还是在一些发展中国家,人才构成都呈金字塔结构。但是,与一些发展国家相比,发展中国家由于受发达国家的人才掠夺,IT蓝领的缺口更大。

  正因为此,IT行业的高级人才、尤其是高级技术人才,是业界最受欢迎的。当前,微软、Google和雅虎中国在中国高校掀起的招聘热潮,其主要招聘对象就是技术人员,彰显出国内外IT巨头对技术人员的青睐。作为尚处于发展中的IT行业来说,短期内技术肯定是决定因素,因此技术人员也必将是IT行业的主导性人才。

  IT人的生存现状,昭示着IT行业的繁荣或衰败;IT人的流动,暗示了IT业的发展走向。面对IT行业一夜暴富的神话,充满和追求的青年后生不可能不心动。然而,像百度员工那样,一夜之间就冒出几个亿万富翁,几百个千万富翁的例子,毕竟还是少数。因此,为了IT行业的持续繁荣,为了IT人的远大理想,我们还是应该悠着点,不为别的,就为了自己的健康、家人的幸福和生命的终极意义。

 

 

结合重译wiring web application with open source java学习Spring...

  学习其中的内容。

  totodo在2004年9月就已经翻译了这篇文章,总体还可以。我准备重译的同时学习文中的用Struts+Spring+Hibernate构建web应用。今天下载了文中的源码。

  我觉得当前在完善学习日记用户界面和重译这篇文章这两件事之间,重译和学习这篇文章应该优先。

再译Wiring Your Web Application with Open Source Java

(由admin转自:http://www.onjava.com/pub/a/onjava/2004/04/07/wiringwebapps.html)

[注:这个翻译任务是从matrix的文档wiki那里看到的,我的英文水平只能勉强看懂,但是翻译它是一举三得:学技术、学英语、为网络学习作贡献,听说这篇文章在csdn上有人翻译了,可我就是没有找到,有人找到了在这里告诉一下,以免大家重复劳动。我采用从粗到精的翻译方法,先忽略细节,按我的理解粗翻一遍,然后再请大家指正,精确化细节问题。-admin ]

[原来totodo已经翻译了这篇文章|#7]译者注:今天再次在google上用文中的包关键字"com.meagle.bo""com.meagle.service.dao.hibernate"搜索了一下(上次用的关键字是"Wiring Your Web Application with Open Source Java""中文",结果没有找到,大家吸取我的教训哦:)),发现totodo在2004年就已经翻译了这篇文章([使用struts+spring+hibernate 组装web应用|http://www.matrix.org.cn/resource/article/1034.html])。总体翻译得还可以,但是也有不少没有忠于原文甚至错误的地方(我想,我的错误也许更多:)。现在我将结合两篇译文来修改、精确化中文译文,并希望在大家的指点下,得到一篇精确忠于原作者意图的译文。

  -admin 2006.1.3 14:02

Tags: java spring struts hibernate programming

Bookmark with del.icio.us

  

Wiring Your Web Application with Open Source Java

by Mark Eagle

04/07/2004

用Java开源技术构建你的web应用

Building non-trivial web applications with Java is no trivial task. There are many things to consider when structuring an architecture to house an application. From a high-level, developers are faced with decisions about how they are going to construct user interfaces, where the business logic will reside, and how to persist application data. Each of these three layers has their own questions to be answered. What technologies should be implemented across each layer? How can the application be designed so that it is loosely coupled and flexible to change? Does the architecture allow layers to be replaced without affecting other layers? How will the application handle container level services such as transactions?

  其实,就算用Java建造一个不是很烦琐的web应用,也不是件轻松的事情。 在构架的一开始就有很多事情要考虑。 从高处看,摆在开发者面前有很多问题:要考虑是怎样建立用户接口?在哪里处理业务逻辑? 怎样持久化的数据。 而这三层构架中,每一层都有他们要仔细考虑的。 各个层该使用什么技术? 怎样的设计能松散耦合还能灵活改变? 怎样替换某个层而不影响整体构架?应用程序如何做各种级别的业务处理(比如事务处理)?

   其实,就算用Java建造一个不是很烦琐的web应用程序,也不是件轻松的事情。当为一个应用程序建造一个构架时有许多事情需要考虑。从高层来说,开发者需要考虑:怎样建立用户接口(user interfaces)?在哪里处理业务逻辑?和怎样持久化应用数据。这三层每一层都有它们各自的问题需要回答。 各个层次应该使用什么技术?怎样才能把应用程序设计得松耦合和能灵活改变?构架允许层的替换不会影响到其它层吗?应用程序怎样处理容器级的服务(container level services),比如事务处理(transactions)?

There are definitely a number of questions that need to be addressed when creating an architecture for your web application. Fortunately, there have been developers that have run into these reoccurring problems and built frameworks to address these issues. A good framework relieves developers from attempting to reinvent the wheel for complex problems; it is extensible for internal customization; and it has a strong user community to support it. Frameworks generally address one problem well. However, your application will have several layers that might require their own framework. Just solving your UI problem does not mean that you should couple your business logic and persistence logic into a UI component. For example, you should not have business logic with JDBC code inside of a controller. This is not the functionality that a controller was intended to provide. A UI controller should be a lightweight component that delegates calls to other application layers for services outside the UI scope. Good frameworks naturally form guidelines where code should be placed. More importantly, frameworks alleviate developers from building code such as persistence from scratch and allow them to concentrate on the application logic that is important to a client.

  构架一个Web应用需要弄明白好多问题。 幸运的是,已经有不少开发者已经遇到过这类问题,并且建立了处理这类问题的框架。 一个好框架具备以下几点: 减轻开发者处理复杂的问题的负担(“不重复发明轮子”); 内部有良好的扩展; 并且有一个支持它的强大的用户团体。 好的构架一般有针对性的处理某一类问题,并且能将它做好(Do One Thing well)。 然而,你的程序中有几个层可能需要使用特定的框架,已经完成的UI(用户接口) 并不代表你也可以把你的业务逻辑和持久逻辑偶合到你的UI部分。 举个例子, 你不该在一个Controller(控制器)里面写JDBC代码作为你的业务逻辑, 这不是控制器应该提供的。 一个UI 控制器应该委派给其它给在UI范围之外的轻量级组件。 好的框架应该能指导代码如何分布。 更重要的是,框架能把开发者从编码中解放出来,使他们能专心于应用程序的逻辑(这对客户来说很重要)。

  当为你的web应用程序创建一个构架时,需要涉及到相当多的问题。幸运的是,已经有不少开发者已经遇到过这类重复发生的问题,并且建立了处理这类问题的框架。一个好框架具备以下几点: 减轻开发者处理复杂的问题的负担(“不重复发明轮子”);内部定义为可扩展的;有一个强大的用户群支持。框架通常能够很好的解决一方面的问题。然而,你的应用程序有几个层可能都需要它们各自的框架。就如解决你的用户接口(UI)问题时你就不应该把事务逻辑和持久化逻辑掺杂进来。例如,你不应该在控制器(controller)里面写jdbc代码,使它包含有业务逻辑,这不是控制器应该提供的功能。它应该是轻量级的,代理来自用户接口(UI)外的调用请求给其它服务于这些请求的应用层。好的框架自然的形成代码如何分布的指导。更重要的是,框架减轻开发者从头开始写像持久层这样的代码的痛苦,使他们专注于对客户来说很重要的应用逻辑。

This article will discuss how to combine several well-known frameworks to achieve loose coupling, how to structure your architecture, and how to enforce a consistent design across all application layers. The challenge is combining frameworks so that each layer is exposed to each other in a loosely coupled manner, regardless of the underlying technologies. This article will discuss one strategy for combining frameworks using three popular open source frameworks. For the presentation layer we will use Struts; for our business layer we will use Spring; and for our persistence layer we will use Hibernate. You should be able to substitute any one of these frameworks in your application and get the same effect. Figure 1 shows what this looks like from a high level when the frameworks are combined.

  这篇文章将讨论怎样结合几种著名的框架来使得你的应用程序做到松弛耦合。 如何建立你的架构,并且怎样让你的各个应用层保持一致。?如何整合框架以便让每个层在以一种松散偶合的方式彼此作用而不用管低层的技术细节?这对我们来说真是一种挑战。 这里讨论一个整合框架的策略( 使用3 种受欢迎的开源框架) :表示层我们用Struts; 业务层我们用Spring;而持久层则用Hibernate。 你也可以用其他FrameWork替换只要能得到同样的效果。 见图1 (框架组合示意图)

  这篇文章将怎样组合几个著名的框架去做到松耦合的目的,怎样建立你的构架,怎样让你的各个应用层保持一致。富于挑战的是:组合这些框架使得每一层都以一种松耦合的方式彼此沟通,而与底层的技术无关。这篇文章将使用3种流行的开源框架来讨论组合框架的策略。表现层我们将使用Struts;业务层我们将使用Spring;持久层使用Hibrenate.你也可以在你的应用程序中替换这些框架中的任何一种而得到同样的效果。图1展示了当这些框架组合在一起时从高层看是什么样子。

Figure 1. Overview of framework architecture with Struts, Spring, and Hibernate.

图1用Struts, Spring, 和 Hibernate框架构建的概览

Application Layering

Most non-trivial web applications can be divided into at least four layers of responsibility. These layers are the presentation, persistence, business, and domain model layers. Each layer has a distinct responsibility in the application and should not mix functionality with other layers. Each application layer should be isolated from other layers but allow an interface for communication between them. Let's start by inspecting each of these layers and discuss what these layers should provide and what they should not provide.

应用程序的分层

大部分的Web应用在职责上至少能被分成4层。 这四层是:presentation(描述),persistence(持久),business(业务)和domain model(域模块)。每个层在处理程序上都应该有一项明确的责任, 而不应该在功能上与其它层混合,并且每个层要与其它层分开的,但要给他们之间放一个通信接口。 我们就从介绍各个层开始,讨论一下这些层应该提供什么,不应该提供什么。

应用程序的分层

大多数不复杂的web应用都能被分成至少4个各负其责的层次。这些层次是:表现层(presentation)、持久层(persistence)、业务层(business)、领域模型层(domain model)。每层在应用程序中都有明确的责任,不应该和其它层混淆功能。每一应用层应该彼此独立但要给他们之间放一个通信接口。让我们从审视各个层开始,讨论这些层应该提供什么和不应该提供什么。

The Presentation Layer

表示层(The Presentation Layer)

表现层 (The Presentation Layer)

  

At one end of a typical web application is the presentation layer. Many Java developers understand what Struts provides. However, too often, coupled code such as business logic is placed into an org.apache.struts.Action. So, let's agree on what a framework like Struts should provide. Here is what Struts is responsible for:

  一般来讲,一个典型的Web应用的的末端应该是表示层。 很多Java发者也理解Struts所提供的。 象业务逻辑之类的被打包到org.apache.struts.Action., 因此,我们很赞成使用Struts这样的框架。

  在一个典型的web应用的一端是表现层。很多Java开发者也理解Struts所提供的。然而,太常见的是,他们把像业务逻辑之类的耦合的代码放进了一个org.apache.struts.Action。所以,让我们在像Struts这样一个框架应该提供什么上取得一致意见。这儿是Struts负责的:

Managing requests and responses for a user.

Providing a controller to delegate calls to business logic and other upstream processes.

Handling exceptions from other tiers that throw exceptions to a Struts Action.

Assembling a model that can be presented in a view.

Performing UI validation.

下面是Struts所负责的:

* 管理用户的请求,做出相应的响应。

* 提供一个Controller ,委派调用业务逻辑和其它上层处理。

* 处理异常,抛给Struts Action

* 为显示提供一个模型

* UI验证。

为用户管理请求和响应;

提供一个控制器(controller)代理调用业务逻辑和其它上层处理;

处理从其它层掷出给一个Struts Action的异常;

为显示提供一个模型;

执行用户接口(UI)验证。

Here are some items that are often coded using Struts but should not be associated with the presentation layer:

Direct communication with the database, such as JDBC calls.

Business logic and validation related to your application.

Transaction management.

Introducing this type of code in the presentation layer leads to type coupling and cumbersome maintenance.

以下条款,不该在Struts显示层的编码中经常出现。 它们与显示层无关的。

* 直接的与数据库通信,例如JDBC调用。

* 与你应用程序相关联的业务逻辑以及校验。

* 事物管理。

在表示层引入这些代码,则会带来高偶合和麻烦的维护。

这儿是一些经常用Struts编写的但是却不应该和Struts表现层相伴的项目:

直接和数据库通信,比如JDBC调用;

业务逻辑和与你的应用程序相关的验证;

事务管理;

在表现层中引入这种代码将导致典型耦合(type coupling)和讨厌的维护。

The Persistence Layer

At the other end of a typical web application is the persistence layer. This is usually where things get out of control fast. Developers underestimate the challenges in building their own persistence frameworks. A custom, in-house persistence layer not only requires a great amount of development time, but also often lacks functionality and becomes unmanageable. There are several open source object-to-relational mapping (ORM) frameworks that solve much of this problem. In particular, the Hibernate framework allows object-to-relational persistence and query service for Java. Hibernate has a medium learning curve for Java developers who are already familiar with SQL and the JDBC API. Hibernate persistent objects are based on plain-old Java objects and Java collections. Furthermore, using Hibernate does not interfere with your IDE. The following list contains the type of code that you would write inside a persistence framework:

持久层(The Persistence Layer)

典型的Web应用的另一个末端是持久层。这里通常是程序最容易失控的地方。开发者总是低估构建他们自己的持久框架的挑战性。系统内部的持续层不但需要大量调试时间,而且还经常缺少功能使之变得难以控制,这是持久层的通病。 还好有几个ORM开源框架很好的解决了这类问题。尤其是Hibernate。 Hibernate为java提供了OR持久化机制和查询服务, 它还给已经熟悉SQL和JDBC API 的Java开发者一个学习桥梁,他们学习起来很方便。 Hibernate的持久对象是基于POJO和Java collections。此外,使用Hibernate并不妨碍你正在使用的IDE。

请看下面的条目,你在持久层编码中需要了解的。

持久层 (The Persistence Layer )

在典型web应用的另一端是持久层。这通常是使事情迅速失控的地方。开发者低估了构建他们自己的持久层框架的挑战性。一般来说,机构内部自己写的持久层不仅需要大量的开发时间,而且还经常缺少功能和变得难以控制。有几个开源的“对象-关系映射”(ORM)框架非常解决问题。尤其是,Hibernate框架为java提供了"对象-关系持久化"(object-to-relational persistence)机制和查询服务。Hibernate对那些已经熟悉了SQL和JDBC API的Java开发者有一个适中的学习曲线。Hibernate持久对象是基于简单旧式Java对象(POJO)和Java集合(Java collections)。此外,使用Hibernate并不妨碍你正在使用的IDE。下面的列表包含了你该写在一个持久层框架里的代码类型:

[注:由admin翻译上述部分2005年12月28日22:40分;由***在***修改了上述部分;由***在***修改了上述部分...请自行填写,以便联系]

Querying relational information into objects. Hibernate does this through an OO query language called HQL, or by using an expressive criteria API. HQL is very similar to SQL except you use objects instead of tables and fields instead of columns. There are some new specific HQL language elements to learn; however, they are easy to understand and well documented. HQL is a natural language to use for querying objects that require a small learning curve.

* 查询对象的相关信息的语句。 Hibernate通过一个OO查询语言(HQL)或者正则表达的API来完成查询。 HQL非常类似于SQL-- 只是把SQL里的table和columns用Object和它的fields代替。 你需要学习一些新的HQL语言; 不管怎样,他们容易理解而文档也做的很好。 HQL是一种对象查询的自然语言,花很小的代价就能学习它。

查询相关的信息成为对象。Hibernate通过一种叫作HQL的面向对象(OO)的查询语言或者使用条件表达式API(expressive criteria API)来做这个事情。 HQL非常类似于SQL-- 只是把SQL里的table和columns用Object和它的fields代替。有一些新的专用的HQL语言成分要学;不过,它们容易理解而且文档做得好。HQL是一种使用来查询对象的自然语言,花很小的代价就能学习它。

Saving, updating, and deleting information stored in a database.

* 如何存储,更新,删除数据库记录。

保存、更新、删除储存在数据库中的信息。

Advanced object-to-relational mapping frameworks like Hibernate have support for most major SQL databases, and they support parent/child relationships, transactions, inheritance, and polymorphism.

* 象Hibernate这类的高级ORM框架支持大部分主流数据库,并且他们支持 Parent/child关系,事物处理,继承和多态。

像Hibernate这样的高级“对象-关系”映射(object-to-relational mapping)框架提供对大多数主流SQL数据库的支持,它们支持“父/子”(parent/child)关系、事务处理、继承和多态。

Here are some items that should be avoided in the persistence layer:

这儿是一些应该在持久层里被避免的项目:

Business logic should be in a higher layer of your application. Only data access operations should be permitted.

业务逻辑应该在你的应用的一个高一些的层次里。持久层里仅仅允许数据存取操作。

You should not have persistence logic coupled with your presentation logic. Avoid logic in presentation components such as JSPs or servlet-based classes that communicate with data access directly. By isolating persistence logic into its own layer, the application becomes flexible to change without affecting code in other layers. For example, Hibernate could be replaced with another persistence framework or API without modification to the code in any other layer.

你不应该把持久层逻辑(persistence logic)和你的表现层逻辑(presentation logic)搅在一起。避免像JSPs或基于servlet的类这些表现层组件里的逻辑和数据存取直接通信。通过把持久层逻辑隔离进它自己的层,应用程序变得易于修改而不会影响在其它层的代码。例如:Hebernate能够被其它持久层框架或者API代替而不会修改在其它任何层的代码。

The Business Layer

The middle component of a typical web application is the business or service layer. This service layer is often the most ignored layer from a coding perspective. It is not uncommon to find this type of code scattered around in the UI layer or in the persistence layer. This is not the correct place because it leads to tightly coupled applications and code that can be hard to maintain over time. Fortunately, several frameworks exist that address these issues. Two of the most popular frameworks in this space are Spring and PicoContainer. These are referred to as microcontainers that have a very small footprint and determine how you wire your objects together. Both of these frameworks work on a simple concept of dependency injection (also known as inversion of control). This article will focus on Spring's use of setter injection through bean properties for named configuration parameters. Spring also allows a sophisticated form of constructor injection as an alternative to setter injection as well. The objects are wired together by a simple XML file that contains references to objects such as the transaction management handler, object factories, service objects that contain business logic, and data access objects (DAO).

业务层(The Business Layer)

一个典型Web应用的中间部分是业务层或者服务层。 从编码的视角来看,这层是最容易被忽视的一层。 而我们却往往在UI层或持久层周围看到这些业务处理的代码,这其实是不正确的,因为它导致了程序代码的紧密偶合,这样一来,随着时间推移这些代码很难维护。幸好,针对这一问题有好几种Frameworks存在。 最受欢迎的两个框架是Spring和PicoContainer。 这些为也被称为microcontainers,他们能让你很好的把对象搭配起来。 这两个框架都着手于‘依赖注射’(dependency injection)(还有我们知道的‘控制反转’Inversion of Control=IoC)这样的简单概念。 这篇文章将关注于Spring的注射(译注:通过一个给定参数的Setter方法来构造Bean,有所不同于Factory), Spring还提供了Setter Injection(type2),Constructor Injection(type3)等方式供我们选择。 Spring把程序中所涉及到包含业务逻辑和Dao的Objects——例如transaction management handler(事物管理控制)、Object Factoris(对象工厂)、service objects(服务组件)——都通过XML来配置联系起来。

[注:糟糕,还没有接触过Spring和PicoContainer,这下面的翻译肯定是漏洞百出,还望大虾不吝赐教:)]

业务层

在一个典型的web应用程序的中间的组件是业务层或服务层。从编码的视角来看,这个服务层是最容易被忽视的一层。不难在用户接口(UI)层或者持久层里找到散布在其中的这种类型的代码。这不是正确的地方,因为这导致了应用程序的紧耦合,这样一来,随着时间推移代码将很难维护。幸好,针对这一问题有好几种Frameworks存在。在这个领域两个最流行的框架是Spring和PicoContainer,它们叫作微容器(microcontainers),你可以不费力不费神的把你的对象连在一起。所有这些框架都工作在一个简单的叫作“依赖注入”(dependency injection)(也通称“控制反转”(inversion of control))的概念上。这篇文章将着眼于Spring的为指定的配置参数通过bean属性的setter注入(setter injection)的使用。Spring也提供了一个构建器注入(constructor injection)的复杂形式作为setter注入的一个替代。对象们被一个简单的XML文件连在一起,这个XML文件含有到像事务管理器(transaction management handler)、对象工厂(object factories)、包含业务逻辑的服务对象(service objects)、和数据存取对象(DAO)这些对象的引用(references)。

The way Spring uses these concepts will be made clearer with examples later in this article. The business layer should be responsible for the following:

Handling application business logic and business validation

Managing transactions

Allowing interfaces for interaction with other layers

Managing dependencies between business level objects

Adding flexibility between the presentation and the persistence layer so they do not directly communicate with each other

Exposing a context to the business layer from the presentation layer to obtain business services

Managing implementations from the business logic to the persistence layer

后面我们会举个例子来揭示一下Spring 是怎样运用这些概念。

业务层所负责的如下:

* 处理应用程序的 业务逻辑和业务校验

* 管理事物

* 允许与其它层相互作用的接口

* 管理业务层级别的对象的依赖。

* 在显示层和持久层之间增加了一个灵活的机制,使得他们不直接的联系在一起。

* 通过揭示 从显示层到业务层之间的Context来得到business services。

* 管理程序的执行(从业务层到持久层)。

这篇文章的后面将用例子来把Spring使用这些概念的方法说得更清楚一些。业务层应该负责下面这些事情:

处理应用程序的业务逻辑和业务验证;

管理事务;

预留和其它层交互的接口;

管理业务层对象之间的依赖;

增加在表现层和持久层之间的灵活性,使它们互不直接通信;

从表现层中提供一个上下文(context)给业务层获得业务服务(business services );

管理从业务逻辑到持久层的实现。

The Domain Model Layer

Finally, since we are addressing non-trivial, web-based applications we need a set of objects that can move between the different layers. The domain object layer consists of objects that represent real-world business objects such as an Order, OrderLineItem, Product, and so on. This layer allows developers to stop building and maintaining unnecessary data transfer objects, or DTOs, to match their domain objects. For example, Hibernate allows you to read database information into an object graph of domain objects, so that you can present it to your UI layer in a disconnected manner. Those objects can be updated and sent back across to the persistence layer and updated within the database. Furthermore, you do not have to transform objects into DTOs, which can get lost in translation as they are moved between different application layers. This model allows Java developers to work with objects naturally in an OO fashion without additional coding.

域模块层(The Domain Model Layer )

既然我们致力于的是一个不是很复杂的Web的应用, 我们需要一个对象集合,让它在不同层之间移动的。 域模块层由实际需求中的业务对象组成 比如, OrderLineItem , Product等等。 开发者在这层 不用管那些DTOs,仅关注domain object即可。 例如,Hibernate允许你将数据库中的信息存放入对象(domain objects),这样你可以在连接断开的情况下把这些数据显示到UI层。 而那些对象也可以返回给持续层,从而在数据库里更新。 而且,你不必把对象转化成DTOs(这可能似的它在不同层之间的在传输过程中丢失),这个模型使得Java开发者能很自然运用OO,而不需要附加的编码。

领域模型层

最后,因为我们讨论不平凡的、基于web的应用,我们需要一组对象能在不同的层之间移动。领域对象层由那些代表真实世界业务对象,比如:一份订单、订单项、产品等等组成。这个层允许开发者停止建造和维护不必要的数据传输对象,或者DTOs,来匹配他们的领域对象。例如,Hibernate允许你把数据库信息读进领域对象的一个对象图,所以你能以一种分离的方式把它交给你的用户界面层。那些对象能被更新和送回到持久层在数据库里更新。进一步,你不必转换对象到DTOs,DTOs能在传输中迷路,因为他们在不同的应用层间移动。这种模式允许Java开发者自然地以一种面向对象的风格和对象一起工作,没有附加的编码。

[注:由admin翻译上述部分2005年12月30日20:57分;由***在***修改了上述部分;由***在***修改了上述部分...请自行填写,以便联系] 

相关资源

转自:http://www.onjava.com/pub/a/onjava/2004/04/07/wiringwebapps.html 

 日记标题 (转帖)Wiring Your Web Application with Open Source Java(2)  作者: guest  创建时间: 2005-12-28 20:58:18  最近更新: 2005-12-28 20:58:18  编辑 我要评论  

内容

(由admin转自:http://www.onjava.com/pub/a/onjava/2004/04/07/wiringwebapps.html?page=2)

Wiring Together a Simple Example

Now that we understand the components from a high level, let's put this into practice. Again, for this example, we will combine the Struts, Spring, and Hibernate frameworks. Each one of these frameworks has too much detail to cover in one article. Instead of going into many details about each framework, this article will show how to wire them together with simple example code. The sample application will demonstrate how a request is serviced across each layer. A user of this sample application can save a new order to the database and view an existing order in the database. Further enhancements might allow the user to update or delete an existing order.

一个简单例子

既然我们已经从全局上理解这些组件。 现在就让我们开始实践吧。 我们还是用 Struts,Spring 和Hibernate。这三个框架已经被描述够多了,这里就不重复介绍了。 这篇文章举例指导你如何使用这三个框架整合开发, 并向你揭示 一个请求是如何贯穿于各个层的。(从用户的加入一个Order到数据库,显示;进而更新、删除)。

结合一个简单的例子

  现在,我们从一个高的层次理解了组件,让我们把这些用于实践。在这个例子中,我们将合并Struts、Spring、Hibernate框架。每一个这些框架在一篇文章中都有太多的细节覆盖到。这篇文章将用一个简单的例子代码展示怎样把它们结合在一起,而不是进入每个框架的许多细节。示例应用将示范一个请求怎样跨越每一层被服务。这个示例应用的一个用户能保存一个订单到数据库中和查看一个在数据库中存在的订单。进一步的提高也许允许用户更新或删除一个存在的订单。  

 

You can download the source code of the application.

从这里可以下载到程序程序原代码(download)

你可以下载这个应用的源码。

First, we will create our domain objects since they will interoperate with each layer. These objects will allow us to define what should be persisted, what business logic should be provided, and what type of presentation interface should be designed. Next, we will configure the persistence layer and define object-to-relational mappings with Hibernate for our domain objects. Then we will define and configure our business objects. After we have these components we can discuss wiring these layers using Spring. Finally, we will provide a presentation layer that knows how to communicate with the business service layer and knows how to handle exceptions that arise from other layers.

  既然每个层是互相作用的,我们就先来创建domain objects。首先,我们要在这些Object中要确定那些是需要持久化的,哪些是提供给business logic,那些是显示接口的设计。 下一步,我们将配置我们的持久层并且定义好Hibernate的OR mappings。然后定义好Business Objects。有了这些组成部分之后,我们将 使用Spring把这些连接起来。 最后,我们提供给Spring一个持久层,从这个持久层里我们可以知道它是如何与业务逻辑层(business service layer)通信的,以及它是怎样处理其他层抛出的异常的。。

  首先,我们将创建我们的领域对象因为它们将和每一层交互。这些对象将允许我们定义什么应该被持久化,什么业务逻辑应该被提供,和哪种表现界面应该被设计。然后,我们将配置持久层和为我们的领域对象用Hibernate定义“对象-关系”映射。然后,我们将定义和配置我们的业务对象。在有了这些组件后,我们能讨论和Spring把这些层连在一起。最后,我们将提供一个表现层,它知道怎样和业务服务层交流和知道怎样处理从其它层产生的异常。

Domain Object Layer

Since these objects will interoperate across all layers this might be a good place to start coding. This simple domain model will contain an object that represents an order and an object that represents a line item for an order. The order object will have a one-to-many relationship to a collection of line item objects. The example code has two simple objects in the domain layer:

com.meagle.bo.Order.java: contains the header-level information for an order.

com.meagle.bo.OrderLineItem.java: contains the detail-level information for an order.

Consider choosing package names for your objects that reflect how your application is layered. For example, the domain objects in the sample application can be located in the com.meagle.bo package. More specialized domain objects would be located in subpackages under the com.meagle.bo package. The business logic begins in the com.meagle.service package and DAO objects are located in the com.meagle.service.dao.hibernate package. The presentation classes for forms and actions reside in com.meagle.action and com.meagle.forms, respectively. Accurate package naming provides a clear separation for the functionality that your classes provide, allows for easier maintenance when troubleshooting, and provides consistency when adding new classes or packages to the application.

域对象层(Domain Object Layer)

这层是编码的着手点,我们的编码就从这层开始。 例子中Order 与OrderItem 是一个One—To—Many的关系。 下面就是Domain Object Layer的两个对象:

· com.meagle.bo.Order.java: 包含了一个Order的概要信息

· com.meagle.bo.OrderLineItem.java: 包含了Order的详细信息

好好考虑怎你的package命名,这反应出了你是怎样分层的。 例如 domain objects在程序中可能打包在com.meagle.bo内。 更详细一点将打包在com. meagle.bo的子目录下面。business logic应该从com.meagle.serice开始打包,而DAO 对象应该位于com.meagle.service.dao.hibernate。反应Forms和Actions的 持久对象(presentation classes) 应该分别放在 com.meagle.action和com.meagle.forms包。 准确的给包命名使得你的classes很好分割并且易于维护,并且在你添加新的classes时,能使得程序结构上保持上下一致。

领域对象层

因为这些对象将和所有层交互,这也许是一个开始编码的好地方。这个简单的领域模型将包括一个代表一份订单的对象和一个代表一个订单项的对象。订单对象将和一组订单项对象有一对多的关系。例子代码在领域层有两个简单的对象:

com.meagle.bo.Order.java: 包括一份订单的概括信息;

com.meagle.bo.OrderLineItem.java: 包括一份订单的详细信息;

考虑为你的对象选择包名,它将反映你的应用是怎样分层的。例如:简单应用的领域对象可以放进com.meagle.bo包[译者注:bo-business object?]。更多专门的领域对象将放入在com.meagle.bo下面的子包里。业务逻辑在com.meagle.service包里开始,DAO对象被放进com.meagle.service.dao.hibernate包。对于forms和actions的表现类分别驻入com.meagle.action 和 com.meagle.forms包。准确的包命名为你的类提供的功能提供一个清楚的区分,考虑到当故障维护时更易于维护,当增加新的类或包给应用时提供一致性。

Persistence Layer Configuration

There are several steps involved in setting up the persistence layer with Hibernate. The first step is to configure our domain business objects to be persisted. Since Hibernate works with POJOs we will use our domain objects for persistence. Therefore the Order and OrderLineItem objects will need to provide getter and setter methods for all fields that they contain. The Order object would contain setter and getter methods such as ID, UserName, Total, and OrderLineItems in a standard JavaBean format. The OrderLineItem would similarly follow the JavaBean format for its fields.

Hibernate maps domain objects-to-relational databases in XML files. For our Order and OrderLineItem objects there will be two mapping files to express this. There are tools such as XDoclet to assist with this mapping. Hibernate will map the domain objects to these files:

Order.hbm.xml

OrderLineItem.hbm.xml

You will find these generated files in the WebContent/WEB-INF/classes/com/meagle/bo directory. The Hibernate SessionFactory is configured to know which database it is communicating with, the DataSource or connection pool to use, and what persistent objects are available for persistence. Session objects provided by the SessionFactory are the interface used to translate between Java objects and persistence functions such as selecting, saving, updating, and deleting objects. We will discuss configuring the SessionFactory that Hibernate requires to handle Session objects in a later section.

持久层的配置(Persistence Layer Configuration)

建立Hibernate的持久层 需要好几个步骤。 第一步让我们把BO持久化。 既然Hibernate是通过POJO工作的, 因此Order和 OrderLineItem对象需要给所有的fileds 加上getter,setter方法。 Hibernate通过XML文件来映射(OR)对象,以下两个xml文件分别映射了Order 和OrderItem对象。(这里有个叫XDoclet工具可以自动生成你的XML影射文件)

- Order.hbm.xml

- OrderLineItem.hbm.xml

- Order.hbm.xml

- OrderLineItem.hbm.xml

你可以在WebContent/WEB-INF/classes/com/meagle/bo目录下找到这些xml文件。Hibernate的 [urlhttp://www.hibernate.org/hib_docs/api/net/sf/hibernate/SessionFactory.html]SessionFactory [/url]是用来告诉程序 应该与哪个数据库通信,该使用哪个连接池或使用了DataSource, 应该加载哪些持久对象。而Session接口是用来完成Selecting,Saving,Delete和Updating这些操作。 后面的我们将讲述SessionFactory和Session是怎样设置的。

持久层配置

用Hibernate设置持久层涉及到几个步骤。第一步是配置我们的被持久化的领域对象。因为Hibernate和POJOs[译者注:Persistence Objects Java Objects?]一起工作,我们将使用我们的领域对象持久化。因此,订单和订单项对象将需要提供它们包括的所有的字段的getter和setter方法。订单对象将包括像ID、用户名、合计、和订单项这样一些字段的以一种标准的JavaBean的格式的setter和getter方法。订单项对象将同样的用JavaBean的格式为它的字段设置setter和getter方法。

  Hibernate在XML文件里映射领域对象到关系数据库。为我们的订单和订单项对象将有两个映射文件来表达这种映射。有像XDoclet这样的工具来帮助这种映射。Hibernate将映射领域对象到这些文件:

Order.hbm.xml

OrderLineItem.hbm.xml

你可以在WebContent/WEB-INF/classes/com/meagle/bo目录里找到这些生成的文件。Hibernate SessionFactory被配置来知道它正和哪种数据库交流、使用哪种数据源或连接池、什么持久的对象被持久化是有效的。被SessionFactory提供的Session对象是用于在Java对象和像选取、保存、更新、删除对象这样的一些持久化功能间的翻译的接口。我们将在后面的小节讨论配置Hibernate处理Session对象需要的SessionFactory。

Business Layer Configuration

Now that we have our domain objects we need to have business service objects that perform application logic, make calls to the persistence layer, take requests from the UI layer, deal with transactions, and handle exceptions. To wire all of this together and make this easy to manage we will use the bean management aspect of the Spring framework. Spring uses inversion of control (IoC), or setter dependency injection, to wire up objects that are referenced in an external XML file. Inversion of control is a simple concept that allows objects to accept other objects that are created at a higher level. This way your object is free from having to create objects and reduces object coupling.

Here is an example of an object creating its dependencies without IoC, which leads to tight object coupling:

Figure 2. Objects arranged without IoC. Object A creates objects B and C.

And here is an example with IoC that allows objects to be created at higher levels and passed into objects so that they can use the implementations directly:

Figure 3. Objects arranged with IoC. Object A contains setter methods that accept interfaces to objects B and C. This could have also been achieved with constructors in object A that accepts objects B and C.

业务层的配置(Business Layer Configuration)

既然我们已经有了domain objects,接下来我们就要business service objects了,用他们来执行程序的logic,调用持久层,得到UI层的requests,处理transactions,并且控制exceptions。 为了将这些连接起来并且易于管理,我们将使用面向方面的 SpringFramework。 Spring 提供了 控制倒置(inversion of control 0==IoC)和注射依赖设置(setter dependency injection)这些方式(可供选择),用XML文件将对象连接起来。 IoC是一个简单概念(它允许一个对象在上层接受其他对象的创建),用IoC这种方式让你的对象从创建中释放了出来,降低了偶合度。

这里是一个没有使用IoC的对象创建的例子,它有很高偶合度。

图 2.没有使用 IoC. A 创建了 B 和 C

而这里是一个使用IoC的例子,这种方式允许对象在高层可以创建并进入另外一个对象,所以这样可以直接被执行。

 图 3. 对象使用了 IoC。 A 包含了接受B,C的 setter方法 , 这同样达到了 由A创建B,C的目的。

业务层配置

  现在,我们有了我们的领域对象,我们需要有业务服务对象来执行应用逻辑、执行向持久层的调用、获得从用户界面层的请求、处理事务、处理异常。为了把所有这些连在一起使它易于管理,我们将使用Spring框架的bean管理方面的功能。Spring使用“控制反转”(IoC),或者“setter依赖注入”来把这些对象连好,这些对象在一个外部的XML文件中被引用。“控制反转”是一个简单的概念,它允许对象接受其它在一个高一些的层次创建的对象。使用这种方法,你的对象从必须创建其它对象中解放出来和减少对象耦合。

  这儿是个不使用IoC的对象创建它的从属对象的例子,这导致紧的对象耦合:

  图2:没有使用IoC的对象组织。对象A创建对象B和C。

  这儿是一个使用IoC的例子,它允许对象在一个高一些层次被创建和传进对象,所以它们能直接使用现存的对象:

  图3:对象使用IoC组织。对象A包含setter方法,它们接受到对象B和C的接口。这也可以用对象A里的接受对象B和C的构建器完成。

Building Our Business Service Objects

The setters we will use in our business objects accept interfaces that allow loosely defined implementations of the objects that will be set, or injected. In our case we will allow our business service object to accept a DAO to handle the persistence of our domain objects. While the examples in this article use Hibernate, we can easily switch implementations to a different persistence framework and inform Spring of the new implementation DAO object to use. You can see how programming to interfaces and using the dependency injection pattern loosely couples your business logic from your persistence mechanism.

Here is the interface for the business service object that is stubbed for a DAO object dependency:

建立我们的业务服务对象(Building Our Business Service Objects)

Business Object中的Setter方法接受的是接口,这样我们可以很松散的定义对象实现,然后注入。 在我们的案例中,我们将用一个business service object接收一个DAO,用它来控制domain objects的持久化。 由于在这个例子中使用了Hibernate,我们可以很方便的用其他持久框架实现 同时通知Spring 有新的DAO可以使用了。

在面向接口的编程中,你会明白 “注射依赖”模式是怎样松散耦合你的业务逻辑和持久机制的:)。

下面是一个接口business service object,DAO代码片段:

 代码:

建造我们的业务服务对象

  我们将在我们的业务对象中使用的setter方法接受接口,这些接口允许将被设置或者注入的对象的宽松实现。在我们这个例子里我们将允许我们的业务服务对象接受一个DAO去控制我们的领域对象的持久化。虽然在这篇文章的例子中使用Hibernate,我们可以容易的转换到一个不同的持久框架的实现,通知Spring使用新的实现的DAO对象。你将看见怎样编程到接口和使用“依赖注入”模式宽松耦合你的业务逻辑和你的持久化机制。

  这儿是业务服务对象的接口,它有一个DAO对象依赖的桩。[译者注:是setOrderDAO方法吗?]

public interface IOrderService {

  public abstract Order saveNewOrder(Order order)

    throws OrderException,

           OrderMinimumAmountException;

  public abstract List findOrderByUser(

                                     String user)

                           throws OrderException;

  public abstract Order findOrderById(int id)

                           throws OrderException;

  public abstract void setOrderDAO(

                             IOrderDAO orderDAO);

}

Notice that the code above has a setter for a DAO object. There is not a getOrderDAO method because it is not necessary since there is often no need to access the wired OrderDAO object from the outside. The DAO object will be used to communicate with our persistence layer. We will wire the business service object and the DAO object together with Spring. Because we are coding to interfaces, we do not tightly couple the implementation.

  注意到这段代码里有一个 setOrderDao(),它就是一个DAO Object设置方法(注射器)。 但这里并没有一个getOrderDao的方法,这不必要,因为你并不会在外部访问这个orderDao。这个DAO Objecte将被调用,和我们的persistence layer 通信。我们将用Spring把DAO Object 和 business service object搭配起来的。因为我们是面向接口编程的,所以并不需要将实现类紧密的耦合在一起。

  注意上面的代码有一个为DAO对象准备的setter方法。这儿不是一个getOrderDAO方法因为它不是必要的,因为不太有从外面访问连着的OrderDAO对象的需要。DAO对象将被用来和我们的持久层沟通。我们将用Spring把业务服务对象和DAO对象连在一起。因为我们编码到接口,我们不会紧耦合实现。

The next step is to code our DAO implementation object. Since Spring has built-in support for Hibernate this example DAO will extend the HibernateDaoSupport class, which allows us to easily get a reference to a HibernateTemplate, which is a helper class that simplifies coding with a Hibernate Session and handles HibernateExceptions. Here is the interface for the DAO:

接下去我们开始我们的DAO的实现类进行编码。 既然Spring已经有对Hibernate的支持,那这个例子就直接继承HibernateDaoSupport类了,这个类很有用,我们可以参考HibernateTemplate(它主要是针对HibernateDaoSupport的一个用法,译注:具体可以查看Srping 的API)。 下面是这个DAO接口代码: 代码:

下一步是写我们的DAO实现对象。因为Spring有Hibernate内建的支持,这个例子DAO将继承HibernateDaoSupport类,它[译者注:英语语法问题:它是指“例子DAO”还是指“HibernateDaoSupport类”?]允许我们容易取得一个到HibernateTemplate的引用,HibernateTemplate是一个帮助类,它能简化Hibernate Session的编码和处理HibernateExceptions。这儿是DAO的接口:

public interface IOrderDAO {

  public abstract Order findOrderById(

                                    final int id);

  public abstract List findOrdersPlaceByUser(

                           final String placedBy);

  public abstract Order saveOrder(

                               final Order order);

}

We still have a couple more objects to wire together for our business layer. This includes the HibernateSessionFactory and a TransactionManager object. This is done directly in the Spring configuration file. Spring provides a HibernateTransactionManager, which will bind a Hibernate Session from the factory to a thread to support transactions (see ThreadLocal for more information). Here is the Spring configuration of the HibernateSessionFactory and the HibernateTransactionManager:

  我们仍然要给我们持久层组装很多关联的对象,这里包含了HibernateSessionFactory 和TransactionManager。 Spring 提供了一个 HibernateTransactionManager,他用线程捆绑了一个Hibernate Session,用它来支持transactions(请查看ThreadLocal) 。 下面是HibernateSessionFactory 和 HibernateTransactionManager:的配置:  代码:

  我们还有两个对象要和我们的业务层连在一起。这包括HibernateSessionFactory和一个TransactionManager对象。这在Spring配置文件里直接完成。Spring提供一个HibernateTransactionManager,它将从工厂绑定一个Hibernate Session到一个线程来支持事务(见ThreadLocal获取更多的信息)。这儿是HibernateSessionFactory和HibernateTransactionManager的Spring配置。

<bean id="mySessionFactory"

       class="org.springframework.orm.hibernate.

              LocalSessionFactoryBean">

  <property name="mappingResources">

    <list>

      <value>

        com/meagle/bo/Order.hbm.xml

      </value>

      <value>

        com/meagle/bo/OrderLineItem.hbm.xml

      </value>

    </list>

  </property>

  <property name="hibernateProperties">

    <props>

      <prop key="hibernate.dialect">

        net.sf.hibernate.dialect.MySQLDialect

      </prop>

      <prop key="hibernate.show_sql">

        false

      </prop>

      <prop key="hibernate.proxool.xml">

        C:/MyWebApps/.../WEB-INF/proxool.xml

      </prop>

      <prop key="hibernate.proxool.pool_alias">

          spring

      </prop>

    </props>

  </property>

</bean>

<!-- Transaction manager for a single Hibernate

SessionFactory (alternative to JTA) -->

<bean id="myTransactionManager"

         class="org.

                springframework.

                orm.

                hibernate.

                HibernateTransactionManager">

  <property name="sessionFactory">

    <ref local="mySessionFactory"/>

  </property>

  </bean>

Each object can be referenced in the Spring configuration within a <bean> tag. In this case the bean mySessionFactory represents a HibernateSessionFactory and the bean myTransactionManager represents a Hibernate transaction manager. Notice that the transactionManger bean has a property element called sessionFactory. The HibernateTransactionManager class has a setter and getter for sessionFactory, which is used for dependency injection when the Spring container starts. The sessionFactory property references the mySessionFactory bean. These two objects will now be wired together when the Spring container initializes. This wiring relieves you from creating singleton objects and factories for referencing and creating these objects, which reduces code maintenance in your application. The mySessionFactory bean has two property elements, which translate to setters for mappingResources and hibernatePropertes. Normally, this configuration would be stored in the hibernate.cfg.xml file if you were using Hibernate outside of Spring. However, Spring provides an easy way to incorporate the Hibernate configuration within the Spring configuration file. For more information see the Spring API.

 

  可以看出:每个对象都可以在Spring 配置信息中用<bean>标签引用。在这里,mySessionFactory引用了HibernateSessionFactory,而myTransactionManager引用了HibernateTransactionManage。 注意代码中myTransactionManger Bean有个sessionFactory属性。 HibernateTransactionManager有个sessionFactory setter 和 getter方法,这是用来在Spring启动的时候实现“依赖注入” (dependency injection)的。 在sessionFactory 属性里 引用mySessionFactory。这两个对象在Spring容器初始化后就被组装了起来了。 这样的搭配让你从 单例(singleton objects)和工厂(factories)中解放了出来,降低了代码的维护代价。 mySessionFactory.的两个属性,分别是用来注入mappingResources 和 hibernatePropertes的。通常,如果你在Spring之外使用Hibernate,这样的设置应该放在hibernate.cfg.xml中的。 不管怎样,Spring提供了一个便捷的方式-----在Spring内部配置中并入了Hibernate的配置。 如果要得到更多的信息,可以查阅Spring API。

  每一个对象能被Spring配置里的一个<bean>标记引用。在这个例子里,bean “mySessionFactory”代表一个HibernateSessionFactory,bean “myTransactionManager”代表一个Hibernate transaction manager。注意transactionManger bean有一个叫作sessionFactory的属性元素。HibernateTransactionManager有一个为sessionFactory准备的setter和getter方法,它们是用来当Spring容器启动时的依赖注入。sessionFactory属性指的是mySessionFactory bean。这两个对象现在当Spring容器初始化时将被连在一起。这种连接把你从为引用和创建这些对象而创建singleton对象和工厂中解放出来,这减少了你的应用中的代码维护。mySessionFactory bean有两个属性元素,它们转换到为mappingResources 和 hibernatePropertes的setter方法。通常,如果你在Spring外面使用Hibernate,这个配置将被保存在hibernate.cfg.xml文件中。然而,Spring提供一个容易的方法在Spring配置文件内合并Hibernate配置。获得更多的信息看Spring API.

相关资源

转自:http://www.onjava.com/pub/a/onjava/2004/04/07/wiringwebapps.html?page=2 

 日记标题 (转帖)Wiring Your Web Application with Open Source Java(3)  作者: guest  创建时间: 2005-12-28 21:04:44  最近更新: 2005-12-28 21:05:26  编辑 我要评论  

内容

(由admin转自:http://www.onjava.com/pub/a/onjava/2004/04/07/wiringwebapps.html?page=3)

Now that we have our container service beans configured and wired together we need to wire our business service object and our DAO object together. Then we need to wire these objects to the transaction manager.

既然我们已经组装配置好了Service Beans,就需要把Business Service Object和 DAO也组装起来,并把这些对象配到一个事务管理器(transaction manager)里。

现在我们已经配置了我们的容器服务beans和把它们连在了一起,我们需要把我们的业务服务对象和我们的DAO对象连在一起。然后,我们需要把这些对象和事务manager连起来。

 

Here is what this looks like in the Spring configuration file:

 在Spring中的配置信息:  代码:

这是在Spring配置文件里的样子:

<!-- ORDER SERVICE -->

<bean id="orderService"

  class="org.

         springframework.

         transaction.

         interceptor.

         TransactionProxyFactoryBean">

  <property name="transactionManager">

    <ref local="myTransactionManager"/>

  </property>

  <property name="target">

    <ref local="orderTarget"/>

  </property>

  <property name="transactionAttributes">

    <props>

      <prop key="find*">

     PROPAGATION_REQUIRED,readOnly,-OrderException

      </prop>

      <prop key="save*">

     PROPAGATION_REQUIRED,-OrderException

      </prop>

    </props>

  </property>

</bean>

<!-- ORDER TARGET PRIMARY BUSINESS OBJECT:

Hibernate implementation -->

<bean id="orderTarget"

         class="com.

                meagle.

                service.

                spring.

                OrderServiceSpringImpl">

  <property name="orderDAO">

    <ref local="orderDAO"/>

  </property>

</bean>

<!-- ORDER DAO OBJECT -->

<bean id="orderDAO"

         class="com.

                meagle.

                service.

                dao.

                hibernate.

                OrderHibernateDAO">

  <property name="sessionFactory">

    <ref local="mySessionFactory"/>

  </property>

</bean>

Figure 4 is an overview of what we have wired together. This shows how each object is related and set into other objects by Spring. Compare this with the Spring configuration file in the sample application to see these relationships.

图4 是我们对象搭建的一个提纲。 从中可以看出,每个对象都联系着Spring,并且能通过Spring注入到其他对象。把它与Spring的配置文件比较,观察他们之间的关系

图4是我们已经连在一起的东西的一个概览。它展示了每个对象是怎样被关联的和怎样被Spring设置进其它对象中。把这幅图和Spring配置文件在示例应用中对比看它们之间的关系。

Figure 4. This is how Spring will assemble the beans based on this configuration.

图 4. Spring就是这样基于配置文件,将各个Bean搭建在一起。

图4:这是Spring怎样将在这个配置的基础上装配beans。

This example uses a TransactionProxyFactoryBean, which has a setter for a transaction manager that we have already defined. This is a convenience object that knows how to deal with declarative transaction handling and your service objects. You can define how transactions are handled through the transactionAttributes property, which defines patterns for method names, and how they participate in a transaction. For more information about configuring isolation levels and commits or rollbacks on a transaction see TransactionAttributeEditor.

这个例子使用一个TransactionProxyFactoryBean,它定义了一个setTransactionManager()。 这对象很有用,他能很方便的处理你申明的事物还有Service Object。 你可以通过transactionAttributes属性来定义怎样处理。 想知道更多还是参考TransactionAttributeEditor吧。

这个例子使用一个TransactionProxyFactoryBean,它有一个为我们已经定义了的事务管理者准备的setter。这是一个方便的对象,它知道怎样处理声明的事务操作和你的服务对象。你可以通过transactionAttributes属性定义事务怎样被处理,transactionAttributes属性为方法名定义模式和它们怎样参与进一个事务。获得更多的关于在一个事务上配置隔离层和提交或回滚看TransactionAttributeEditor。

The class TransactionProxyFactoryBean also has a setter for a target, which will be a reference to our business service object called orderTarget. The orderTarget bean defines which business service class to use and it has a property which refers to setOrderDAO(). This property will populate the orderDAO bean that is our DAO object to communicate with our persistence layer.

TransactionProxyFactoryBean 还有个setter. 这会被我们 Business service object(orderTarget)引用, orderTarget定义了 业务服务层,并且它还有个属性,由setOrderDAO()引用。这个属性

TransactionProxyFactoryBean类也有一个为一个target的setter,target将是一个到我们的叫作orderTarget的业务服务对象的引用。 orderTarget bean定义使用哪个业务服务对象和有一个指向setOrderDAO()的属性。这个属性orderDAO bean将居于其中,orderDAO bean是我们的和持久层交流的DAO对象。

One more note about Spring and beans is that beans can operate in two modes. These are defined as singleton and prototype. The default mode for a bean is singleton that means that one shared instance of the bean will be managed. This is used for stateless operations like a stateless session bean would provide. The prototype mode allows new instances of the bean to be create when the bean is served through Spring. You should only use prototype mode when each user needs their own copy of the bean.

Spring 和Bean 的还有一点要注意的: bean可以以用两种方式创造。 这些都在单例模式(Sington)和原型模式(propotype)中定义了。 默认的方式是singleton,这意味着共享的实例将被束缚。 而原形模式是在Spring用到bean的时候允许新建实例的。当每个用户需要得到他们自己Bean的Copy时,你应该仅使用prototype模式。(更多的请参考设计模式中的单例模式和原形模式)

还有一个关于Spring和bean要注意的是bean能以两种模式运作。这两种模式被定义为singleton和prototype.为一个bean默认的模式是singleton,意味着一个共享的bean的实例将被管理。这是用于像一个无状态会话bean将提供的无状态操作。prototype模式允许当bean被通过Spring服务时新的bean的实例被创建。你应当仅仅在每一个用户需要他们自己的bean的拷贝时使用prototype模式。

Providing a Service Locator

Now that we have wired up our services with our DAO we need to expose our services to other layers. This is generally used from code in a layer such as UI that uses Struts or Swing. An easy way to handle this is with a service locator patterned class to return resources from a Spring context. This can also be done directly through Spring by referencing the bean ID.

提供一个服务定位器(Providing a Service Locator)

既然我们已经将我们的Serices和DAO搭配起来了。我们需要把我们的Service显示到其他层。 这个通常是在Struts或者Swing这层里编码。一个简单方法就是用 服务定位器返回给Spring context 。当然,可以通过直接调用Spring中的Bean来做。

下面是一个Struts Actin 中的服务定位器的一个例子。

 代码:

提供一个服务定位器

  现在我们已经把我们的服务和我们的DAO连起来了,我们需要暴露我们的服务给其它层。这通常被从在一个像在使用Struts或Swing的用户界面的层里的代码使用。一个处理这个容易的方法是使用一个服务定位器模式的类来从一个Spring上下文中返回资源。这也能通过Spring引用bean ID被直接完成。

Here is an example of how a service locator can be configured in a Struts Action:

这儿是一个服务定位器怎样能被配置在一个Struts Action中的示例:

public abstract class BaseAction extends Action {

  private IOrderService orderService;

  public void setServlet(ActionServlet

                                 actionServlet) {

    super.setServlet(actionServlet);

    ServletContext servletContext =

               actionServlet.getServletContext();

    WebApplicationContext wac =

      WebApplicationContextUtils.

         getRequiredWebApplicationContext(

                                 servletContext);

      this.orderService = (IOrderService)

                     wac.getBean("orderService");

  }

  protected IOrderService getOrderService() {

    return orderService;

  }

}

UI Layer Configuration

The UI Layer for the example application uses the Struts framework. Here we will discuss what is related to Struts when layering an application. Let's begin by examining an Action configuration within the struts-config.xml file.

UI 层配置 (UI Layer Configuration)

这个例子里UI层 使用了Struts framework. 这里我们要讲述一下在给程序分层的时候, 哪些是和Struts部分的。我们就从一个Struts-config.xml文件中的Action的配置信息开始吧。 代码:

用户界面层配置

  示例应用的用户界面层使用Struts框架。这儿我们将讨论当分层一个应用时和Struts相关的东西。让我们从检查在struts-config.xml文件里的一个Action配置开始。

  

<action path="/SaveNewOrder"

    type="com.meagle.action.SaveOrderAction"

    name="OrderForm"

    scope="request"

    validate="true"

    input="/NewOrder.jsp">

  <display-name>Save New Order</display-name>

  <exception key="error.order.save"

    path="/NewOrder.jsp"

    scope="request"

    type="com.meag

(转帖)POJO 与 PO的 概念

转自:http://www.kissjava.com/zhuanti/hibernate/2005-06-03/13341117764046.html

[文章信息]

 

作者: robbin

时间: 2005-06-03 13:29:44

出处: KissJava.com

责任编辑: Icy

点击: 

 

[文章导读]

 

POJO 与 PO的 概念

 

 

 

  

专题推荐

 · 手机游戏开发专辑

· Struts专题学习

· Hibernate大杂烩

· WebWork全接触

· Spring - 春的诱惑

· Eclipse使用大全

· JBuilder 开发者指南

· Ant - 让编程更轻松

 

 

 

热门文章

 ·  图解利用Eclipse3+Lomboz3+Tomcat开发JSP(4673)

·  图解利用Eclipse3+Lomboz3+Tomcat开发JSP(4673)

·  史上最简单的struts+spring+hibernate配置实例(4657)

·  Eclipse 平台Java开发入门(4568)

·  Eclipse 平台Java开发入门(4568)

·  Spring 入门(一个简单的例子)(3349)

·  J2SDK和TOMCAT的安装及配置(2680)

·  struts傻瓜式学习(一天篇)(2572)

·  Spring framework 10分钟入门(2188)

·  图解利用Eclipse3+Lomboz3+Tomcat开发JSP(1704)

 

 

 

 

 

[正文]

 

 

 

 

   POJO = pure old java object or plain ordinary java object or what ever.

PO = persisent object 持久对象

就是说在一些Object/Relation Mapping工具中,能够做到维护数据库表记录的persisent object完全是一个符合Java Bean规范的纯Java对象,没有增加别的属性和方法。全都是这样子的:

public class User {

  private long id;

  private String name;

  public void setId(long id) {

 this.id = id;



public void setName(String name) {

this.name=name;

}

 public long getId() {

 return id;



public String getName() {

return name;

}

--------------------------------------------------------------------------------

首先要区别持久对象和POJO。

持久对象实际上必须对应数据库中的entity,所以和POJO有所区别。比如说POJO是由new创建,由GC回收。但是持久对象是insert数据库创建,由数据库delete删除的。基本上持久对象生命周期和数据库密切相关。另外持久对象往往只能存在一个数据库Connection之中,Connnection关闭以后,持久对象就不存在了,而POJO只要不被GC回收,总是存在的。

由于存在诸多差别,因此持久对象PO(Persistent Object)在代码上肯定和POJO不同,起码PO相对于POJO会增加一些用来管理数据库entity状态的属性和方法。而ORM追求的目标就是要PO在使用上尽量和POJO一致,对于程序员来说,他们可以把PO当做POJO来用,而感觉不到PO的存在。

JDO的实现方法是这样的:

1、编写POJO

2、编译POJO

3、使用JDO的一个专门工具,叫做Enhancer,一般是一个命令行程序,手工运行,或者在ant脚本里面运行,对POJO的class文件处理一下,把POJO替换成同名的PO。

4、在运行期运行的实际上是PO,而不是POJO。

该方法有点类似于JSP,JSP也是在编译期被转换成Servlet来运行的,在运行期实际上运行的是Servlet,而不是JSP。

Hibernate的实现方法比较先进:

1、编写POJO

2、编译POJO

3、直接运行,在运行期,由Hibernate的CGLIB动态把POJO转换为PO。

由此可以看出Hibernate是在运行期把POJO的字节码转换为PO的,而JDO是在编译期转换的。一般认为JDO的方式效率会稍高,毕竟是编译期转换嘛。但是Hibernate的作者Gavin King说CGLIB的效率非常之高,运行期的PO的字节码生成速度非常之快,效率损失几乎可以忽略不计。

实际上运行期生成PO的好处非常大,这样对于程序员来说,是无法接触到PO的,PO对他们来说完全透明。可以更加自由的以POJO的概念操纵PO。另外由于是运行期生成PO,所以可以支持增量编译,增量调试。而JDO则无法做到这一点。实际上已经有很多人在抱怨JDO的编译期Enhancer问题了,而据说JBossDO将采用运行期生成PO字节码,而不采用编译期生成PO字节码。

另外一个相关的问题是,不同的JDO产品的Enhancer生成的PO字节码可能会有所不同,可能会影响在JDO产品之间的可移植性,这一点有点类似EJB的可移植性难题。

--------------------------------------------------------------------------------

由这个问题另外引出一个JDO的缺陷。

由于JDO的PO状态管理方式,所以当你在程序里面get/set的时候,实际上不是从PO的实例中取values,而是从JDO ?中取出来,所以一旦PM关闭,PO就不能进行存取了。

在JDO中,也可以通过一些办法使得PO可以在PM外面使用,比如说定义PO是transient的,但是该PO在PM关闭后就没有PO identity了。无法进行跨PM的状态管理。

而Hibernate是从PO实例中取values的,所以即使Session关闭,也一样可以get/set,可以进行跨Session的状态管理。

在分多层的应用中,由于持久层和业务层和web层都是分开的,此时Hibernate的PO完全可以当做一个POJO来用,也就是当做一个VO,在各层间自由传递,而不用去管Session是开还是关。如果你把这个POJO序列化的话,甚至可以用在分布式环境中。(不适合lazy loading的情况)

但是JDO的PO在PM关闭后就不能再用了,所以必须在PM关闭前把PO拷贝一份VO,把VO传递给业务层和web层使用。在非分布式环境中,也可以使用ThreadLocal模式确保PM始终是打开状态,来避免每次必须进行PO到VO的拷贝操作。但是不管怎么说,这总是权宜之计,不如Hibernate的功能强。

我有点烦了

  编码真的是一件枯燥无味的活动,前些天征对与用户交互的改进设计后,对编码实施有了畏难情绪,迟迟不愿动手。

  但是,我想,既然在做它,这个任务我一定完成,为了使学习日记使用起来方便一点。