dubbo · 2025-01-07 0

dubbo 服务注册

一、注册 DubboConfigConfigurationRegistrar 和 DubboComponentScanRegistrar

@EnableDubbo
// EnableDubbo.java
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@EnableDubboConfig
@DubboComponentScan
public @interface EnableDubbo
// EnableDubboConfig.java
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Import(DubboConfigConfigurationRegistrar.class)
public @interface EnableDubboConfig
// DubboComponentScan.java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(DubboComponentScanRegistrar.class)
public @interface DubboComponentScan 

2.DubboConfigConfigurationRegistrar

二、DubboConfigConfigurationRegistrar

registerContextBeans() 方法,注册 bean:
beanName: org.apache.dubbo.config.spring.context.DubboSpringInitContext bean: DubboSpringInitContext
beanName: org.apache.dubbo.rpc.model.ApplicationModel bean: ApplicationModel
beanName: org.apache.dubbo.rpc.model.ModuleModel bean: ModuleModel
beanName: dubboServicePackagesHolder bean: ServicePackagesHolder
beanName: dubboReferenceBeanManager bean: ReferenceBeanManager
beanName: referenceAnnotationBeanPostProcessor bean: ReferenceAnnotationBeanPostProcessor postProcessBeanFactory() 方法
beanName: dubboConfigAliasPostProcessor bean: DubboConfigAliasPostProcessor
beanName: org.apache.dubbo.config.spring.context.DubboDeployApplicationListener bean: DubboDeployApplicationListener setApplicationContext() 方法
beanName: org.apache.dubbo.config.spring.context.DubboConfigApplicationListener bean: DubboConfigApplicationListener onApplicationEvent() 方法
beabName: dubboConfigDefaultPropertyValueBeanPostProcessor bean: DubboConfigDefaultPropertyValueBeanPostProcessor processBeforeInitialization() 方法
beanName: dubboConfigBeanInitializer bean: DubboConfigBeanInitializer afterPropertiesSet() 方法
beanName: dubboInfraBeanRegisterPostProcessor bean: DubboInfraBeanRegisterPostProcessor postProcessBeanFactory() 方法

// DubboConfigConfigurationRegistrar.java
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    DubboSpringInitializer.initialize(registry);
}
// DubboSpringInitializer.java
public static void initialize(BeanDefinitionRegistry registry) {
    if (contextMap.putIfAbsent(registry, new DubboSpringInitContext()) != null) {
        return;
    }

    DubboSpringInitContext context = contextMap.get(registry);

    // find beanFactory
    ConfigurableListableBeanFactory beanFactory = findBeanFactory(registry);

    // init dubbo context
    initContext(context, registry, beanFactory);
}

private static void initContext(DubboSpringInitContext context, BeanDefinitionRegistry registry,
                                ConfigurableListableBeanFactory beanFactory) {
    context.setRegistry(registry);
    context.setBeanFactory(beanFactory);

    customize(context);

    ModuleModel moduleModel = context.getModuleModel();
    if (moduleModel == null) {
        ApplicationModel applicationModel;
        if (findContextForApplication(ApplicationModel.defaultModel()) == null) {
            applicationModel = ApplicationModel.defaultModel();
        } else {
            applicationModel = FrameworkModel.defaultModel().newApplication();
        }

        moduleModel = applicationModel.getDefaultModule();
        context.setModuleModel(moduleModel);
    }

    registerContextBeans(beanFactory, context);

    context.markAsBound();
    moduleModel.setLifeCycleManagedExternally(true);

    DubboBeanUtils.registerCommonBeans(registry);
}

private static void registerContextBeans(ConfigurableListableBeanFactory beanFactory, DubboSpringInitContext context) {
    registerSingleton(beanFactory, context);
    registerSingleton(beanFactory, context.getApplicationModel());
    registerSingleton(beanFactory, context.getModuleModel());
}

private static void registerSingleton(ConfigurableListableBeanFactory beanFactory, Object bean) {
    beanFactory.registerSingleton(bean.getClass().getName(), bean);
}
// DubboBeanUtils.java
static void registerCommonBeans(BeanDefinitionRegistry registry) {

    registerInfrastructureBean(registry, ServicePackagesHolder.BEAN_NAME, ServicePackagesHolder.class);

    registerInfrastructureBean(registry, ReferenceBeanManager.BEAN_NAME, ReferenceBeanManager.class);

    // Since 2.5.7 Register @Reference Annotation Bean Processor as an infrastructure Bean
    registerInfrastructureBean(registry, ReferenceAnnotationBeanPostProcessor.BEAN_NAME,
        ReferenceAnnotationBeanPostProcessor.class);

    // TODO Whether DubboConfigAliasPostProcessor can be removed ?
    // Since 2.7.4 [Feature] https://github.com/apache/dubbo/issues/5093
    registerInfrastructureBean(registry, DubboConfigAliasPostProcessor.BEAN_NAME,
        DubboConfigAliasPostProcessor.class);

    // register ApplicationListeners
    registerInfrastructureBean(registry, DubboDeployApplicationListener.class.getName(), DubboDeployApplicationListener.class);
    registerInfrastructureBean(registry, DubboConfigApplicationListener.class.getName(), DubboConfigApplicationListener.class);

    // Since 2.7.6 Register DubboConfigDefaultPropertyValueBeanPostProcessor as an infrastructure Bean
    registerInfrastructureBean(registry, DubboConfigDefaultPropertyValueBeanPostProcessor.BEAN_NAME,
        DubboConfigDefaultPropertyValueBeanPostProcessor.class);

    // Dubbo config initializer
    registerInfrastructureBean(registry, DubboConfigBeanInitializer.BEAN_NAME, DubboConfigBeanInitializer.class);

    // register infra bean if not exists later
    registerInfrastructureBean(registry, DubboInfraBeanRegisterPostProcessor.BEAN_NAME, DubboInfraBeanRegisterPostProcessor.class);
}

