通过上一篇博客(http://mozhenghua.iteye.com/blog/1830842),我们了解到了如何通过spring来解析如下,只有一个子标签(一对一实体关系)的需求
<tsearcher:parent id="testparent"> <tsearcher:child name="alex" age="12"/> </tsearcher:parent>
那么如果子标签如果有n个(上不封顶)的话(一对多实体关系)有应该如何解析呢?标签如下:
<tsearcher:parent id="testparent"> <tsearcher:child name="alex" age="12"/> <tsearcher:child name="joe" age="11"/> <tsearcher:child name="kid" age="13"/> </tsearcher:parent>
首先,创建Parent和Child类,给标签映射时使用。
public class Child {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Child() {
super();
}
}
public class Parent {
private Map<String,Child> child;
public Map<String, Child> getChild() {
return child;
}
public void setChild(Map<String, Child> child) {
this.child = child;
}
}
Parent中的属性是Map<String,Child>类型的,key是Child的name,value就是Child类型。
以下就是解析Parent标签的解析器代码:
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.config.TypedStringValue;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public class ParentParser extends AbstractSimpleBeanDefinitionParser {
protected void doParse(Element element, ParserContext parserContext,
BeanDefinitionBuilder builder) {
try {
builder.addPropertyValue("child", parseMapElement(element,
parserContext, builder));
} catch (Exception e) {
parserContext.getReaderContext()
.error(
"class " + Parent.class.getName()
+ " can not be create", element, e);
}
}
@SuppressWarnings("all")
public Map parseMapElement(Element mapEle,
ParserContext parserContext, BeanDefinitionBuilder builder) {
List entryEles = DomUtils.getChildElementsByTagName(mapEle, "child");
// 关键是以下这个ManagedMap类型,充当着一个map类型的beandefinition类型的说明对象
ManagedMap map = new ManagedMap(entryEles.size());
map.setMergeEnabled(true);
map.setSource(parserContext.getReaderContext().extractSource(mapEle));
for (Iterator it = entryEles.iterator(); it.hasNext();) {
Element entryEle = (Element) it.next();
String name = entryEle.getAttribute("name");
map.put(key, parserContext.getDelegate().parseCustomElement(
entryEle, builder.getRawBeanDefinition()));
}
return map;
}
@Override
protected Class<Parent> getBeanClass(Element element) {
return Parent.class;
}
}
以下就是解析Child的解析器:
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;
public class ChildParser extends AbstractSimpleBeanDefinitionParser {
@Override
protected void doParse(Element element, ParserContext parserContext,
BeanDefinitionBuilder builder) {
super.doParse(element, parserContext, builder);
builder.addPropertyValue("name", element.getAttribute("name"));
builder.addPropertyValue("age", Integer.parseInt(element
.getAttribute("age")));
}
@Override
protected Class<Child> getBeanClass(Element element) {
return Child.class;
}
}
以上只给出parent和client类的相关代码,如果要了解如何将这些类是怎么配置的,请查阅上一篇博客(http://mozhenghua.iteye.com/blog/1830842)