dubbo · 2025-01-07 0

dubbo 服务注册

一、示例

1.dubbo-common

<groupId>org.example</groupId>
<artifactId>dubbo-common</artifactId>
<version>1.0.0</version>
public interface Server1 {

    String method1();

    String method2();
}

2.spring-boot-dubbo-provider1

pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.2</version>
    <relativePath/>
</parent>

<groupId>org.example</groupId>
<artifactId>spring-boot-dubbo-provider1</artifactId>
<version>1.0.0</version>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-registry-zookeeper</artifactId>
        <version>3.2.0</version>
    </dependency>

    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>3.2.0</version>
    </dependency>

    <dependency>
        <groupId>org.example</groupId>
        <artifactId>dubbo-common</artifactId>
        <version>1.0.0</version>
    </dependency>
</dependencies>

application.yml

# 服务端口
server:
  port: 18001

# dubbo 配置
dubbo:
  # 应用
  application:
    name: provider1
    qos-enable: false
    # register-mode: all # 接口级+应用级均注册,接口级注册与应用级注册并存(/dubbo && /service),应用升级到 dubbo 3.0 后,服务端自动开启接口级 + 应用级双注册功能,默认无需开发者修改任何配置
    register-mode: interface # 只接口级注册(/dubbo)
    # register-mode: instance # 只应用级注册(/service)
  # 注册中心地址
  registry:
    address: zookeeper://127.0.0.1:12181
    # group: group_1
    timeout: 300000 # 连接超时时间,默认 30s
    session: 600000 # 会话超时时间,默认 60s
  provider:
    timeout: 300000
  # 协议
  protocol:
    name: dubbo
    port: 21881 # 默认 20880
@DubboService(version = "1.0", group = "dev_group")
public class Server1Impl implements Server1 {

    @Override
    public String method1() {
        return "this is provider1 Service1#method1()";
    }

    @Override
    public String method2() {
        return "this is provider1 Service1#method2()";
    }
}
@RestController
public class IndexController {

    @DubboReference(version = "1.0", group = "dev_group")
    private Server1 server1;

    @RequestMapping("/")
    public String index(){
        String result = server1.method1();
        return result;
    }
}
@SpringBootApplication
@EnableDubbo
public class Provider1Boot {
    /*
        @DubboService 会生成两个 Bean
          1)
            beanName: server1Impl
            bean: Server1Impl
            beanFactory.getBean("server1Impl") 和 beanFactory.getBean(Server1.class) 可找到此 Bean
          2)
            ServiceBean:com.example.common.server.Server1:1.0:dev_group
            bean: ServiceBean
            beanFactory.getBean("com.example.common.server.Server1:1.0:dev_group") 和
     */
    public static void main(String[] args) {
        SpringApplication.run(Provider1Boot.class, args);
    }
}

3.spring-boot-dubbo-consumer1

pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.2</version>
    <relativePath/>
</parent>

<groupId>org.example</groupId>
<artifactId>spring-boot-dubbo-consumer1</artifactId>
<version>1.0.0</version>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-registry-zookeeper</artifactId>
        <version>3.2.0</version>
    </dependency>

    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>3.2.0</version>
    </dependency>

    <dependency>
        <groupId>org.example</groupId>
        <artifactId>dubbo-common</artifactId>
        <version>1.0.0</version>
    </dependency>
</dependencies>

application.yml

# 服务端口
server:
  port: 19001

# dubbo 配置
dubbo:
  # 应用
  application:
    name: consumer1
    qos-enable: false
    # register-mode: all # 接口级+应用级均注册,接口级注册与应用级注册并存(/dubbo && /service),应用升级到 dubbo 3.0 后,服务端自动开启接口级 + 应用级双注册功能,默认无需开发者修改任何配置
    register-mode: interface # 只接口级注册(/dubbo)
    # register-mode: instance # 只应用级注册(/service)
  # 注册中心地址
  registry:
    address: zookeeper://127.0.0.1:12181
    # group: group_1
    timeout: 300000 # 连接超时时间,默认 30s
    session: 600000 # 会话超时时间,默认 60s
  consumer:
    timeout: 300000
    retries: 0
  # 协议
  protocol:
    name: dubbo
    port: 21883
@RestController
public class IndexController {

    @DubboReference(version = "1.0", group = "dev_group")
    private Server1 server1;

