【问题标题】:Xml configuration versus Annotation based configuration [closed]Xml配置与基于注释的配置[关闭]
【发布时间】:2010-09-15 23:50:12
【问题描述】:

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

我的问题是:基于 XML 的配置相对于基于注解的配置有哪些优势?基于注解​​的配置相对于基于 XML 的配置有哪些优势?

【问题讨论】:

标签: java xml spring annotations


【解决方案1】:

我一直认为注释是一种指示一个类的能力,或者它如何与其他人交互。

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

例如,关于代理的 ip 和端口的信息,肯定会进入 XML 文件,它是运行时配置。

使用@Autowire,@Element来表示框架对类的处理是很好的使用注解。

将 URL 放入 @Webservice 注释是不好的风格。

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

【讨论】:

  • 注解和基于注解的配置(Java config)是两个不同的东西,当你谈论前者时,OP 会询问后者。
【解决方案2】:

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

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

  1. Annotations vs XML, advantages and disadvantages
  2. http://www.ibm.com/developerworks/library/j-cwt08025/

【讨论】:

    【解决方案3】:

    对于 Spring 框架,我喜欢能够使用 @Component 注释并设置“组件扫描”选项的想法,以便 Spring 可以找到我的 Java bean,这样我就不必在 XML 中定义我的所有 bean ,也不是在 JavaConfig 中。例如,对于只需要连接到其他类(理想情况下通过接口)的无状态单例 Java bean,这种方法非常有效。一般来说,对于 Spring bean,我大部分时间都放弃了用于定义 bean 的 Spring XML DSL,现在更倾向于使用 JavaConfig 和 Spring Annotations,因为您可以获得一些编译时检查配置和一些重构支持,而您没有无法使用 Spring XML 配置。在我发现 JavaConfig/Annotations 无法完成使用 XML 配置可用的功能的某些极少数情况下,我确实将两者混合使用。

    对于 Hibernate ORM(还没有使用过 JPA)我仍然更喜欢 XML 映射文件,因为域模型类中的注释在某种程度上违反了The Clean Architecture,这是我过去几年采用的一种分层架构风格。发生违规是因为它要求核心层依赖于持久性相关的东西,例如 Hibernate 或 JPA 库,并且它使域模型 POJO 对持久性的无知程度降低了一些。事实上,核心层根本不应该依赖任何其他基础设施。

    但是,如果 The Clean Architecture 不是您的“一杯茶”,那么我可以看到在域模型类中使用 Hibernate/JPA 注释肯定比单独的 XML 映射文件具有优势(例如方便性和可维护性)。

    【讨论】:

      【解决方案4】:

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

      • 当涉及到 JPA 配置时,因为它只完成一次并且通常不会经常更改,因此我更愿意坚持使用注解配置。可能会担心看到更大的配置图 - 在这种情况下,我使用 MSQLWorkbench 图表。
      • Xml 配置非常适合获得更大的应用程序图,但在运行之前发现一些错误可能很麻烦。在这种情况下,Spring @Configuration 注释听起来是一个更好的选择,因为它可以让您看到更大的图景,并且还允许在编译时验证配置。
      • 至于 Spring 配置,我更喜欢将这两种方法结合起来:将 @Configuration 注释与 Services 和 Query 接口和 xml 配置用于 dataSource 和 spring 配置内容,例如 context:component-scan base-package=" ……”
      • 但是当涉及到流配置(Spring Web Flow 或 Lexaden Web Flow)时,xml 配置位 java 注释,因为看到整个业务流程的更大图景非常重要。而且用注解的方式来实现听起来很麻烦。

      我更喜欢将这两种方法结合起来 - java 注释和基本 xml 最小化配置地狱。

      【讨论】:

        【解决方案5】:

        还有其他方面可以比较,例如重构和其他代码更改。使用 XML 时,重构需要付出很大的努力,因为您必须处理所有 XML 内容。但是使用注解很容易。

        我的首选方式是基于 Java 的配置,没有(或最少)注释。 http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-java

        【讨论】:

          【解决方案6】:

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

          如果只是为了单元测试,开发人员应该在他们的编码中应用依赖注入模式,并利用 EasyMock 或 JMock 等模拟工具来规避依赖关系。

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

          【讨论】:

            【解决方案7】:

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

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

            两者都不是更好,因此两者都受支持,尽管注释更时尚。因此,像 JPA 这样的新框架往往会更加强调它们。更成熟的 API(如原生 Hibernate)两者都提供,因为众所周知,这两者都不够。

            【讨论】:

              【解决方案8】:

              我认为可见性是基于 XML 的方法的一大胜利。我发现 XML 并没有那么糟糕,考虑到用于导航 XML 文档的各种工具(即 Visual Studio + ReSharper 的文件结构窗口)。

              您当然可以采用混合方法,但这对我来说似乎很危险,因为这可能会使项目的新开发人员难以弄清楚不同对象的配置或映射位置。

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

              【讨论】:

                【解决方案9】:

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

                1. 使用“组件扫描”自动加载使用@Repository、@Service 或@Component 的类。我通常给每个 bean 一个名字,然后使用 @Resource 将它们连接在一起。我发现这个管道不会经常改变,所以注释很有意义。

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

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

                【讨论】:

                  【解决方案10】:

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

                  Spring 中的“bean 名称”在实现类之上形成了一个额外的抽象级别。使用 XML bean 是相对于它们的 bean 名称定义和引用的。使用注释,它们被它们的类/接口引用。 (虽然bean名称存在,但不需要知道)

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

                  【讨论】:

                    【解决方案11】:

                    我两个都用。主要是 XML,但是当我有一堆从公共类继承并具有公共属性的 bean 时,我在超类中为它们使用注释,因此我不必为每个 bean 设置相同的属性。因为我有点控制狂,我使用 @Resource(name="referredBean") 而不仅仅是自动装配的东西(如果我需要另一个与原始引用Bean 相同类的 bean,可以为自己省去很多麻烦) .

                    【讨论】:

                      【解决方案12】:

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

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

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

                      【讨论】:

                        【解决方案13】:

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

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

                        但是,与其使用 XML 进行事务管理,不如使用注释将方法标记为事务性是非常有意义的,因为这是程序员可能希望知道的信息。但是一个接口将被注入为 SubtypeY 而不是 SubtypeX 不应该包含在类中,因为如果现在你想注入 SubtypeX,你必须改变你的代码,而你之前有一个接口契约,所以使用 XML,您只需要更改 XML 映射,并且这样做相当快速且轻松。

                        我没有使用 JPA 注释,所以我不知道它们有多好,但我认为将 bean 映射到 XML 中的数据库也很好,因为对象不应该关心它的位置信息来自哪里,它应该只关心它可以用它的信息做什么。但是如果你喜欢 JPA(我没有任何经验),那就去吧。

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

                        【讨论】:

                        • 感谢您的精彩回答!我一直很难决定使用哪个。 This SO answer 说他们提倡去耦,而this blog post 说他们提倡紧密耦合!您的回答确实为我澄清了问题。
                        • 我将这个建议总结为:为 AOP 使用注解(例如,事务可以被视为一个方面),但不要将其用于依赖注入。
                        • 这个答案现在(2015 年)仍然是热门话题吗?
                        • 在大多数情况下,对于大多数人来说,注释是首选
                        【解决方案14】:

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

                        • 加:注释不那么啰嗦
                        • 减号:注释不太明显

                        由你决定什么更重要......

                        一般来说,我建议选择一种方式,并在产品的某个封闭部分使用它...

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

                        【讨论】:

                          【解决方案15】:

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

                          【讨论】:

                          • 我认为“配置与约定”与这个问题是正交的。注释和 XML 文件都有许多合理的默认值(约定),大大简化了它们的使用。真正的区别在于编译时与运行时以及代码内与代码外。
                          【解决方案16】:

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

                          【讨论】:

                          • 注解是编译时的事情,这是基于注解的配置的一个优点,但是注解和 xml 都是配置方法,在这种情况下,它们实现了相同的目的。例如。在 xml 文件中配置休眠映射,而不是在类上使用注释。
                          • 啊,我明白了我的困惑。这个问题误导我认为它描述的数据配置超出了类元数据。
                          猜你喜欢
                          • 2012-01-15
                          • 1970-01-01
                          • 2017-05-27
                          • 2015-07-11
                          • 2016-08-02
                          • 2017-06-23
                          • 2015-12-06
                          • 2017-06-25
                          • 2011-11-01
                          相关资源
                          最近更新 更多