/**

*作者:张荣华

*日期:2008-4-2

**/

前言
Xml和annotation都是我们在项目中常用到的技术,尤其是在配置文件这一块。很久很久以前,当jdk5.0还没有出来的时候,或者我们还没有大规模换到jdk5.0的时代,xml作为配置文件是大行其道,但是当annotation诞生之后,形式有所转变,曾经发挥巨大功能的xml开始被人们所批斗了,现下人们对annotation开始了疯狂的崇拜。

那么就先说说xml的功与过,他的功我们都看在心里,就拿以前最常见的技术来说吧,struts+spring+hibernate,哪一个不用配置文件,使用配置文件谁不用xml,虽然hibernate还支持property文件配置,但是很显然,那玩意儿更不易读(可能还有人说,我用xdoclet了, 可是这个东东用的人是非常之少的)。于是我们看到我的项目里到处都是xml配置文件,从struts,到hibernate,而且尤其是struts和hibernate,一个中型项目,struts的xml配置文件有时候达到数万行,再大一点的,可以数十万行,虽然很多时候都是拷贝,粘贴,但是看这个这个数十个几千行的struts配置文件能不让人倒胃口吗。再说那个hbm.xml,大家再熟悉不过了,你想想吧,一个几域模型的项目里,你需要有多少配置文件,我眼睛都看花了。这些都是xml的缺点。但是xml也有优点,比如我要做一个通用的配置,象spring里的声明式事务管理之类,那么所有的需要事务管理的bean,我只要一段配置文件或者很少几段配置文件就可以解决,这个配置不会超过50行。

那么再看看配置文件界的后起之秀吧,话说自打annotation出来之后,众人犹如众星捧月一般,把这玩意举上神坛,每日供奉,于是呼出来一批基于annotation的mvc框架,我们看看最常用的一个吧,struts2.0里也可以使用annotation来实现result的配置,我们看看它是怎么做的:
首先:指定action的package目录。
其次:根据上面指定的目录下的action的名字来声明url,这样struts2.0可以根据url自动找到需要执行的action的方法。
第三:根据方法上声明的annotation来返回对应的页面。

Struts2.0的这个零配置就是使用coc和annotation来实现的,很简单吧,但是虽然简单,功效却非常之大,这样struts.xml中的action的配置全部都可以拿掉了,配置文件就会变的非常之简单。然后我们在维护或者开发的时候,第一时间就可以知道这个方法会返回哪些页面(曾经我在webwork2上也实现了同样的功能),而在从前,我们不得不去xml配置文件中ctrl+f来寻找,就这一点就节省了很多的时间,同时xml配置文件中的配置也所剩无几,剩下的都是一些公用的配置。我们再看hibernate呢,hibernate3.2支持annotation,而且在新项目中我一直使用annotation来配置我们的po,我们得到的好处就是我们再也看不到hbm文件了,我直接就可以看到某个po属性的配置,可以这么说在这个地方用得是恰到好处,给我们带了不少方便。问题是annotation是万能的吗,我需要把struts.xml文件全部去掉吗,我要把事务的配置都写道类里面去吗,如果我们这样做了,我相信实现annotation的人一定会哭了。

举个例子吧,spring2.0支持使用annoation来配置事务,我看了一下,发现如果我们用annotation来配置事务,事务的传播途径,是否只读之类的配置我们需要写上很多遍才行,而事实上,大多数方法的事务需求是一样的,即使有一些不一样,我们也可以通过多配两个transactionAttribute就可以实现,我们为了使用annotation而让配置反而变复杂了,值得吗。难道只是为了和别人吹嘘“hi,知道吗,我们现在连事务也使用annotation来实现了”。我们最想要的不是把这些公用的东西整到annotation里去,而是要把一些独用的东西放进去,比如说struts中的action定义,hibernate中po的配置,还有一个目前最想要的是spring的bean定义,这些东西可以放到annotation里去。

Annotation不是万能钥匙,不能解开所有的锁,大家也不要对它过度崇拜,一个优秀的软件工程师不只是不断的学习,更需要的是正确的判断在何种场景下需要选择何种技术,一般说来一种技术越强大,那么它的局限性就越高,所以通常我们会选择其他的技术来和它互补,在配置文件界,我们可以说annotation很好很强大,但是我们不要忘了xml也是很好的,也是很强大的,而且他们是互补的。

 

评论
imKenny 2008-06-22
Readonly 写道
ahuaxuan 写道

Model一个field上挂了O/R Mapping, Full Text Index, Validation, Security...如果这么多配置不放在annotation中还是需要放在配置文件中,那么一个model就需要很多配置文件了