    @RequestMapping("/")
    public String index(){
        String result = server1.method1();
        return result;
    }
}
@SpringBootApplication
public class Consumer1Boot {
    /*
        @DubboReference 会生成一个 Bean
            1. 扫描到 @DubboReference
                beanName: server1
                bean: $Proxy62
                beanFactory.getBean("server1") 和 beanFactory.getBean(Server1.class) 可找到此 Bean
     */
    public static void main(String[] args) {
        SpringApplication.run(Consumer1Boot.class, args);
    }
}

二、原理

1.注册 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

registerContextBeans() 方法,注册 bean:

1.beanName: org.apache.dubbo.config.spring.context.DubboSpringInitContext
   bean: DubboSpringInitContext
2.beanName: org.apache.dubbo.rpc.model.ApplicationModel
   bean: ApplicationModel
3.beanName: org.apache.dubbo.rpc.model.ModuleModel
   bean: ModuleModel
4.beanName: dubboServicePackagesHolder
   bean: ServicePackagesHolder
5.beanName: dubboReferenceBeanManager
   bean: ReferenceBeanManager
6.beanName: referenceAnnotationBeanPostProcessor
   bean: ReferenceAnnotationBeanPostProcessor
   有 postProcessBeanFactory() 方法
7.beanName: dubboConfigAliasPostProcessor
   bean: DubboConfigAliasPostProcessor
8.beanName: org.apache.dubbo.config.spring.context.DubboDeployApplicationListener
   bean: DubboDeployApplicationListener
   有 setApplicationContext() 方法
9.beanName: org.apache.dubbo.config.spring.context.DubboConfigApplicationListener
   bean: DubboConfigApplicationListener
   有 onApplicationEvent() 方法
10.beabName: dubboConfigDefaultPropertyValueBeanPostProcessor
   bean: DubboConfigDefaultPropertyValueBeanPostProcessor
   有 processBeforeInitialization() 方法
11.beanName: dubboConfigBeanInitializer
   bean: DubboConfigBeanInitializer
   有 afterPropertiesSet() 方法
12.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);
}

2.DubboComponentScanRegistrar

registerServiceAnnotationPostProcessor() 方法,依次从 @DubboComponentScan、@EnableDubbo、启动类,获得扫描的包路径
注册 bean:

1.beanName: org.apache.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationPostProcessor#0
  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);

}

3.ServiceAnnotationPostProcessor

扫描注解

1.@org.apache.dubbo.config.annotation.DubboService
2.@org.apache.dubbo.config.annotation.Service
3.@com.alibaba.dubbo.config.annotation.Service.class

doScan(basePackages) 方法,会扫描注解 @org.apache.dubbo.config.annotation.DubboService、@org.apache.dubbo.config.annotation.Service、@com.alibaba.dubbo.config.annotation.Service
把符合的 bean,注册 BeanDefinition 到 spring 容器

beanName: server1Impl
beanDefinition: ScannedGenericBeanDefinition,其中 beanClass 是 com.example.provider.server.Server1Impl

processScannedBeanDefinition(beanDefinitionHolder) 方法,注册 BeanDefinition 到 spring 容器

beaName: ServiceBean:com.example.common.server.Server1:1.0:dev_group
beanDefinition: RootBeanDefinition,其中 beanClass 是 ServiceBean
// 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);

}

private AbstractBeanDefinition buildServiceBeanDefinition(Map<String, Object> serviceAnnotationAttributes,
                                                          String serviceInterface,
                                                          String refServiceBeanName) {
    BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ServiceBean.class);
    ...
    return builder.getBeanDefinition();
}
// ClassPathBeanDefinitionScanner.java
public int scan(String... basePackages) {
    int beanCountAtScanStart = this.registry.getBeanDefinitionCount();

    doScan(basePackages);
    ...
    return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
}

protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
    ...
    Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
    for (String basePackage : basePackages) {
        Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
        for (BeanDefinition candidate : candidates) {
            ...
            if (checkCandidate(beanName, candidate)) {
                BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
                definitionHolder =
                        AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
                beanDefinitions.add(definitionHolder);
                registerBeanDefinition(definitionHolder, this.registry);
            }
        }
    }
    return beanDefinitions;
}

4.ReferenceAnnotationBeanPostProcessor 注册 bean

