Xml配置与基于注释的配置[关闭]


131

在最近我从事的一些大型项目中,选择其中一个(XML或注释)似乎变得越来越重要。随着项目的发展,一致性对于可维护性非常重要。

我的问题是:与基于注释的配置相比,基于XML的配置有哪些优势?与基于XML的配置相比,基于注释的配置有哪些优势?


假设您的意思是@Component@Autowired,这是错误的二分法。还有其他创建配置的方法,包括JavaConfig和groovy config。
bacar


Answers:


199

注释有其用途,但它们并不是杀死XML配置的灵丹妙药。我建议将两者混合!

例如,如果使用Spring,则将XML用于应用程序的依赖项注入部分是完全直观的。相比之下,这使代码的依赖关系脱离了将要使用它的代码,相反,在代码中使用某种需要依赖关系的注释使代码知道这种自动配置。

但是,不是将XML用于事务管理,而是将方法标记为带有注释的事务是很有意义的,因为这是程序员可能希望知道的信息。但是,不应将接口作为SubtypeY而不是SubtypeX插入类中,因为如果您现在想注入SubtypeX,则必须更改代码,而无论如何您都必须先进行接口协定,所以使用XML,您只需要更改XML映射即可,而且这样做非常快捷,轻松。

我没有使用过JPA批注,所以我不知道它们的优劣,但是我认为将bean的映射关系保留为XML也很好,因为该对象不必关心其信息来自何处。 ,它应该只关心它可以使用其信息做什么。但是,如果您喜欢JPA(我对此没有任何经验),则一定要这样做。

一般而言:如果注释提供功能并本身充当注释,并且不将代码绑定到某些特定过程以在没有此注释的情况下正常运行,请使用注释。例如,标记为事务性的事务方法不会破坏其操作逻辑,并且还可以充当良好的代码级注释。否则,此信息最好用XML表示,因为尽管它最终会影响代码的运行方式,但不会更改代码的主要功能,因此不属于源文件。


感谢您的出色回答!我在决定使用哪个方面遇到了一些困难。这样的回答说他们促进去耦,而这篇博客文章说他们促进紧密耦合!您的回答确实为我澄清了问题。
Mikayla Maki 2014年

5
我将这个建议总结为:对AOP使用注释(例如,可以将事务视为一个方面),但不要将其用于依赖项注入。
bacar 2014年

1
如今(2015年),这个答案仍然是热门话题吗?
sp00m 2015年

1
在大多数情况下,对于大多数人来说,似乎更希望使用注释
Junjun Liu

31

这里存在着一个更广泛的问题,即外部化与内联元数据。如果您的对象模型只能以一种方式持久化,那么内联元数据(即注释)将更加紧凑和可读。

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

尽管注解更时髦,但哪一个都不是更好,因此两者都受支持。结果,像JPA这样的新的发烧友式框架倾向于更加重视它们。像本地Hibernate这样的更成熟的API可以同时提供这两种功能,因为众所周知,这两个都不足够。


13

我经常思考的注解作为某种指标的东西一类是能够,或者如何将其与他人互动。

另一方面,Spring XML配置对我来说就是配置

例如,有关代理的ip和端口的信息明确地进入了XML文件,它是运行时配置。

使用@Autowire@Element以表明框架做什么用的类是很好用的注解。

将URL放入@Webservice批注是不好的样式。

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


注释和基于注释的配置(Java config)是两件不同的事情,OP在您谈论前者时会询问后者。
2015年

6

我已经使用Spring几年了,所需的XML数量肯定变得乏味。在Spring 2.5中新的XML模式和注释支持之间,我通常会执行以下操作:

  1. 使用“ component-scan”来自动加载使用@ Repository,@ Service或@Component的类。我通常给每个bean一个名称,然后使用@Resource将它们连接在一起。我发现该管道不会经常更改,因此注释是有意义的。

  2. 对所有AOP使用“ aop”命名空间。这确实很棒。我仍然将其用于事务处理,因为将@Transactional放在所有位置都是一种拖累。您可以为任何服务或存储库上的方法创建命名切入点,并很快应用建议。

  3. 我将LocalContainerEntityManagerFactoryBean和HibernateJpaVendorAdapter一起使用来配置Hibernate。这使Hibernate可以轻松地在类路径上自动发现@Entity类。然后,使用引用LCEMFB的“ factory-bean”和“ factory-method”创建一个名为SessionFactory的bean。


5

使用仅批注方法的重要部分是“ bean名称”的概念或多或少地消失了(变得无关紧要)。

Spring中的“ bean名称”在实现类上形成了附加的抽象层次。带有XML的bean是相对于其bean名称定义和引用的。使用注释时,它们由其类/接口引用。(尽管bean名称存在,但是您不需要知道它)

我坚信摆脱多余的抽象可以简化系统并提高生产率。对于大型项目,我认为摆脱XML可以带来可观的收益。


5

我认为可见性是基于XML的方法的一大胜利。我发现XML并没有那么糟糕,因为那里提供了用于导航XML文档的各种工具(即Visual Studio + ReSharper的File Structure窗口)。

您当然可以采取混合方法,但是这对我来说似乎很危险,仅因为可能会导致项目中的新开发人员很难弄清楚在何处配置或映射不同的对象。

我不知道; 最终,XML Hell对我来说似乎并不那么糟糕。


