天天看點

在Spring的XML檔案中通過命名空間配置的标簽是怎麼解析的?

其實在spring中把解析标簽的類都都放在了相應的META-INF目錄下的spring.handlers的檔案中,比如mvc的命名空間解析設定在spring-webmvc-3.2.5.RELEASE.jar包下META-INF/spring.handlers的檔案中。

在Spring的XML檔案中通過命名空間配置的标簽是怎麼解析的?

這說明處理MVC這個命名空間的配置需要使用MvcNamespaceHandler(在其内部将mvc:annotation-driven交給 AnnotationDrivenBeanDefinitionParser ),源碼如下:

在Spring的XML檔案中通過命名空間配置的标簽是怎麼解析的?

解析配置的接口是org.springframework.beans.factory.xml.NamespaceHandler,它的實作結構如下:

在Spring的XML檔案中通過命名空間配置的标簽是怎麼解析的?

在這個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。