扫描注解

@org.apache.dubbo.config.annotation.DubboReference
@org.apache.dubbo.config.annotation.Reference
@com.alibaba.dubbo.config.annotation.Reference

循环 beanDefinitionNames,找到成员变量和方法,标注 @org.apache.dubbo.config.annotation.DubboReference、@org.apache.dubbo.config.annotation.Reference、@com.alibaba.dubbo.config.annotation.Reference 的成员变量和方法,把扫描到的成员变量和方法,注册到 spring,并注册到 referenceBeanManager

beanName: server1
beanDefinition: RootBeanDefinition,其中 beanClass 是 org.apache.dubbo.config.spring.ReferenceBean
referenceKey: ReferenceBean:dev_group/com.example.common.server.Server1:1.0()
referenceBeanName: server1
// ReferenceAnnotationBeanPostProcessor.java
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    String[] beanNames = beanFactory.getBeanDefinitionNames();
    for (String beanName : beanNames) {
        Class<?> beanType;
        if (beanFactory.isFactoryBean(beanName)) {
            ...
        } else {
            beanType = beanFactory.getType(beanName);
        }
        if (beanType != null) {
            AnnotatedInjectionMetadata metadata = findInjectionMetadata(beanName, beanType, null);
            try {
                prepareInjection(metadata);
            } catch (BeansException e) {
                throw e;
            } catch (Exception e) {
                throw new IllegalStateException("Prepare dubbo reference injection element failed", e);
            }
        }
    }
    ...
    try {
        applicationContext.publishEvent(new DubboConfigInitEvent(applicationContext));
    } catch (Exception e) {
        ...
    }
}

protected AnnotatedInjectionMetadata findInjectionMetadata(String beanName, Class<?> clazz, PropertyValues pvs) {
    String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
    AbstractAnnotationBeanPostProcessor.AnnotatedInjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
    if (needsRefreshInjectionMetadata(metadata, clazz)) {
        synchronized (this.injectionMetadataCache) {
            metadata = this.injectionMetadataCache.get(cacheKey);

            if (needsRefreshInjectionMetadata(metadata, clazz)) {
                if (metadata != null) {
                    metadata.clear(pvs);
                }
                try {
                    metadata = buildAnnotatedMetadata(clazz);
                    this.injectionMetadataCache.put(cacheKey, metadata);
                } catch (NoClassDefFoundError err) {
                    ...
                }
            }
        }
    }
    return metadata;
}

private AbstractAnnotationBeanPostProcessor.AnnotatedInjectionMetadata buildAnnotatedMetadata(final Class<?> beanClass) {
    Collection<AbstractAnnotationBeanPostProcessor.AnnotatedFieldElement> fieldElements = findFieldAnnotationMetadata(beanClass);
    Collection<AbstractAnnotationBeanPostProcessor.AnnotatedMethodElement> methodElements = findAnnotatedMethodMetadata(beanClass);
    return new AnnotatedInjectionMetadata(beanClass, fieldElements, methodElements);
}

protected void prepareInjection(AnnotatedInjectionMetadata metadata) throws BeansException {
    try {
        for (AnnotatedFieldElement fieldElement : metadata.getFieldElements()) {
            if (fieldElement.injectedObject != null) {
                continue;
            }
            Class<?> injectedType = fieldElement.field.getType();
            AnnotationAttributes attributes = fieldElement.attributes;
            String referenceBeanName = registerReferenceBean(fieldElement.getPropertyName(), injectedType, attributes, fieldElement.field);

            //associate fieldElement and reference bean
            fieldElement.injectedObject = referenceBeanName;
            injectedFieldReferenceBeanCache.put(fieldElement, referenceBeanName);

        }

        for (AnnotatedMethodElement methodElement : metadata.getMethodElements()) {
            if (methodElement.injectedObject != null) {
                continue;
            }
            Class<?> injectedType = methodElement.getInjectedType();
            AnnotationAttributes attributes = methodElement.attributes;
            String referenceBeanName = registerReferenceBean(methodElement.getPropertyName(), injectedType, attributes, methodElement.method);

            //associate methodElement and reference bean
            methodElement.injectedObject = referenceBeanName;
            injectedMethodReferenceBeanCache.put(methodElement, referenceBeanName);
        }
    } catch (ClassNotFoundException e) {
        ...
    }
}