偶的意见就是要分开多个配置文件,减少Line Of Code per File,减少维护成本,降低出错概率,分离关注点。




支持分离xml,不过我认为xml+annotation的方式比较好,配置和注解各行其道相辅相成。
fireflyc 2008-06-17
tiannet 写道
就像编程语言一样,
没什么哪个好哪个坏,只有适合的场合。
个人更倾向于在代码中完成尽可能多的事情,
就像java中的代码注释,为什么要和代码结合那么紧密呢?

集中式管理有什么不好的地方?
举一个例子,使用Spring的事务管理,
若是使用xml配置,
我现在在查看一个业务方法,我怎么知道它是否使用了事务?
我必须找到相应的配置文件,如果配置文件很多,从哪找也是一个问题,
而如果使用annotation,那么看到@Transactional就知道它使用了事务。

我觉得讨论xml和annotation的问题,
不如讨论哪些情况下使用xml更好,哪些情况下使用annotation更好!

看我上面的回复:
归结起来一句话:
在需要配置的地方使用xml配置文件,那些本身就应该是代码的一部分的应该是annotation。
tiannet 2008-06-17
就像编程语言一样,
没什么哪个好哪个坏,只有适合的场合。
个人更倾向于在代码中完成尽可能多的事情,
就像java中的代码注释,为什么要和代码结合那么紧密呢?

集中式管理有什么不好的地方?
举一个例子,使用Spring的事务管理,
若是使用xml配置,
我现在在查看一个业务方法,我怎么知道它是否使用了事务?
我必须找到相应的配置文件,如果配置文件很多,从哪找也是一个问题,
而如果使用annotation,那么看到@Transactional就知道它使用了事务。

我觉得讨论xml和annotation的问题,
不如讨论哪些情况下使用xml更好,哪些情况下使用annotation更好!
fireflyc 2008-06-16
我的意见是这样的:
xml配置文件的目的便是配置,为的是只需修改配置文件就能改动系统的一些逻辑。
annotation本质就是一种代码。

所以不能使用annotation代替xml配置文件,因为这是一种倒退。我们配置的原因是为了修改系统的逻辑无需编译代码。可是annotation是写在代码中的所以必须重新编译代码。

归结起来一句话:
在需要配置的地方使用xml配置文件,那些本身就应该是代码的一部分的应该是annotation。
davidcen 2008-06-09
cats_tiger 写道
XML和annotation确实很难取舍,在我们的项目中Hibnerat Domain用Annotation,习惯之后确实比hbm.xml方便。以前我们是用xdoclet生成hbm的,但是annotation更好用。
Spring目前还没有用annotation,XML集中配置依赖关系很方便,而且Spring的常用配置很简单。
最难搞定的是Struts2了,Result的annotation是不会用的,一来coc风格的配置已经很简单了,二来要我在web.xml加入packages的路径实在不爽。所以只用annotation作验证,但是验证复杂了也很乱:
@Validations(requiredStrings = {
      @RequiredStringValidator(fieldName = "model.loginId", message = "登录名是必须的."),
      @RequiredStringValidator(fieldName = "model.password", message = "密码是必须的."),
      @RequiredStringValidator(fieldName = "model.confirmPwd", message = "请两次输入密码.") }, stringLengthFields = { @StringLengthFieldValidator(fieldName = "password", minLength = "3", maxLength = "32", message = "密码应多于3字符", trim = true) }, emails = { @EmailValidator(fieldName = "model.email", message = "请输入正确的e-Mail.") }, expressions = { @ExpressionValidator(message = "两次输入的密码必须相同.", expression = "model.password==model.confirmPwd") })


这堆代码看着实在恶心,还不如xml呢。遇到这种情况我就让弟兄们随机应变了。

