关于xml和注解
更新日期:
关于XML和注解
回答1
最初引入配置文件的原因是为了降低耦合、方便修改等。在缺少元数据信息的过去,指定哪个类哪个方法用来做什么,或者指定ORM框架的实体映射等,只能通过人工手动编写。最初的Java可不像Ruby on Rails这种框架可以做到约定大于配置。如果把配置信息硬编码在代码里,那势必是每天都要大量改动代码,从而堆积大量样板代码,这些样板代码可读性很差,会和项目中很多的类发生耦合,而改动代码就要编译、重新封包部署,会非常影响工作效率。特别是如果将某个配置过的类删掉,那么如果不在配置代码里去掉对这个类的引用,那么必定编译无法通过。而配置文件的话,捕获一下ClassNotFound异常然后忽略这段配置就可以了。所以在过去,使用某种格式的配置文件,当然xml居多,来配置Java项目的各个组件是十分正常的。
不过配置文件也是存在弊端的,首先最大的问题就是配置文件是不参与编译的,这也意味着无法享受静态语言编译检查带来的好处。配置文件是否起作用,甚至格式是否正确,只能在将项目跑起来的时候,才能进行排除。如果是比较隐晦的错误,也会给开发人员带来很多困扰。再者,尽管XML等配置文件的可读性理论上是良好的,但如果其内容过于繁杂,甚至堆积成山,那么对于维护人员来说也是一件非常痛苦的事情。
不过事情在Java引入注解之后得到了很大的改变。注解是可以给类、接口、方法、成员变量、参数上附加元信息的新功能。有了它的标记,再也不用将一大堆类、方法创建完了还要在XML里罗列一遍,配置文件的体积得到了极大地瘦身。回到刚刚的问题,之所以最初不用Java代码作为配置文件,主要是因为这些代码需要经常性改动,会导致配置代码和项目产生耦合,且频繁编译,替换也不方便。但有了注解之后,直接扫描注解就能获得足够多的配置信息,样板代码消失了,配置文件本身其实很少会发生变化了,这样以来,用XML还是用Java代码做配置,其实问题都不大了。而且用代码的话,可以享受IDE的语法提示,确保不容易写错,对自己的配置到底会怎样被框架使用也会了解的更深刻一点,嗯,一点儿而已。
甚至,包括Servlet 3.0和Spring Framework都重新引入了基于代码配置的功能。没错儿,题主,现在的Java,不仅不是需要使用XML之类的配置文件,而是真的有很多框架是可以用Java代码做配置文件的。我现在开Spring项目,连web.xml和applicationContext.xml之类的配置文件都没有,统统是使用代码进行配置的。其他框架不敢保证,但是Servlet3.0和Spring的配置,都是可以在XML和Java代码两者之间随意转换的。不存在某种写法只能在特定的配置手段中使用的问题。
使用代码作为配置文件除了可以享受IDE语法高亮提示和静态编译除错的好处之外,还有一个好处是对于需要根据复杂情景灵活提供配置的时候,代码的灵活性是配置文件无法比拟的。比如使用随机数、使用if-else、调用远程服务器提供配置信息等,即使XML能配出来,也是相当麻烦,绝对比使用代码要多出很多行来的。
以上是Java项目配置文件发展的历史,以及各自的利弊及适用场景。其实无论XML也好,Java代码也好,在现在Java项目中都是OK的。不过如果需要更加灵活的配置,还是更加推荐使用Java代码的方式。现在这种方式也是愈发主流,甚至Gradle这种项目配置,都使用脚本语言了。当然,我的水平有限,也有可能个人理解中也有很多谬误,欢迎指正交流。
回答2
最早最早的程序都是写死的,也就是说用语言本身来写“配置”。这是第一阶段。
但程序员们很快发现要改点什么就得重新编译程序,很不方便,于是把一些可可能会变的东西写到配置文件中,配置文件通常是文本文件,ini或者xml之类的。ini相对功能较简单,xml则比较复杂。这是第二阶段。
后来配置越来越多,配置文件变得复杂起来,为了让xml尽可能不写错(xml的错误不能在编译期检查出),还使用了dtd,schema等对xml进行验证。程序员们甚至想一切皆配置,所有程序按功能完全模块化,以后改什么动动配置即可,看起来很美好……这是第三阶段。
但配置的复杂也是个大问题,后来程序员们又发现,这么复杂的配置掌握起来其实也很困难,并不比写代码简单多少,错误还不能在编译期看出,且有些东西确实万年不变的,干嘛要配置呢?于是又返璞归真的开始宣传“零配置”,利用一些新的语言特性,如“注解”(annotation),将配置“写死”在程序中……这是第四阶段。
第五阶段,其实我瞎编的,就是配置文件还是要,只不过只保留了最必要的部分,大多“配置”都写死了。