public String registerReferenceBean(String propertyName, Class<?> injectedType, Map<String, Object> attributes, Member member) throws BeansException {
    ...
    // check reference key
    String referenceKey = ReferenceBeanSupport.generateReferenceKey(attributes, applicationContext);

    // find reference bean name by reference key
    List<String> registeredReferenceBeanNames = referenceBeanManager.getBeanNamesByKey(referenceKey);
    if (registeredReferenceBeanNames.size() > 0) {
        // found same name and reference key
        if (registeredReferenceBeanNames.contains(referenceBeanName)) {
            return referenceBeanName;
        }
    }

    ...
    Class interfaceClass = injectedType;

    // Register the reference bean definition to the beanFactory
    RootBeanDefinition beanDefinition = new RootBeanDefinition();
    beanDefinition.setBeanClassName(ReferenceBean.class.getName());
    beanDefinition.getPropertyValues().add(ReferenceAttributes.ID, referenceBeanName);

    // set attribute instead of property values
    beanDefinition.setAttribute(Constants.REFERENCE_PROPS, attributes);
    beanDefinition.setAttribute(ReferenceAttributes.INTERFACE_CLASS, interfaceClass);
    beanDefinition.setAttribute(ReferenceAttributes.INTERFACE_NAME, interfaceName);

    // create decorated definition for reference bean, Avoid being instantiated when getting the beanType of ReferenceBean
    // see org.springframework.beans.factory.support.AbstractBeanFactory#getTypeForFactoryBean()
    GenericBeanDefinition targetDefinition = new GenericBeanDefinition();
    targetDefinition.setBeanClass(interfaceClass);
    beanDefinition.setDecoratedDefinition(new BeanDefinitionHolder(targetDefinition, referenceBeanName + "_decorated"));

    // signal object type since Spring 5.2
    beanDefinition.setAttribute(Constants.OBJECT_TYPE_ATTRIBUTE, interfaceClass);

    beanDefinitionRegistry.registerBeanDefinition(referenceBeanName, beanDefinition);
    referenceBeanManager.registerReferenceKeyAndBeanName(referenceKey, referenceBeanName);
    logger.info("Register dubbo reference bean: " + referenceBeanName + " = " + referenceKey + " at " + member);
    return referenceBeanName;
}

5.ReferenceAnnotationBeanPostProcessor 注入属性

1.执行 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName) 方法,调用 ReferenceAnnotationBeanPostProcessor 的 postProcessMergedBeanDefinition(mbd, beanType, beanName) 方法,扫描@org.apache.dubbo.config.annotation.DubboReference、@org.apache.dubbo.config.annotation.Reference、@com.alibaba.dubbo.config.annotation.Reference 注解,把符合的成员变量绑定的 BeanDefinition,
并从 spring 容器中,获得对应的 bean (若没有注册,则会注册到 spring 容器) 的 beanName,绑定到 BeanDefinition

2.执行 populateBean(beanName, mbd, bw) 方法,调用 ReferenceAnnotationBeanPostProcessor 的 postProcessProperties(pvs, bean, beanName) 方法,进行把值赋值给成员变量

// DefaultListableBeanFactory.java
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {

    BeanWrapper instanceWrapper = null;
    ...
    if (instanceWrapper == null) {
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    Object bean = instanceWrapper.getWrappedInstance();
    ...
    // Allow post-processors to modify the merged bean definition.
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            }
            ...
            mbd.postProcessed = true;
        }
    }
    ...
    Object exposedObject = bean;
    try {
        populateBean(beanName, mbd, instanceWrapper);
        ...
    }
    ...
}

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
    for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
        processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
    }
}

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    if (bw == null) {
        ...
    }
    ...
    PropertyDescriptor[] filteredPds = null;
    if (hasInstAwareBpps) {
        if (pvs == null) {
            pvs = mbd.getPropertyValues();
        }
        for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
            PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
            if (pvsToUse == null) {
                if (filteredPds == null) {
                    filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                }
                pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                if (pvsToUse == null) {
                    return;
                }
            }
            pvs = pvsToUse;
        }
    }
    if (needsDepCheck) {
        if (filteredPds == null) {
            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        }
        checkDependencies(beanName, mbd, filteredPds, pvs);
    }   
    ...
}
// ReferenceAnnotationBeanPostProcessor.java
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
    if (beanType != null) {
        if (isReferenceBean(beanDefinition)) {
            ...
        } else if (isAnnotatedReferenceBean(beanDefinition)) {
            ...
        } else {
            AnnotatedInjectionMetadata metadata = findInjectionMetadata(beanName, beanType, null);
            metadata.checkConfigMembers(beanDefinition);
            try {
                prepareInjection(metadata);
            } catch (Exception e) {
                ...
            }
        }
    }
}