三、DubboComponentScanRegistrar

依次从 @DubboComponentScan、@EnableDubbo、启动类,获得扫描的包路径
注册 bean 为 ServiceAnnotationPostProcessor

// DubboComponentScanRegistrar.java
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

    // initialize dubbo beans
    DubboSpringInitializer.initialize(registry);

    Set<String> packagesToScan = getPackagesToScan(importingClassMetadata);

    registerServiceAnnotationPostProcessor(packagesToScan, registry);
}

private Set<String> getPackagesToScan(AnnotationMetadata metadata) {
    // get from @DubboComponentScan 
    Set<String> packagesToScan = getPackagesToScan0(metadata, DubboComponentScan.class, "basePackages", "basePackageClasses");

    // get from @EnableDubbo, compatible with spring 3.x
    if (packagesToScan.isEmpty()) {
        packagesToScan = getPackagesToScan0(metadata, EnableDubbo.class, "scanBasePackages", "scanBasePackageClasses");
    }

    if (packagesToScan.isEmpty()) {
        return Collections.singleton(ClassUtils.getPackageName(metadata.getClassName()));
    }
    return packagesToScan;
}

private void registerServiceAnnotationPostProcessor(Set<String> packagesToScan, BeanDefinitionRegistry registry) {
    BeanDefinitionBuilder builder = rootBeanDefinition(ServiceAnnotationPostProcessor.class);
    builder.addConstructorArgValue(packagesToScan);
    builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
    BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, registry);

}

四、ServiceAnnotationPostProcessor

扫描注解
@org.apache.dubbo.config.annotation.DubboService
@org.apache.dubbo.config.annotation.Service
@com.alibaba.dubbo.config.annotation.Service.class

注册
beanName: ServiceBean:com.example.common.server.Server1::

// ServiceAnnotationPostProcessor.java
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    this.registry = registry;
    scanServiceBeans(resolvedPackagesToScan, registry);
}

private void scanServiceBeans(Set<String> packagesToScan, BeanDefinitionRegistry registry) {
    scanned = true;
    ...
    DubboClassPathBeanDefinitionScanner scanner =
            new DubboClassPathBeanDefinitionScanner(registry, environment, resourceLoader);

    BeanNameGenerator beanNameGenerator = resolveBeanNameGenerator(registry);
    scanner.setBeanNameGenerator(beanNameGenerator);
    for (Class<? extends Annotation> annotationType : serviceAnnotationTypes) {
        scanner.addIncludeFilter(new AnnotationTypeFilter(annotationType));
    }

    ScanExcludeFilter scanExcludeFilter = new ScanExcludeFilter();
    scanner.addExcludeFilter(scanExcludeFilter);

    for (String packageToScan : packagesToScan) {
        ...
        scanner.scan(packageToScan);

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

        if (!CollectionUtils.isEmpty(beanDefinitionHolders)) {
            ...
            for (BeanDefinitionHolder beanDefinitionHolder : beanDefinitionHolders) {
                processScannedBeanDefinition(beanDefinitionHolder);
                servicePackagesHolder.addScannedClass(beanDefinitionHolder.getBeanDefinition().getBeanClassName());
            }
        } else {
            ...
        }

        servicePackagesHolder.addScannedPackage(packageToScan);
    }
}

private void processScannedBeanDefinition(BeanDefinitionHolder beanDefinitionHolder) {
    Class<?> beanClass = resolveClass(beanDefinitionHolder);
    Annotation service = findServiceAnnotation(beanClass);

    // The attributes of @Service annotation
    Map<String, Object> serviceAnnotationAttributes = AnnotationUtils.getAttributes(service, true);

    String serviceInterface = resolveInterfaceName(serviceAnnotationAttributes, beanClass);

    String annotatedServiceBeanName = beanDefinitionHolder.getBeanName();

    // ServiceBean Bean name
    String beanName = generateServiceBeanName(serviceAnnotationAttributes, serviceInterface);

    AbstractBeanDefinition serviceBeanDefinition =
            buildServiceBeanDefinition(serviceAnnotationAttributes, serviceInterface, annotatedServiceBeanName);

    registerServiceBeanDefinition(beanName, serviceBeanDefinition, serviceInterface);

}