spring-dubbo启动过程

spring-dubbo启动过程

  1. 首先@EnableDubbo注解将DubboComponentScanRegistrar引入进来

       2. DubboComponentScanRegistrar类会注册一个ServiceAnnotationBeanPostProcessor,这是一个BeanDefinitionRegistry的后置处理器。
       3. 后置处理器对BeanDefinitionRegistry进行后置处理,他会使用scan扫描EnableDubbo注解上标注的包名内的类,扫描到的同时会注册进spring。
    

org.apache.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor#registerServiceBeans

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
private void registerServiceBeans(Set<String> packagesToScan, BeanDefinitionRegistry registry) {

DubboClassPathBeanDefinitionScanner scanner =
new DubboClassPathBeanDefinitionScanner(registry, environment, resourceLoader);

BeanNameGenerator beanNameGenerator = resolveBeanNameGenerator(registry);

scanner.setBeanNameGenerator(beanNameGenerator);
//扫描带有注解的类,同时兼容阿里版本的dubbo
scanner.addIncludeFilter(new AnnotationTypeFilter(Service.class));
scanner.addIncludeFilter(new AnnotationTypeFilter(com.alibaba.dubbo.config.annotation.Service.class));

for (String packageToScan : packagesToScan) {

// 扫描此包名下的类,此方法里扫描到后会直接注册到spring容器里
scanner.scan(packageToScan);

Set<BeanDefinitionHolder> beanDefinitionHolders =
findServiceBeanDefinitionHolders(scanner, packageToScan, registry, beanNameGenerator);

if (!CollectionUtils.isEmpty(beanDefinitionHolders)) {
//将扫描到的dubbo类包装成ServiceBean.class,也注册到spring容器
for (BeanDefinitionHolder beanDefinitionHolder : beanDefinitionHolders) {
registerServiceBean(beanDefinitionHolder, registry, scanner);
}

} else {
if (logger.isWarnEnabled()) {
logger.warn("No Spring Bean annotating Dubbo's @Service was found under package["
+ packageToScan + "]");
}
}
}
}
  1. 上述使用scan扫描到的bean,注册到spring的同时,会再包装成ServiceBean也注册到spring里面

  2. ServiceBean实现了ApplicationListener接口,其会在监听到事件后,将接口暴漏出去

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
    if (!isExported() && !isUnexported()) {
    if (logger.isInfoEnabled()) {
    logger.info("The service ready on spring started. service: " + getInterface());
    }
    //将接口暴漏出去
    export();
    }
    }

注意

​ 因为ServiceBean是ApplicationListener接口,spring初始化ApplicationListener时,会将ServiceBean一同初始化了,此时要求其内部的Dubbo类也要初始化,如果其没有初始化,ServiceBean在执行export时会因为找不到类而报错。

​ 因为Dubbo的export是由spring容器的事件触发的,如果是单容器不会有问题,但是如果容器初始化时创建了子容器,而子容器的事件会发送到父容器里面的,导致父容器还没有初始化完成就export了。


spring-dubbo启动过程
https://www.huangchaoyu.com/3407224340.html
作者
hcy
发布于
2021年2月9日
更新于
2024年8月17日
许可协议