【问题标题】:Spring configuration XML schema: with or without version?Spring 配置 XML 模式:有或没有版本?
【发布时间】:2014-01-20 14:15:52
【问题描述】:

我是 Spring 新手。让我感到困惑的一件事是,有时我会看到带有版本化模式的 XML 配置文件,但有时会看到非版本化模式。例如,有时我会看到类似

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <context:annotation-config/>

    <context:component-scan base-package="base.package"/>

</beans>

有时像这样:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

    <context:component-scan base-package="base.package"/>

</beans>

请注意,两个示例中的 spring-beansspring-context 架构不同。

所以,我的问题是,你会使用哪种风格,为什么?特别是,版本化模式将来会变得不可用,当 Spring 更新模式时,非版本化模式是否会与当前应用程序保持兼容?

一个附带的问题是,我在哪里可以找到版本化的 Spring 模式列表?

非常感谢!

【问题讨论】:

标签: java spring


【解决方案1】:

考虑使用无版本 xsd。这将使工具获取与您正在使用的 spring jar 版本匹配的 xsd 版本(查看 jar 中的 spring.schemas 文件)。如果在升级 Spring 库时出现任何不兼容(这应该很少见),您应该能够在构建期间捕获它。

这将提供一个机会来决定是否需要为该文件引入版本化 xsd 或实际从使用过时和不推荐的属性/元素演变而来。希望是后者。

否则风险是永远使用可能已弃用的属性/元素。

【讨论】:

    【解决方案2】:

    我已报名参加 udemy 的春​​季课程。我按照老师教我做的每一个步骤去做。 所以如果你使用spring mvc和hibernate你可能会遇到这个错误 无法读取架构文档“http://www.springframework.org/schema/tx/spring-tx.xsd”等:

    <mvc:annotation-driven/> and <tx:annotation-driven transaction-manager="myTransactionManager" /> elements
    

    在我的 spring 配置文件中我有这两个 url

        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
    
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx.xsd
    

    在 xsi:schemaLocation 中,我将其替换为

        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
    
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
    

    实际上我访问了这两个站点 http://www.springframework.org/schema/mvc/http://www.springframework.org/schema/tx/ 并且刚刚添加了最新版本的 spring-mvc 和 spring-tx,即 spring-mvc-4.2.xsd 和 spring-tx-4.2.xsd

    所以,在我看来,明确指定版本 no 是一个好习惯。 希望这可以帮助。 谢谢。

    【讨论】:

      【解决方案3】:

      您会在您的 Jar 中找到 META-INF/spring.schemas 文件。该文件定义了所有兼容的 xsd 版本。如果您指向没有任何版本号的 URL,默认情况下它将与您的 Jar 文件兼容。只要您在类路径中没有两个不同版本的 spring jar,您的应用程序就不会出现任何运行时错误。

      【讨论】:

        【解决方案4】:

        我知道这个问题已经有两年多了,但我的看法是谨慎行事。

        在我的例子中,我正在开发一个独立的 CLI 工具,一罐罐子。当我声明的 XSD 是无版本的(原文如此)时,我会注意到非常奇怪的错误。考虑以下 xml 片段:

        如果没有版本,属性占位符中的value-separator属性会导致以下错误:

        org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 22 in XML document from class path resource [META-INF/slitools/sli-cli-applicationContext.xml] is invalid; nested exception is org.xml.sax.SAXParseException: cvc-complex-type.3.2.2: Attribute 'value-separator' is not allowed to appear in element 'context:property-placeholder'.
            at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:399)
        

        人们可以尝试通过传递依赖来查看到底是什么被拉取(尽管仔细检查表明我们正在拉取包含正确 xsds 的正确 jars(并确保我们在做正确的属性时与 shade 插件合并)构建超级罐子。)

        显然是 YMMV。如果它适用于一个项目,那就更好了。但是,如果您开始看到无法解释的奇怪错误,并且您没有足够的带宽将它们追查到根本原因,那么最好准确地说。

        与此相反的论点是,如果您更改了 spring 依赖项的版本,则需要确保显式 xsd 版本是正确的。在软件中,一切都是关于权衡(以及了解您的决策所涉及的内容。)

        【讨论】:

        • 好点。我的想法与声明的配置相同,考虑到较低版本可能会在较高版本上中断。
        【解决方案5】:

        建议使用“无版本”XSD,因为它们映射到您在应用程序中使用的框架的当前版本。

        应用程序和工具不应该尝试从 Web 获取这些 XSD,因为这些模式包含在 JAR 中。如果是这样,这通常意味着您的应用正在尝试使用比您正在使用的框架版本更新的 XSD,或者您的 IDE/工具未正确配置。

        据我所知,只有一种情况需要使用特定的 XSD 版本:尝试使用在较新版本中已被弃用/修改的 XML 属性时。至少可以说,这种情况并不经常发生。

        无论如何,Spring 团队应该放弃 Spring 5.0 的版本化架构,请参阅 SPR-13499

        更多关于“无版本 == 当前版本”:

        那些 XSD 文件包含在 Spring JAR 中——“无版本”XSD 在构建期间映射到最新版本(请参阅实际建立该链接的 spring.schemas 文件)。 此外,在线提供的文件也是以相同的方式构建的(请参阅"schemaZip" target in the gradle build)。

        【讨论】:

        • 我们知道,schemaLocation 中的信息作为“提示”提供给 xml 处理器。因此,当 xml 处理器分析 xml 时,它会发现 xsd 文件符合 spring.schemas 定义。但是我无法理解的一件事,对于xml编辑器,如果我们定义了schemaLocation,它会在我们输入时自动完成,那么它是怎么知道的呢?它还引用了 spring.schemas 中的定义?或者从远程服务器下载 xsd 文件?如果从远程服务器下载文件,也就是说,如果我们不指定版本,它会引用最新版本。
        • 可能会出现一种情况,如果它从远程服务器下载文件,那么xsd总是最新版本,所以如果一个元素定义在最新版本而不是我们项目使用的版本(低版本),会发生什么? xml处理器从本地jar加载xsd,无法识别元素定义。
        • 我遇到了situation,其中版本导致我出现 HTTP 404... 我的意思是在删除版本后它工作正常。你知道为什么吗?
        • 我无法确保 eclipse 09-2018 永远不会从 web 获取 Spring 模式。由于在 URL 中没有版本的在线 Spring Integration XSD 是古老的 1.0 版本,这导致我在 Eclipse 编辑器中的 XML 中出现零星的错误标记。在此处查看在线 XSD 中的 important notespringframework.org/schema/integration/spring-integration.xsd 或此处:springframework.org/schema/integration/xml/…
        【解决方案6】:

        我不确定它们是否是一个指导,但我个人的偏好是参考非版本化模式 - 通常,如果您正在使用 Spring 项目的更新版本(Spring 核心、集成等),然后您可以参考未版本化的模式。

        未版本化的模式指向项目的最新版本,因此如果您使用的是 Spring 的真正旧版本(例如 2.5 版与当前发布的 4.0 版),它们可能不是正确的语法,在这种情况下它指向版本化模式可能会更好。

        这里要说明的一点是,如果可能的话,最好完全避免使用 xml 并使用Java based @Configuration 样式来配置您的 Spring bean。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-09-29
          • 1970-01-01
          • 2014-01-24
          • 1970-01-01
          • 2023-03-05
          • 2015-05-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多