“此服务器是否仅用作命名空间(避免命名冲突的方式)或可以将哪些元素添加到 xml 文档中?”
后者。
Namesapces 用于标识架构定义中的元素和属性。
“我正在添加元素(休眠/弹簧配置),它抱怨我们需要添加一些命名空间?”
使用 Spring 进行持久化,您通常需要 spring-orm jar、spring-jdbc、spring-tx,可能还有其他一些。通常,所有spring-xxx jar 都带有它们的模式定义。如上所述,如果要在该特定模式中使用元素,则需要在上下文文件中添加命名空间。
您当前拥有的命名空间只是 beans 和 context 命名空间。如果您查看 xsd,您将看到这些名称空间允许的所有顶级元素。例如,bean 命名空间只允许<alias>、<bean>、<beans>、<description> 和<import>。而上下文命名空间只支持
<context:annotation-config>
<context:component-scan>
<context:load-time-weaver>
<context:mbean-export>
<context:mbean-server>
<context:property-override>
<context:property-placeholder>
<context:spring-configured>
因为 beans 是文档的默认命名空间
<beans xmlns="http://www.springframework.org/schema/beans"
您不需要像 <context:component-scan> 那样为元素添加前缀(例如 <beans:bean>)
至于您当前的问题“它抱怨我们需要添加一些命名空间”...您实际上并没有提供足够的信息来帮助您调查问题,但通常在这样做时持久性,您将需要 tx 命名空间来处理事务,如果您想使用嵌入式数据库,您可能需要带有 <jdbc:embedded-database> 元素的 jdbc 命名空间。
这只是一般的猜测工作。
" 我有这样的疑问,为什么添加 spring 期望的命名空间(对于任何 xml 解析器)将能够获取元素。XSD 的工作不是告诉所有元素可以包含在一个XML 文档?”
您的误解有点不清楚,但就像任何其他基于模式的 xml 一样,它需要验证。模式就像一个类定义。类定义是该类实例所允许的约定。
Spring,使用您的上下文来创建您定义的所有 bean。如果定义不正确,Spring 可能不知道如何处理您的 xml。这就是我们有模式的原因 - 为了遵循他的指导方针,更高级别的应用程序需要你遵循才能工作。
Spring 在后台所做的是获取您的 xml 文件,并使用相应的NamespaceHandler,它能够找到您需要的解析器。解析器的工作是创建允许 Spring 容器实例化您的 bean 的 bean 定义
示例流程:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:oxm="http://www.springframework.org/schema/oxm"
xsi:schemaLocation="http://www.springframework.org/schema/oxm
http://www.springframework.org/schema/oxm/spring-oxm-4.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<oxm:jaxb2-marshaller>
<oxm:class-to-be-bound name="com.underdogdevs.spring.oxm.Application" />
</oxm:jaxb2-marshaller>
</beans>
使用jaxb2-marshaller 的oxm 命名空间,该命名空间在其中一个jar 包的spring-oxm-4.0.xsd 中定义。
注意schemaLocation http://www.springframework.org/schema/oxm/spring-oxm-4.0.xsd。 Spring 将使用它来确定处理程序。
-
查看包含在每个spring-xxx.jar 中的META-INF,您会发现spring.schemas 和spring.handlers 文件。在那里你会发现
http\://www.springframework.org/schema/oxm/
spring-oxm-4.0.xsd=org/springframework/oxm/config/spring-oxm-4.0.xsd
http\://www.springframework.org/schema
/oxm=org.springframework.oxm.config.OxmNamespaceHandler
这告诉 spring 要验证哪个架构,以及要使用的命名空间处理程序分别是 OxmNamespaceHandler。
-
如果我们查看OxmNamespaceHandler 类,您会发现
registerBeanDefinitionParser("jaxb2-marshaller",
new Jaxb2MarshallerBeanDefinitionParser());
现在发生的事情是命名空间处理程序将我们引导到正确的解析器。
-
现在看看Jaxb2MarshallerBeanDefinitionParser
@Override
protected String getBeanClassName(Element element) {
return "org.springframework.oxm.jaxb.Jaxb2Marshaller";
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder beanDefinitionBuilder) {
String contextPath = element.getAttribute("context-path");
if (!StringUtils.hasText(contextPath)) {
// Backwards compatibility with 3.x version of the xsd
contextPath = element.getAttribute("contextPath");
}
if (StringUtils.hasText(contextPath)) {
beanDefinitionBuilder.addPropertyValue("contextPath", contextPath);
}
List<Element> classes = DomUtils.getChildElementsByTagName(element, "class-to-be-bound");
if (!classes.isEmpty()) {
ManagedList<String> classesToBeBound = new ManagedList<String>(classes.size());
for (Element classToBeBound : classes) {
String className = classToBeBound.getAttribute("name");
classesToBeBound.add(className);
}
beanDefinitionBuilder.addPropertyValue("classesToBeBound", classesToBeBound);
}
}
要注意的有趣点是返回"org.springframework.oxm.jaxb.Jaxb2Marshaller" 的getBeanClassName 方法。这就是 Spring 知道要创建哪个 bean 的方式。此外,如果您查看上面的上下文文件,您将看到元素 <oxm:class-to-be-bound>。这是<oxm:jax2b-marshaller> 元素的架构定义的一部分。您也可以在 doParse() 方法中看到它 - getChildElementsByTagName(element, "class-to-be-bound");。
所有这些都是为了确保我们最终得到一个好的Jaxb2marshaller 实例。它与 Spring 中的一切工作方式几乎相同
因此,您可以看到 Spring 在幕后发生了很多事情,希望您能明白为什么需要命名空间。