Xmlconfiguration与基于注释的configuration

在最近我一直在研究的一些大型项目中,select一个或另一个(XML或注释)似乎变得越来越重要。 随着项目的增长,一致性对可维护性非常重要。

我的问题是,人们喜欢什么? 你喜欢基于XML还是Annotation? 或两者? 每个人都谈论XMLconfiguration地狱和如何注释是答案,怎么样的注释configuration地狱?

注释有它们的用途,但它们不是杀死XMLconfiguration的一个silverlight子弹。 我build议混合两个!

例如,如果使用Spring,将XML用于应用程序的dependency injection部分是完全直观的。 这使代码的依赖性远离将要使用它的代码,相反,在代码中使用某种注释需要依赖性使代码意识到这种自动configuration。

然而,不使用XML进行事务pipe理,而是将方法标记为具有注释的事务,这是非常有意义的,因为这是程序员可能希望知道的信息。 但是一个接口将被注入为SubtypeY,而不是SubtypeX,因此如果现在你想注入SubtypeX,你必须改变你的代码,而你之前有一个接口合约,所以用XML,你只需要改变XML映射,这样做是相当快速和无痛的。

我没有使用JPA批注,所以我不知道它们有多好,但是我认为将XML的映射留在XML中的数据库也是好的,因为对象不应该关心它的信息来自哪里它应该只关心它可以用它的信息做什么。 但是如果你喜欢JPA(我没有任何expression的意思),一定要去做。

一般来说:如果一个注解提供了一些function,并作为一个注释本身,并且不把代码绑定到某个特定的过程,以便在没有这个注释的情况下正常运行,那么去注释。 例如,标记为事务性的事务性方法不会中止其操作逻辑,并且也可以作为良好的代码级别评论。 否则,这个信息最好用XML来表示,因为尽pipe最终会影响代码的运行,但它不会改变代码的主要function,因此不属于源文件。

这里有一个更广泛的问题,即外部元素与内部元数据的问题。 如果你的对象模型只会以一种方式持续下去,那么内联元数据(即注释)就更加紧凑和可读。

但是,如果您的对象模型在不同的应用程序中被重复使用,那么每个应用程序都希望以不同的方式保持模型,那么将元数据(即XML描述符)外化就变得更合适。

没有一个更好,所以都支持,虽然注释更时尚。 因此,像JPA这样的新发型框架倾向于更加强调它们。 像本地Hibernate这样的更成熟的API提供了这两种function,因为众所周知,没有一个是足够的。

我总是把注释看作某种types能力的指示器,或者如何与其他人交互。

另一方面Spring的XMLconfiguration对我来说就是这样, configuration

例如,有关代理的IP和端口的信息将定义为XML文件,这是运行时configuration。

使用@ @Autowire ,@ @Element来指示框架如何处理类是很好的使用注释。

把URL放到@Webservice注释中是不好的样式。

但这只是我的意见。 交互和configuration之间的界限并不总是很清楚。

我已经使用Spring几年了,所需要的XML数量肯定是很乏味的。 在Spring 2.5中新的XML模式和注解支持之间,我通常会做这些事情:

  1. 使用“component-scan”自动加载使用@Repository,@Service或@Component的类。 我通常给每个bean一个名字,然后用@Resource将它们连接在一起。 我发现这个pipe道并不经常改变,所以注释是有道理的。

  2. 对所有AOP使用“aop”命名空间。 这真的很好。 我仍然使用它来进行交易,因为将@Transactional放在整个地方都是一种拖累。 您可以为任何服务或存储库上的方法创build命名切入点,并快速应用这些build议。

  3. 我使用LocalContainerEntityManagerFactoryBean和HibernateJpaVendorAdapter来configurationHibernate。 这让Hibernate可以轻松地自动发现类path上的@Entity类。 然后我使用参考LCEMFB的“factory-bean”和“factory-method”创build一个名为SessionFactory的bean。

我认为使用基于XML的方法,可见性是一个巨大的胜利。 我发现XML并不是那么糟糕,因为用于导航XML文档的各种工具(例如Visual Studio + ReSharper的文件结构窗口)。

你当然可以采取混合的方法,但这对我来说似乎是危险的,因为可能会使项目上的新开发人员难以找出configuration或映射不同对象的位置。

我不知道; 到底XMLHell对我来说似乎不是那么糟糕。

这取决于你想要configuration什么,因为有一些选项不能用configuration来configuration。 如果我们从注释方面看:

  • 加上:注释不那么通俗
  • 减号:注释不太明显

这取决于你更重要的是什么

一般来说,我会build议select一种方式,并在产品的一些封闭部分使用它。

(除了一些例外:例如,如果您select基于XML的configuration,可以使用@Autowire注释,它是混合的,但是这有助于可读性和可维护性)

使用仅注解方法的一个重要部分是“bean名称”的概念或多或less消失(变得微不足道)。

Spring中的“bean名称”形成了对实现类的更多抽象层次。 XML bean是相对于它们的bean名称定义和引用的。 有了注释,它们就被它们的类/接口引用了。 (尽pipebean的名字存在,你不需要知道它)

我坚信,摆脱多余的抽象简化了系统,提高了生产力。 对于大型项目,我认为通过摆脱XML的收益可以是巨大的。

