在我最近一直在努力的一些大型项目中,选择其中一个(XML或Annotation)似乎变得越来越重要。随着项目的增长,一致性对于可维护性非常重要。
我的问题是:与基于注释的配置相比,基于XML的配置有哪些优势?与基于XML的配置相比,基于注释的配置有哪些优势?
答案 0 :(得分:197)
注释有其用途,但它们不是杀死XML配置的银弹。我建议将两者混合使用!
例如,如果使用Spring,则将XML用于应用程序的依赖项注入部分是完全直观的。这使得代码的依赖性远离将要使用它的代码,相反,在需要依赖关系的代码中使用某种注释使代码知道这种自动配置。
但是,不是使用XML进行事务管理,而是将方法标记为带有注释的事务,这非常有意义,因为这是程序员可能希望知道的信息。但是一个接口将被注入为SubtypeY而不是SubtypeX不应该包含在类中,因为如果现在你想要注入SubtypeX,你必须改变你的代码,而你之前有一个接口契约,所以使用XML,您只需要更改XML映射,这样做非常快速,轻松。
我没有使用JPA注释,所以我不知道它们有多好,但我认为将bean映射到XML中的数据库也很好,因为对象不应该关心它在哪里信息来自,它应该只关心它可以用它的信息做什么。但是如果你喜欢JPA(我对它没有任何考虑),那么一定要去吧。
一般情况下: 如果注释提供了功能并且在其自身中充当注释,并且没有将代码绑定到某个特定进程以便在没有此注释的情况下正常运行,那么请转到注释。例如,标记为事务的事务方法不会终止其操作逻辑,也可以作为良好的代码级注释。否则,此信息可能最好表示为XML,因为尽管它最终会影响代码的运行方式,但它不会更改代码的主要功能,因此不属于源文件。
答案 1 :(得分:30)
这里存在一个更广泛的问题,即外部化和内联元数据。如果您的对象模型只是以某种方式持久存在,那么内联元数据(即注释)将更加紧凑和可读。
但是,如果您的对象模型在不同的应用程序中重用,每个应用程序都希望以不同的方式保留模型,那么外部化元数据(即XML描述符)会变得更合适。
两者都不是更好,因此两者都得到支持,尽管注释更加时尚。因此,像JPA这样的新型触发框架往往更加强调它们。像原生Hibernate这样的更成熟的API提供了两者,因为众所周知,这两者都不够。
答案 2 :(得分:13)
我一直认为注释是某个类的能力的某种指示,或者 它与其他人的交互方式。
另一方面,对我来说,Spring XML配置只是配置例如,有关代理的ip和端口的信息肯定会进入XML文件,它是运行时配置。
使用@Autowire
,@Element
来表明框架如何处理该类是很好地使用注释。
将网址放入@Webservice
注释是不好的风格。
但这只是我的意见。 交互和配置之间的界限并不总是很清楚。
答案 3 :(得分:6)
我已经使用Spring几年了,所需的XML数量肯定变得乏味。在Spring 2.5中的新XML模式和注释支持之间,我通常会做这些事情:
使用“component-scan”自动加载使用@ Repository,@ Service或@Component的类。我通常给每个bean命名,然后使用@Resource将它们连接在一起。我发现这个管道并没有经常变化,因此注释是有意义的。
对所有AOP使用“aop”命名空间。这真的很棒。我仍然将它用于交易,因为将@Transactional放在所有地方都是一种拖累。您可以为任何服务或存储库上的方法创建命名切入点,并快速应用建议。
我使用LocalContainerEntityManagerFactoryBean和HibernateJpaVendorAdapter来配置Hibernate。这让Hibernate可以轻松地自动发现类路径上的@Entity类。然后我使用“factory-bean”和“factory-method”创建一个名为SessionFactory的bean,引用LCEMFB。
答案 4 :(得分:5)
使用仅注释方法的一个重要部分是“bean名称”的概念或多或少会消失(变得无关紧要)。
Spring中的“bean名称”形成了对实现类的额外抽象级别。使用XML bean相对于其bean名称进行定义和引用。使用注释,它们的类/接口引用它们。 (尽管bean名称存在,但您不需要知道它)
我坚信,摆脱多余的抽象可以简化系统并提高生产力。对于大型项目,我认为通过删除XML获得的收益可能很大。
答案 5 :(得分:5)
我认为可见性是基于XML的方法的一大胜利。鉴于用于导航XML文档的各种工具(即Visual Studio + ReSharper的文件结构窗口),我发现XML并不是那么糟糕。
你当然可以采用混合方法,但这对我来说似乎很危险,只是因为它可能会让项目上的新开发人员难以找出配置或映射不同对象的位置。
我不知道;最后,XML Hell对我来说似乎并不那么糟糕。
答案 6 :(得分:4)
这取决于您要配置的所有内容,因为有些选项无法使用anotations进行配置。如果我们从注释的一边看到它:
这取决于你更重要的事情......
一般情况下,我建议选择一种方式,并将其全部用于产品的封闭部分......
(除了一些例外:例如,如果您选择基于XML的配置,则可以使用@Autowire注释。它是混合的,但这有助于可读性和可维护性)
答案 7 :(得分:4)
还有其他方面需要比较重构和其他代码更改。使用XML时,需要花费大量精力进行重构,因为您必须处理所有XML内容。但是使用Annotations很容易。
我首选的方法是没有(或最小)注释的基于Java的配置。 http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-java
答案 8 :(得分:3)
我可能错了,但我认为Annotations(如Java的@Tag和C#的[Attribute])是编译时选项,而XML是运行时选项。对我来说,这不是等同的,有不同的利弊。
答案 9 :(得分:3)
我也认为混合是最好的,但它也取决于配置参数的类型。 我正在开发一个也使用Spring的Seam项目,我通常将它部署到不同的开发和测试服务器上。所以我分手了:
关键区别在于您不必为所有更改服务器的配置重新编译代码,只需编辑xml文件即可。 还有一个优点是,一些配置更改可以由不了解所有相关代码的团队成员完成。
答案 10 :(得分:2)
在DI容器的范围内,我认为基于注释的DI滥用Java注释的使用。通过这样说,我不建议在您的项目中广泛使用它。如果您的项目确实需要DI容器的强大功能,我建议使用Spring IoC和基于Xml的配置选项。
如果只是为了单元测试,开发人员应该在编码中应用Dependency Inject模式,并利用EasyMock或JMock等模拟工具来规避依赖关系。
您应该尽量避免在错误的上下文中使用DI容器。
答案 11 :(得分:2)
始终将链接到特定Java组件(类,方法或字段)的配置信息是由注释表示的良好候选者。在这种情况下,当配置是代码目的的核心时,注释特别有效。由于注释的限制,每个组件只能有一个配置时也是最好的。如果您需要处理多个配置,尤其是那些以包含注释的Java类之外的任何形式为条件的配置,注释可能会产生比它们解决的更多问题。最后,如果不重新编译Java源代码就无法修改注释,因此在运行时需要重新配置的任何内容都不能使用注释。
请参阅以下链接。它们也可能有用。
答案 12 :(得分:1)
这是经典的“配置与公约”问题。在大多数情况下,个人品味决定了答案。但是,就个人而言,我个人更喜欢配置(即基于XML)。 IMO IDE足够强大,足以克服人们经常与构建和维护基于XML的方法相关联的一些XML。最后,我发现配置的好处(例如构建实用程序来构建,维护和部署XML配置文件)从长远来看超过了Convention。
答案 13 :(得分:1)
我同时使用两者。主要是XML,但是当我有一堆bean从公共类继承并具有公共属性时,我在超类中使用注释,因此我不必为每个bean设置相同的属性。因为我有点像控制狂,所以我使用@Resource(name =“referencedBean”)而不仅仅是自动装配东西(如果我需要与原始referBean相同类的另一个bean,可以省去很多麻烦)
答案 14 :(得分:1)
根据我的经验,注释配置有一些优点和缺点:
我更喜欢将两种方法结合起来 - 使用Java注释和必要的xml最小化来最小化配置地狱。
答案 15 :(得分:1)
对于Spring Framework,我喜欢能够使用@Component注释并设置“component-scan”选项,以便Spring可以找到我的java bean,这样我就不必在XML中定义所有的bean了。 ,也不是JavaConfig。例如,对于无状态单例java bean,只需要连接到其他类(通过理想的接口),这种方法非常有效。一般来说,对于Spring bean,我大部分时间都不使用Spring XML DSL来定义bean,现在支持使用JavaConfig和Spring Annotations,因为你可以通过编译时检查你的配置和一些重构支持。使用Spring XML配置。在某些罕见的情况下,我确实混合了两者,我发现JavaConfig / Annotations无法使用XML配置执行可用的操作。
对于Hibernate ORM(尚未使用JPA)我仍然更喜欢XML映射文件,因为域模型类中的注释在某种程度上违反了The Clean Architecture,这是我过去几年采用的分层架构风格。发生这种违规是因为它要求核心层依赖于与持久性相关的东西,如Hibernate或JPA库,这使得域模型POJO的持久性不那么明显。事实上,核心层根本不应该依赖任何其他基础设施。
然而,如果The Clean Architecture不是你的“茶”那么我可以看到在域模型类中使用Hibernate / JPA注释而不是单独的XML映射文件肯定有优势(例如方便性和可维护性)。