@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
    throws BeansException {
    try {
        AnnotatedInjectionMetadata metadata = findInjectionMetadata(beanName, bean.getClass(), pvs);
        prepareInjection(metadata);
        metadata.inject(bean, beanName, pvs);
    }
    ...
    return pvs;
}

protected void prepareInjection(AnnotatedInjectionMetadata metadata) throws BeansException {
    try {
        //find and register bean definition for @DubboReference/@Reference
        for (AnnotatedFieldElement fieldElement : metadata.getFieldElements()) {
            if (fieldElement.injectedObject != null) {
                continue;
            }
            Class<?> injectedType = fieldElement.field.getType();
            AnnotationAttributes attributes = fieldElement.attributes;
            String referenceBeanName = registerReferenceBean(fieldElement.getPropertyName(), injectedType, attributes, fieldElement.field);

            //associate fieldElement and reference bean
            fieldElement.injectedObject = referenceBeanName;
            injectedFieldReferenceBeanCache.put(fieldElement, referenceBeanName);

        }

        for (AnnotatedMethodElement methodElement : metadata.getMethodElements()) {
            if (methodElement.injectedObject != null) {
                continue;
            }
            Class<?> injectedType = methodElement.getInjectedType();
            AnnotationAttributes attributes = methodElement.attributes;
            String referenceBeanName = registerReferenceBean(methodElement.getPropertyName(), injectedType, attributes, methodElement.method);

            //associate methodElement and reference bean
            methodElement.injectedObject = referenceBeanName;
            injectedMethodReferenceBeanCache.put(methodElement, referenceBeanName);
        }
    } catch (ClassNotFoundException e) {
        throw new BeanCreationException("prepare reference annotation failed", e);
    }
}

protected Object getInjectedObject(AnnotationAttributes attributes, Object bean, String beanName, Class<?> injectedType,
                                   AnnotatedInjectElement injectedElement) throws Exception {
    return doGetInjectedBean(attributes, bean, beanName, injectedType, injectedElement);
}

@Override
protected Object doGetInjectedBean(AnnotationAttributes attributes, Object bean, String beanName, Class<?> injectedType,
                                   AnnotatedInjectElement injectedElement) throws Exception {

    if (injectedElement.injectedObject == null) {
        throw new IllegalStateException("The AnnotatedInjectElement of @DubboReference should be inited before injection");
    }

    return getBeanFactory().getBean((String) injectedElement.injectedObject);
}
// AbstractAnnotationBeanPostProcessor$AnnotatedInjectionMetadata
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
    Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size());
    for (InjectedElement element : this.injectedElements) {
        Member member = element.getMember();
        if (!beanDefinition.isExternallyManagedConfigMember(member)) {
            beanDefinition.registerExternallyManagedConfigMember(member);
            checkedElements.add(element);
        }
    }
    this.checkedElements = checkedElements;
}

public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
    Collection<InjectedElement> checkedElements = this.checkedElements;
    Collection<InjectedElement> elementsToIterate =
            (checkedElements != null ? checkedElements : this.injectedElements);
    if (!elementsToIterate.isEmpty()) {
        for (InjectedElement element : elementsToIterate) {
            element.inject(target, beanName, pvs);
        }
    }
}
// AbstractAnnotationBeanPostProcessor$AnnotatedFieldElement.java
@Override
protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {

    Object injectedObject = getInjectedObject(attributes, bean, beanName, getInjectedType(), this);

    if (member instanceof Field) {
        Field field = (Field) member;
        ReflectionUtils.makeAccessible(field);
        field.set(bean, injectedObject);
    } else if (member instanceof Method) {
        Method method = (Method) member;
        ReflectionUtils.makeAccessible(method);
        method.invoke(bean, injectedObject);
    }
}