4

这取决于您要配置的所有内容,因为有些选项无法使用注释进行配置。如果我们从注解的侧面看到它:

  • 加:注解少说话
  • 减:注释不可见

由您决定更重要的是...

通常,我建议选择一种方法,并在产品的某些封闭部分中使用它。

(但有一些例外:例如,如果您选择基于XML的配置,则可以使用@Autowire注释。混合使用,但这有助于提高可读性和可维护性)



3

我可能错了,但是我认为注释(如Java的@Tag和C#的[Attribute])是编译时选项,而XML是运行时选项。对我来说,这并不等同,并且各有优缺点。


注释是编译时的事实是基于注释的配置的事实,但是注释和xml都是用于配置的方法,在这种情况下,它们可以实现相同的目的。例如。在xml文件中配置休眠映射,而不是在类上使用注释。
abarax

啊,我看到了我的困惑。这个问题使我误以为这是在描述类元数据之外的数据配置。
ARKBAN

3

我也认为混合是最好的选择,但它也取决于配置参数的类型。我正在研究一个也使用Spring的Seam项目,通常将其部署到不同的开发和测试服务器上。所以我分裂了:

  • 服务器特定的配置(类似于服务器上资源的绝对路径):Spring XML文件
  • 将bean作为其他bean的成员注入(或在许多bean中重用Spring XML定义的值):注释

关键区别在于,您不必为所有更改的服务器特定配置重新编译代码,只需编辑xml文件。还有一个优点是,一些不了解所有相关代码的团队成员可以完成一些配置更改。


2

在DI容器的范围内,我认为基于注释的DI正在滥用Java注释。话虽如此,我不建议在您的项目中广泛使用它。如果您的项目确实需要DI容器的功能,我建议将Spring IoC与基于Xml的配置选项一起使用。

如果仅出于单元测试的考虑,开发人员应在代码中应用依赖注入模式,并利用EasyMock或JMock等模拟工具来规避依赖关系。

您应该尝试避免在错误的上下文中使用DI容器。


2

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

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

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

1

这是经典的“配置与约定”问题。在大多数情况下,个人品味决定了答案。但是,我个人更喜欢Configuration(即基于XML)而不是Convention。IMO IDE具有足够的鲁棒性,足以克服人们经常与建筑相关的XML地狱,并维护基于XML的方法。最后,从长远来看,我发现Configuration的好处(例如构建用于构建,维护和部署XML配置文件的实用程序)的好处超过了Convention。


6
我认为“配置与约定”与这个问题正交。注释和XML文件都有许多合理的默认值(约定),可以极大地简化其使用。真正的区别是编译时与运行时以及代码内与代码外。
HDave 2010年

1

我都用。大多数情况下是XML,但是当我有一堆从公共类继承并具有公共属性的bean时,我在超类中为它们使用了批注,因此不必为每个bean设置相同的属性。因为我有点控制狂,所以我使用@Resource(name =“ referredBean”)而不是自动装配东西(如果我需要与原始ReferedBean相同类的另一个bean,可以省去很多麻烦) 。


1

根据我的经验,注释配置有一些优点和缺点:

  • 当涉及到JPA配置时,因为它只需完成一次并且通常不会经常更改,所以我更喜欢坚持注释配置。可能会担心看到更大的配置图-在这种情况下,我使用MSQLWorkbench图。
  • Xml配置非常有助于获得更大的应用程序图景,但要找到一些错误,直到运行时,这可能会很麻烦。在这种情况下,Spring @Configuration批注听起来是一个更好的选择,因为它不仅可以让您看到更大的图片,还可以在编译时验证配置。
  • 对于Spring配置,我更喜欢将两种方法结合使用:使用@Configuration批注与Services和Query接口一起使用,并将xml配置用于dataSource和spring配置,例如context:component-scan base-package =“ ...”
  • 但是xml配置在流程配置(Spring Web Flow或Lexaden Web Flow)方面使用了Java注释,因为看到整个业务流程的整体图非常重要。用注释方法实现它听起来很麻烦。

我更喜欢将两种方法结合使用-Java注释和必要的xml最小化(最小化配置)。


1

对于Spring Framework,我喜欢这样的想法:能够使用@Component批注并设置“ component-scan”选项,以便Spring可以找到我的Java bean,这样就不必在XML中定义所有bean,也不必在XML中定义所有bean。 JavaConfig。例如,对于仅需要(理想情况下通过接口)连接到其他类的无状态单例Java bean,此方法效果很好。总的来说,对于Spring bean,我大部分时候都不再使用Spring XML DSL来定义bean,现在更喜欢使用JavaConfig和Spring Annotations,因为您可以对配置进行编译时检查,并且可以得到一些重构支持。无法获得Spring XML配置。在某些罕见的情况下,我确实将两者混为一谈,因为我发现JavaConfig / Annotations无法完成使用XML配置的可用功能。

对于Hibernate ORM(尚未使用JPA),我仍然更喜欢XML映射文件,因为域模型类中的注释在某种程度上违反了Clean Architecture。,即我过去几年采用的分层体系结构样式。发生违规是因为它要求核心层依赖于与持久性相关的事物(例如Hibernate或JPA库),并且使域模型POJO的持久性少了一些。实际上,核心层根本不应该依赖于任何其他基础架构。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.