最全最简单的dubbo教程-dubbo标签解析原理《十五》
本文主要分析 XML 配置的实现原理和源码。
dubbo解析xml的配置的方式主要是通过spring提供的解析工具解析,dubbo自定义DubboNamespaceHandler 类这个类继承spring提供的NamespaceHandlerSupport类,如图:
这个类在spring启动的时候会调用init方法为每一种标签对应一个特定的标签解析器DubboBeanDefinitionParser ,这个类的代码大概如下:
public class DubboBeanDefinitionParser implements BeanDefinitionParser {
public BeanDefinition parse(Element element, ParserContext parserContext) {
return parse(element, parserContext, beanClass, required);
}
@SuppressWarnings("unchecked")
private static BeanDefinition parse(Element element,ParserContext parserContext,Class<?> beanClass,boolean required) {
RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClass(beanClass);
beanDefinition.setLazyInit(false);
//......省略
if (ProtocolConfig.class.equals(beanClass)) {
for (String name : parserContext.getRegistry().getBeanDefinitionNames()) {
BeanDefinition definition = parserContext.getRegistry().getBeanDefinition(name);
PropertyValue property = definition.getPropertyValues().getPropertyValue("protocol");
if (property != null) {
Object value = property.getValue();
if (value instanceof ProtocolConfig && id.equals(((ProtocolConfig) value).getName())) {
definition.getPropertyValues().addPropertyValue("protocol", new RuntimeBeanReference(id));
}
}
}
} else if (ServiceBean.class.equals(beanClass)) {
String className = element.getAttribute("class");
if(className != null && className.length() > 0) {
RootBeanDefinition classDefinition = new RootBeanDefinition();
classDefinition.setBeanClass(ReflectUtils.forName(className));
classDefinition.setLazyInit(false);
parseProperties(element.getChildNodes(), classDefinition);
beanDefinition.getPropertyValues().addPropertyValue("ref", new BeanDefinitionHolder(classDefinition, id + "Impl"));
}
} else if (ProviderConfig.class.equals(beanClass)) {
parseNested(element, parserContext, ServiceBean.class, true, "service", "provider", id, beanDefinition);
} else if (ConsumerConfig.class.equals(beanClass)) {
parseNested(element, parserContext, ReferenceBean.class, false, "reference", "consumer", id, beanDefinition);
}
//......省略
return beanDefinition;
}
}
通过上面的代码可以看出DubboBeanDefinitionParser通过实现BeanDefinitionParser方法,用来解析XML中对应的标签的值,并将这些值设置到对应的属性中。
可能有小伙伴有疑问了,dubbo怎么知道调用DubboNamespaceHandler 这个handler,这其实这是利用了spring的加载机制,dubbo编写了一个spring.handlers如图:
同时dubbo编写了spring.schemas文件用来对应dubbo.xsd文件如图:
而dubbo.xsd文件正是用来自定义dubbo特有标签格式的文件。最后通过引入他们所对应的两个映射文件名字如图:
这样在web启动的时候会自动通过这两个映射文件名字找到对应的handler与.xsd约束文件。
参考博客:
https://blog.****.net/m0_38043362/article/details/78329188
https://www.cnblogs.com/cyfonly/p/9091857.html