过度滥用和过度设计annotation,会让人哭出声来.正如前面所讨论的,分离关注点.
就这个validations来说,还不是最终设计,因为message要支持国际化,那到时候一样需要各种语言版本的properties文件.我觉得把validations和域对象,尤其是和po混用起来,是污染域对象的行为,相当把校验的逻辑部分包含在model层上,复杂的校验逻辑如何解决?尽管这个域对象能对外声称他是vo,本身po=vo已经能够容忍了,因为他是plain object,我宁可保持po的纯洁,他要解决的问题就是把关系数据库映射到域对象模型上来;假如这个对象仅仅是vo,我可能能够容忍,不过复杂的校验怎么办?分层设计怎么办,我们是不是需要逻辑侵入?总之我们需要一个平衡,如果需要工厂化生产,我们就必须估量这种集合配置带来的问题,从各种方面考量,维护成本,出错概率....,如果只是一个小系统,只是几个类的校验,那就忍忍就算了吧.本来工钱就不够,不是吗?
yujianqiu 2008-04-20
没有绝对的好与不好啦。
不会经常改变的用annotation,经常会变得用XML。
Hibernate用annotation,因为数据模型不会变来变去,有变化依然可以用xml去覆盖。
Struts和Spring用XML,因为不管是名称匹配还是类型匹配都比较死。
@Trasient这个标签我觉得没有那么“可憎”,在代码中显式的申明某个property是瞬时的是很有意义的。另外JPA/Hibernate中的某些标签其实也是对Java语言的一个补充。在Java(实际上现在几乎所有OO语言都存在这个问题)语言中,对于关联关系的表述不够精确。这方面JPA/Hibernate做得可能还不够,当然这估计也不是它们的初衷。
Hibernate支持JPA的annotation是正确的,我觉得Java发展的一个很大的问题就是各立山头,各自为王。Microsoft不也常常因此被诟病吗?
crazy.j 2008-04-18
Readonly 写道
零配置不是annotation的功劳,早在struts2还叫webwork2的年代,照样有零配置的方法可以使用。
偶一直认为把annotation当作配置来用是一点好处也没有的,偶在实际项目中见过Model一个field上挂了O/R Mapping, Full Text Index, Validation, Security...整整超过10行的annotation,偶只不过是想看看这个Model有什么field而已,这样把整个一大包乱七八糟的annotation都塞在一个文件里面,不是一个大倒退么?

确实是这样,这样的文件看上去显得没有主次了。
gj1237 2008-04-18
java越来越复杂
zl584521 2008-04-10
看了,没有用过,感觉很疏远!
yyjn12 2008-04-07
quaff 写道
还有最烦什么零配置,难道Annotation就不是配置?


不算.annotation算硬编码.不算配置,当然可以叫零配置了.

修改annotation的时候就需要修改.java文件,重新编译为.class文件,这显然是硬编码,怎么说是配置呢?

当然,这里不讨论修改xml是否有意义.
jamesqiu 2008-04-07
配置的后起之秀,是动态脚本:
Grails用.groovy
RoR用ruby
好处是:
1)表达能力强,有好的数据类型支持(如list,map等);
2)可以用编程所用的语言书写配置文件中的控制逻辑;
dan 2008-04-07
ray_linn 写道
dan 写道
如果沒有DI和IOC設計模式Object就會直接寫在哪裡?(應是類別裡吧!)

類別的成員型態沒有直接寫在類別裡是因DI設計模式
而DI設計模式漸漸演變成IOC模式,類別的成員歸屬
早在塑模時早已決定了,xml與annotation皆是實現設計模式
使用的技術之一,並不是決解專案方向的起點。

建議在使用IOC時依關聯性來做配罝
如果注入的Object是誇域或以其它Objec相關聯以xml
看做uml做配置,無關聯以annotation,所以使用xml
或annotation早在塑模時早已決定,當SD在做IOC時,IOC
的概念性模型在SA時就已成型了,所以使用xml
和annotation依塑模原則來做配置,重點在關聯性
很多人使用xml是因為他們看得關聯性,使用annotation
的人正因為他們看到類別的完整性,確實很多Object成員
本來就屬於此類別正因IOC設計模式才產生xml
和annotation之間的不同調,但是決定一切的還是在
塑模原則上(在塑模可以看到關聯性相依性,及無關聯性模型)。


不得不说这是所有帖子里比较有价值的.


謝謝您的認同,因為我打字慢,所以從PG->SD->SA都簡單帶過
沒有詳細的說明,因為從PG->SD->SA的說明要打很多的字,
及要舉例及畫UML圖還要寫出code( xml 和annotation )
所以才沒加上去。
不過我的想法也許是錯的,如果有不對的地方能不能給點意見。
如果覺的有道理的話看的懂我雜亂的發言,能不能加一些資料上去,因為我文筆不好,
常常讓人看不懂。謝謝!
ray_linn 2008-04-06
dan 写道
如果沒有DI和IOC設計模式Object就會直接寫在哪裡?(應是類別裡吧!)

類別的成員型態沒有直接寫在類別裡是因DI設計模式
而DI設計模式漸漸演變成IOC模式,類別的成員歸屬
早在塑模時早已決定了,xml與annotation皆是實現設計模式
使用的技術之一,並不是決解專案方向的起點。

