这个服务器仅作为名称空间(避免命名冲突的方法)有用吗?还是可以向 XML 文档中添加哪些元素?
是可以向 XML 文档中添加元素的。
Namespaces 用于标识模式定义中的元素和属性。
当使用 Spring 进行持久化时,通常需要使用
spring-orm
jar、
spring-jdbc
、
spring-tx
等几个 jar 包。一般来说,所有的
spring-xxx
jar 包都附带有它们的模式定义。如上所述,如果要在特定的模式中使用元素,则需要在上下文文件中添加命名空间。
您目前拥有的命名空间只有
beans
和
context
命名空间。如果查看xsds,您将看到允许这些命名空间的所有顶级元素。例如,beans命名空间仅允许
<alias>
、
<bean>
、
<beans>
、
<description>
和
<import>
。而context命名空间则仅支持
<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命名空间,以及
<jdbc:embedded-database>
元素。
这只是一般的猜测。
引用:
“我有这样的疑问:为什么添加一个Spring期望的命名空间(对于任何XML解析器来说都是如此)就能得到该元素?难道不是XSD的工作吗?XSD告诉XML文档中可以包含哪些元素?”
你的误解有点不清楚,但就像基于模式的任何其他XML一样,它需要进行验证。模式就像类定义。类定义是实例允许的合同。
Spring使用您的上下文来创建您定义的所有bean。如果定义不正确,Spring可能无法处理您的xml。这就是为什么我们需要模式 - 遵循应用程序需要您遵循的更高级别指南才能正常工作。
Spring在幕后执行的操作是获取您的xml文件,并使用相应的NamespaceHandler找到所需的解析器。解析器的工作是创建bean定义,使Spring容器可以实例化您的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>
Using the oxm
namespace for the jaxb2-marshaller
, which is define in the spring-oxm-4.0.xsd
in one of the jar packages.
Notice the schemaLocation http://www.springframework.org/schema/oxm/spring-oxm-4.0.xsd
. Spring will use this to determine the handler.
Look in the META-INF
which is included in every spring-xxx.jar
, you will find a spring.schemas
and spring.handlers
file. There you will find
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
this tells spring which schema to validate against, and that the namespace handler to use is the OxmNamespaceHandler
, respectively.
If we look at the OxmNamespaceHandler
class you will find
registerBeanDefinitionParser("jaxb2-marshaller",
new Jaxb2MarshallerBeanDefinitionParser());
What is happening is now the namespace handler is directing us to the right parser.
Now look at the 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)) {
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);
}
}
The interesting point to note is getBeanClassName
method which return "org.springframework.oxm.jaxb.Jaxb2Marshaller"
. This is how Spring knows which bean to create. Also if you look at the context file above, you will see the element <oxm:class-to-be-bound>
. That is part of the schema definition for the <oxm:jax2b-marshaller>
element. You can also see it in the doParse()
method - getChildElementsByTagName(element, "class-to-be-bound");
.
所有这些都是为了确保我们最终获得一个好的
Jaxb2marshaller
实例。在Spring中,几乎所有东西的工作方式都大致相同。
因此,您可以看到Spring背后有很多事情正在发生,希望您能理解为什么需要命名空间。