本篇我们一起来看一下基于Extensible XML authoring 扩展Spring XML元素。这里我总结了以下内容:
* Spring XML 扩展
* 编写 XML Schema 文件:定义 XML 结构
* 自定义 NamespaceHandler 实现:命名空间绑定
* 自定义 BeanDefinitionParser 实现:XML 元素与 BeanDefinition 解析
* 注册 XML 扩展:命名空间与 XML Schema 映射
接下来我们就通过实际案例的方式一起实践一下。代码如下:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://time.eleven.org/schema/users"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://time.eleven.org/schema/users">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
<!-- 定义 User 类型(复杂类型) -->
<xsd:complexType name="User">
<xsd:attribute name="id" type="xsd:long" use="required"/>
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="city" type="City"/>
</xsd:complexType>
<!-- 定义 City 类型(简单类型,枚举) -->
<xsd:simpleType name="City">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="BEIJING"/>
<xsd:enumeration value="HANGZHOU"/>
<xsd:enumeration value="SHANGHAI"/>
</xsd:restriction>
</xsd:simpleType>
<!-- 定义 user 元素 -->
<xsd:element name="user" type="User"/>
</xsd:schema>
## 定义 namespace 与 NamespaceHandler 的映射
http\://time.eleven.org/schema/users=org.eleven.thinking.in.spring.configuration.metadata.UsersNamespaceHandler
http\://time.eleven.org/schema/users.xsd = org/eleven/thinking/in/spring/configuration/metadata/users.xsd
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.eleven.thinking.in.spring.configuration.metadata;
import org.springframework.beans.factory.xml.NamespaceHandler;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
/**
* "users.xsd" {@link NamespaceHandler} 实现
*
* @author <a href="mailto:[email protected]">eleven</a>
* @since
*/
public class UsersNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
// 将 "user" 元素注册对应的 BeanDefinitionParser 实现
registerBeanDefinitionParser("user", new UserBeanDefinitionParser());
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.eleven.thinking.in.spring.configuration.metadata;
import org.eleven.thinking.in.spring.ioc.overview.domain.User;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* "user" 元素的 {@link BeanDefinitionParser} 实现
*
* @author <a href="mailto:[email protected]">eleven</a>
* @since
*/
public class UserBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
@Override
protected Class<?> getBeanClass(Element element) {
return User.class;
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
setPropertyValue("id", element, builder);
setPropertyValue("name", element, builder);
setPropertyValue("city", element, builder);
}
private void setPropertyValue(String attributeName, Element element, BeanDefinitionBuilder builder) {
String attributeValue = element.getAttribute(attributeName);
if (StringUtils.hasText(attributeValue)) {
builder.addPropertyValue(attributeName, attributeValue); // -> <property name="" value=""/>
}
}
}