建議在使用IOC時依關聯性來做配罝
如果注入的Object是誇域或以其它Objec相關聯以xml
看做uml做配置,無關聯以annotation,所以使用xml
或annotation早在塑模時早已決定,當SD在做IOC時,IOC
的概念性模型在SA時就已成型了,所以使用xml
和annotation依塑模原則來做配置,重點在關聯性
很多人使用xml是因為他們看得關聯性,使用annotation
的人正因為他們看到類別的完整性,確實很多Object成員
本來就屬於此類別正因IOC設計模式才產生xml
和annotation之間的不同調,但是決定一切的還是在
塑模原則上(在塑模可以看到關聯性相依性,及無關聯性模型)。


不得不说这是所有帖子里比较有价值的.
ahuaxuan 2008-04-06
sslaowan 写道
ahuaxuan 写道
我做过的最大的项目是的域模型有上百个,hbm.xml文件也有上百个,给我的感觉是维护起来太麻烦了,当我在开发的时候要修改一个属性的时候,我不得不去找hbm文件,虽然有ctrl+shift+r,但是还是让我觉得很不方便,而中小型项目里使用hbm的话,其缺点还不能完全体现出来。

一个领域对象里会有多少属性啊,至于ctrl+shift+r那么夸张吗?

ctrl+shift+r是用来查找资源文件的,一旦与domain object的关联的资源文件有很多的时候,你改一个,必须要改其他的,如果你是维护系统,不知道还有其他的资源文件要改,那么出错的几率就大了,如果使用annotation放在一块,改起来就会一目了然,而且我比较反对把校验使用annotation来做。


ps: 使用ctrl+shift+r和domain object中的属性没有什么关系
yzj520hyy 2008-04-05
Annotation: 当此配置信息不需要经常改动的时候使用。
XML: 当此配置信息需要经常改动的时候使用。
cats_tiger 2008-04-05
XML和annotation确实很难取舍,在我们的项目中Hibnerat Domain用Annotation,习惯之后确实比hbm.xml方便。以前我们是用xdoclet生成hbm的,但是annotation更好用。
Spring目前还没有用annotation,XML集中配置依赖关系很方便,而且Spring的常用配置很简单。
最难搞定的是Struts2了,Result的annotation是不会用的,一来coc风格的配置已经很简单了,二来要我在web.xml加入packages的路径实在不爽。所以只用annotation作验证,但是验证复杂了也很乱:
@Validations(requiredStrings = {
      @RequiredStringValidator(fieldName = "model.loginId", message = "登录名是必须的."),
      @RequiredStringValidator(fieldName = "model.password", message = "密码是必须的."),
      @RequiredStringValidator(fieldName = "model.confirmPwd", message = "请两次输入密码.") }, stringLengthFields = { @StringLengthFieldValidator(fieldName = "password", minLength = "3", maxLength = "32", message = "密码应多于3字符", trim = true) }, emails = { @EmailValidator(fieldName = "model.email", message = "请输入正确的e-Mail.") }, expressions = { @ExpressionValidator(message = "两次输入的密码必须相同.", expression = "model.password==model.confirmPwd") })


这堆代码看着实在恶心,还不如xml呢。遇到这种情况我就让弟兄们随机应变了。
sslaowan 2008-04-05
另外使用XML做配置文件,一方面的作用不就是可以灵活配置吗?依赖关系外置
sslaowan 2008-04-05
ahuaxuan 写道
我做过的最大的项目是的域模型有上百个,hbm.xml文件也有上百个,给我的感觉是维护起来太麻烦了,当我在开发的时候要修改一个属性的时候,我不得不去找hbm文件,虽然有ctrl+shift+r,但是还是让我觉得很不方便,而中小型项目里使用hbm的话,其缺点还不能完全体现出来。

一个领域对象里会有多少属性啊,至于ctrl+shift+r那么夸张吗?
sslaowan 2008-04-05
Readonly 写道
零配置不是annotation的功劳,早在struts2还叫webwork2的年代,照样有零配置的方法可以使用。
偶一直认为把annotation当作配置来用是一点好处也没有的,偶在实际项目中见过Model一个field上挂了O/R Mapping, Full Text Index, Validation, Security...整整超过10行的annotation,偶只不过是想看看这个Model有什么field而已,这样把整个一大包乱七八糟的annotation都塞在一个文件里面,不是一个大倒退么?

我反对在domain中使用annotation代替hbm.xml的原因也在于其,本来轻量的POJO搞的那么混乱
darkjune 2008-04-05
各有各的好处,关键是找到best practise就可以了
发表评论

提醒: 该博客已发表在公共论坛,博客所有留言会成为论坛回贴,留言请注意遵守论坛发贴规则

您还没有登录,请登录后发表评论

ahuaxuan
搜索本博客
我的相册
C21ef232-7784-3985-9b9b-f1aa3bf48f96-thumb
100_2076
共 4 张
存档
最新评论