欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

spring自定义标签实现 之一对多实体解析

程序员文章站 2022-05-01 18:09:12
...

       通过上一篇博客(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