我可能是错的,但我认为Annotations(如Java的@Tag和C#的[Attribute])是编译时选项,XML是运行时选项。 对我来说,这不是等同的,有不同的利弊。

我也认为混合是最好的,但也取决于configuration参数的types。 我正在开发一个也使用Spring的Seam项目,我通常将其部署到不同的开发和testing服务器。 所以我分手了:

  • 服务器特定的configuration(像服务器上资源的绝对path):Spring XML文件
  • 将bean注入为其他bean的成员(或在许多bean中重用Spring XML定义的值):注解

关键的区别是,您不必重新编译所有更改服务器特定configuration的代码,只需编辑xml文件即可。 还有一个好处是,一些configuration变化可以由不了解所有代码的团队成员完成。

还有其他方面比较重构和其他代码的变化。 当使用XML时,需要花费很多精力来进行重构,因为您必须处理所有的XML内容。 但使用注释很容易。

我最喜欢的方式是基于Java的configuration没有(或最小)的注释。 http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-java

在DI容器的范围内,我认为基于注解的DI是滥用Java注释的。 说这个,我不build议在你的项目中广泛使用它。 如果你的项目真的需要DI容器的强大function,我会build议使用基于Xml的Spring IoCconfiguration选项。

如果仅仅是为了unit testing的缘故,开发人员应该在编码中应用dependency injection模式,并利用模拟工具(如EasyMock或JMock)的优势来规避依赖关系。

您应该尽量避免在错误的环境中使用DI容器。

始终要链接到特定Java组件(类,方法或字段)的configuration信息是注释表示的一个好候选。 当configuration是代码的核心时,注释在这种情况下特别有效。 由于注释的限制,每个组件只能有一个configuration也是最好的。 如果需要处理多个configuration,尤其是那些在包含注释的Java类之外的任何条件,那么注释可能会产生比解决问题更多的问题。 最后,无需重新编译Java源代码即可修改注释,因此在运行时需要重新configuration的内容不能使用注释。

请参阅以下链接。 它们也可能有用。

  1. 注释与XML,优点和缺点
  2. http://www.ibm.com/developerworks/library/j-cwt08025/

这是经典的“configuration与公约”问题。 个人品味在大多数情况下决定了答案。 但是,我个人更喜欢configuration(即基于XML)的公约。 国际海事组织的IDE的足够强大,足以克服一些XML地狱的人经常与build设和维护基于XML的方法。 最后,我发现Configuration的好处(比如构build实用程序来构build,维护和部署XMLconfiguration文件)远远超过了Convention。

我用两个。 大多数情况下是XML,但是当我有一堆从一个普通的类inheritance而来的具有公共属性的bean时,我在超类中使用这些注释,所以我不必为每个bean设置相同的属性。 因为我是一个控制怪胎,我使用@Resource(name =“referencedBean”)而不是自动assembly的东西(如果我需要与原始的引用Bean相同的类的另一个bean,则可以节省很多麻烦) 。

从我的经验来看,有一些注释configuration的优缺点:

  • 当涉及JPAconfiguration,因为它是一次完成,通常不会经常更改我宁愿坚持注释configuration。 有可能会有一个关于可能性看到一个更大的configuration图的问题 – 在这种情况下,我使用MSQLWorkbench图。
  • Xmlconfiguration非常好,可以获得更大的应用程序图片,但是直到运行时才会发现一些错误。 在这种情况下,Spring @Configuration注释听起来是一个更好的select,因为它可以让你看到一个更大的图像,也允许在编译时validationconfiguration。
  • 至于Springconfiguration,我更喜欢结合使用两种方法:使用@Configuration注释服务和查询接口和XMLconfigurationdataSource和弹簧configuration的东西,如上下文:component-scan base-package =“…”
  • 但是,在configurationstream程configuration(Spring Web Flow或Lexaden Web Flow)时,xmlconfiguration位java注释是非常重要的,因为查看整个业务stream程的全景图非常重要。 使用注释方法实现它听起来很麻烦。

我更喜欢结合两种方法 – java注释和基本的xml最小化,最大限度地减lessconfiguration地狱。

对于Spring框架,我喜欢能够使用@Component注释并设置“component-scan”选项的想法,以便Spring能够find我的java bean,这样我就不必在XML中定义所有的bean,也不需要JavaConfig。 例如,对于无状态的单独java bean,只需要连接到其他类(理想地通过一个接口),这种方法运行得非常好。 一般来说,对于Spring bean,我大部分都是从Spring XML DSL中移除来定义bean,现在又赞成使用JavaConfig和Spring Annotations,因为你可以在编译时检查一下你的configuration和一些重构支持,使用Spring XMLconfiguration。 在某些极less数情况下,我发现JavaConfig / Annotations不能完成使用XMLconfiguration的function。

对于Hibernate ORM(尚未使用JPA),我仍然更喜欢XML映射文件,因为域模型类中的注释在一定程度上违反了我在过去几年中采用的分层体系结构风格的“清洁体系结构”。 发生违规是因为它要求核心层依赖于持久化相关的东西,如Hibernate或JPA库,它使域模型POJOsless一点持久性无知。 事实上,核心层不应该依赖任何其他基础设施。

但是,如果“清洁架构”不是您的“一杯茶”,那么我可以看到,在分离的XML映射文件中,在域模型类中使用Hibernate / JPA注释具有一定的优势(例如便利性和可维护性)。