设为首页 加入收藏

TOP

【Dubbo源码阅读系列】之 Dubbo XML 配置加载(四)
2019-09-17 17:00:34 】 浏览:117
Tags:Dubbo 源码 阅读 系列 XML 配置 加载
ame 作为 className 并调用 BeanUtils.instantiateClass() 方法初始化一个
NamespaceHandler 实例。初始化后,调用其 init() 方法。这个 init() 方法比较重要,我们接着往下看。

DubboNamespaceHandler
public void init() {
    registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
    registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
    registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
    registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
    registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
    registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
    registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
    registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
    registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
    registerBeanDefinitionParser("annotation", new AnnotationBeanDefinitionParser());
}

NamespaceHandlerSupport
private final Map<String, BeanDefinitionParser> parsers = new HashMap();
protected final void registerBeanDefinitionParser(String elementName, BeanDefinitionParser parser) {
    this.parsers.put(elementName, parser);
}

DubboNamespaceHandler 类中的 init() 方法干的事情特别简单,就是新建 DubboBeanDefinitionParser 对象并将其放入 NamespaceHandlerSupport 类的 parsers 集合中。我们再回顾一下 parseCustomElement() 方法。

BeanDefinitionParserDelegate.java
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
    // 省略...
    return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
    // 省略...
}

这里会调用 NamespaceHandlerSupport 类的 parse() 方法。我们继续跟踪一下。

public BeanDefinition parse(Element element, ParserContext parserContext) {
    return this.findParserForElement(element, parserContext).parse(element, parserContext);
}
private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) {
    String localName = parserContext.getDelegate().getLocalName(element);
    BeanDefinitionParser parser = (BeanDefinitionParser)this.parsers.get(localName);
    if (parser == null) {
        parserContext.getReaderContext().fatal("Cannot locate BeanDefinitionParser for element [" + localName + "]", element);
    }

    return parser;
}

看到这里大家有没有一丝豁然开朗的感觉?之前的 resolve() 方法实际上就是根据当前 element 的 namespaceURI 获取对应的 NamespaceHandler 对象(对于 Dubbo 来说是 DubboNamespaceHandler),
然后调用 DubboNamespaceHandler 中的 init() 方法新建 DubboBeanDefinitionParser 对象并注册到 NamespaceHandlerSupport 类的 parsers 集合中。
然后 parser 方法会根据当前 element 对象从 parsers 集合中获取合适的 BeanDefinitionParser 对象。对于 Dubbo 元素来说,实际上最后执行的是 DubboBeanDefinitionParser 的 parse() 方法。

DubboBeanDefinitionParser.parse()

最后我们再来看看 Dubbo 解析 XML 文件的详细实现吧。如果对具体实现没有兴趣可直接直接跳过。

private static BeanDefinition parse(Element element, ParserContext parserContext, Class<?> beanClass, boolean required) {
        RootBeanDefinition beanDefinition = new RootBeanDefi
首页 上一页 1 2 3 4 5 6 7 下一页 尾页 4/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇小白Salesforce--对object中数据.. 下一篇详解Java中对象的软、弱和虚引用..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目