spring-dubbo启动过程
- 首先@EnableDubbo注解将DubboComponentScanRegistrar引入进来
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 + "]");
}
}
}
}
-
上述使用scan扫描到的bean,注册到spring的同时,会再包装成ServiceBean也注册到spring里面
-
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了。
转载请注明出处:https://www.huangchaoyu.com/2021/02/09/spring-dubbo启动过程/