代码网 logo
AI

dubbo分析

唐某2020-11-23 11:35:4260

dubbo 与spring 整合提供全spring 的配置,下面分析。这一过程。

通过spring 的obtainBeanFactory 方法的解析,了解到在 doLoadBeanDefinition 的时候,在遇到非基础明明空间下的 元素的时候,需要先找到相应的明明空间,这一过程大概是 spring 命名解析器通过伪 SPI 获取到所有的命名空间处理器,并将其缓存在 map中,根据命名空间名称,获取到 命名空间Handler,然后调用其 init 方法,这个方法会注册与该命名空间相关的所有的 BeanDefinitionPhaser。然后遍历所有phaser 通过sport 方法,获取该元素的解析器,对该元素进行处理。

知道了这些,我们可以直接在 dubbo 的 com.alibaba.dubbo.config.spring.schema 包下面 找到这个 dubboNameSpaceHandler。

java 复制代码
public class DubboNamespaceHandler extends NamespaceHandlerSupport {

    static {
        Version.checkDuplicate(DubboNamespaceHandler.class);
    }

    @Override
    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());
    }

}

可以看到,所有的元素解析器,在这个类下进行注册。

在配置 xml的时候,首先都是把 application 元素放在上方。那么就把它当做切入点分析。元素解析器都要在 phaser 方法里面进行处理逻辑。但是dubbo 把除了处理注解的所有逻辑都放到一起了。这么做的好处就是,这些元素谁在前面都会执行 dubbo 的初始化逻辑。。。

parse 方法将近 200 行,分段分析。

java 复制代码
RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClass(beanClass);
beanDefinition.setLazyInit(false);
String id = element.getAttribute("id");
if ((id == null || id.length() == 0) && required) {
    String generatedBeanName = element.getAttribute("name");
    if (generatedBeanName == null || generatedBeanName.length() == 0) {
        if (ProtocolConfig.class.equals(beanClass)) {
            generatedBeanName = "dubbo";
        } else {
            generatedBeanName = element.getAttribute("interface");
        }
    }
    if (generatedBeanName == null || generatedBeanName.length() == 0) {
        generatedBeanName = beanClass.getName();
    }
    id = generatedBeanName;
    int counter = 2;
    while (parserContext.getRegistry().containsBeanDefinition(id)) {
        id = generatedBeanName + (counter++);
    }
}

开头这一部分创建了 RootBeanDefinition。然后获取元素的 name 属性,为beanDefinition 的名称赋值。如果已经注册了该名称的beanDefinition,则通过 counter 解决重名问题。

java 复制代码
if (id != null && id.length() > 0) {
    if (parserContext.getRegistry().containsBeanDefinition(id)) {
        throw new Ille

广告