在Spring的XML文件中通过命名空间配置的标签是怎么解析的?

其实在spring中把解析标签的类都都放在了相应的META-INF目录下的spring.handlers的文件中,比如mvc的命名空间解析设置在spring-webmvc-3.2.5.RELEASE.jar包下META-INF/spring.handlers的文件中。


这说明处理MVC这个命名空间的配置需要使用MvcNamespaceHandler(在其内部将mvc:annotation-driven交给 AnnotationDrivenBeanDefinitionParser ),源码如下:


解析配置的接口是org.springframework.beans.factory.xml.NamespaceHandler,它的实现结构如下:


在这个interface里定义了三个方法:init,parse,和decorate。init方法用来初始化自己;parse用来将配置的标签转化成spring所需要的BeanDefinition;decorate是装饰的意思,这个方法的作用是对所在的BeanDefinition进行一些修改,用的比较少。
public interface NamespaceHandler {
    void init();
    BeanDefinition parse(Element element, ParserContext parserContext);
    BeanDefinitionHolder decorate(Node source, BeanDefinitionHolder definition, ParserContext parserContext);
}
NamespaceHandler的主要实现类有三个,NamespaceHandlerSupport,SimpleConstructorNamespaceHandler,SimplePropertyNamespaceHandler。NamespaceHandlerSupport就是这个接口的默认实现,一般的XXXNamespaceHandler都实现自这个类,这里只简单的介绍一下NamespaceHandlerSupport。
从源码中可以看出在NamespaceHandlerSupport中并没有做具体的解析工作,而是定义了三个解析器,MvcNamespaceHandler将解析的标签注册到NamespaceHandlerSupport上,通过委托给该元素注册的bean来解析所提供的元素。
public abstract class NamespaceHandlerSupport implements NamespaceHandler {
    private final Map<String, BeanDefinitionParser> parsers =
            new HashMap<String, BeanDefinitionParser>();
    private final Map<String, BeanDefinitionDecorator> decorators =
            new HashMap<String, BeanDefinitionDecorator>();
    private final Map<String, BeanDefinitionDecorator> attributeDecorators =
            new HashMap<String, BeanDefinitionDecorator>();
    @Override
    public BeanDefinition parse(Element element, ParserContext parserContext) {
        return findParserForElement(element, parserContext).parse(element, parserContext);
    }
    private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) {
        String localName = parserContext.getDelegate().getLocalName(element);
        BeanDefinitionParser parser = this.parsers.get(localName);
        if (parser == null) {
            parserContext.getReaderContext().fatal(
                    "Cannot locate BeanDefinitionParser for element [" + localName + "]", element);
        }
        return parser;
    }
     @Override
    public BeanDefinitionHolder decorate(
            Node node, BeanDefinitionHolder definition, ParserContext parserContext) {
        return findDecoratorForNode(node, parserContext).decorate(node, definition, parserContext);
    }
    private BeanDefinitionDecorator findDecoratorForNode(Node node, ParserContext parserContext) {
        BeanDefinitionDecorator decorator = null;
        String localName = parserContext.getDelegate().getLocalName(node);
        if (node instanceof Element) {
            decorator = this.decorators.get(localName);
        }
        else if (node instanceof Attr) {
            decorator = this.attributeDecorators.get(localName);
        }
        else {
            parserContext.getReaderContext().fatal(
                    "Cannot decorate based on Nodes of type [" + node.getClass().getName() + "]", node);
        }
        if (decorator == null) {
            parserContext.getReaderContext().fatal("Cannot locate BeanDefinitionDecorator for " +
                    (node instanceof Element ? "element" : "attribute") + " [" + localName + "]", node);
        }
        return decorator;
    }
    protected final void registerBeanDefinitionParser(String elementName, BeanDefinitionParser parser) {
        this.parsers.put(elementName, parser);
    }
    protected final void registerBeanDefinitionDecorator(String elementName, BeanDefinitionDecorator dec) {
        this.decorators.put(elementName, dec);
    }
    protected final void registerBeanDefinitionDecoratorForAttribute(String attrName, BeanDefinitionDecorator dec) {
        this.attributeDecorators.put(attrName, dec);
    }
}

====================================================
public class MvcNamespaceHandler extends NamespaceHandlerSupport {
    public void init() {
        registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
        registerBeanDefinitionParser("default-servlet-handler", new DefaultServletHandlerBeanDefinitionParser());
        registerBeanDefinitionParser("interceptors", new InterceptorsBeanDefinitionParser());
        registerBeanDefinitionParser("resources", new ResourcesBeanDefinitionParser());
        registerBeanDefinitionParser("view-controller", new ViewControllerBeanDefinitionParser());
    }
}
从这里我们可以看到解析MVC命名空间的所有解析器,其中解析annotation-driven的就是AnnotationDrivenBeanDefinitionParser。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值