dubbo自动装配入口

@EnableDubbo注解是源码分析的入口

@SpringBootApplication
@EnableDubbo
public class ConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
}

@EnableDubbo源码

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@EnableDubboConfig //开启自动装配
@DubboComponentScan //扫描核心
public @interface EnableDubbo {

    /**
     * Base packages to scan for annotated @Service classes.
     * <p>
     * Use {@link #scanBasePackageClasses()} for a type-safe alternative to String-based
     * package names.
     *
     * @return the base packages to scan
     * @see DubboComponentScan#basePackages()
     */
    @AliasFor(annotation = DubboComponentScan.class, attribute = "basePackages")
    String[] scanBasePackages() default {};

    /**
     * Type-safe alternative to {@link #scanBasePackages()} for specifying the packages to
     * scan for annotated @Service classes. The package of each class specified will be
     * scanned.
     *
     * @return classes from the base packages to scan
     * @see DubboComponentScan#basePackageClasses
     */
    @AliasFor(annotation = DubboComponentScan.class, attribute = "basePackageClasses")
    Class<?>[] scanBasePackageClasses() default {};

    /**
     * It indicates whether {@link AbstractConfig} binding to multiple Spring Beans.
     *
     * @return the default value is <code>true</code>
     * @see EnableDubboConfig#multiple()
     */
    @AliasFor(annotation = EnableDubboConfig.class, attribute = "multiple")
    boolean multipleConfig() default true;
}

扫描DubboService的类

//在DubboComponentScanRegistrar实例化的时候,我们执行下面的方法,实例化ServerAnnotationPostProcessor
 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);
    }

ServerAnnotationPostProcessor.class注册所有的@Service以及@DubboService
ServerAnnotationPostProcessor注册实例化时,会走下面的postProcessDefinitionRegister()方法。

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

走scanServiceBeans扫描@Service或者@DubboService修饰的类

 private void scanServiceBeans(Set<String> packagesToScan, BeanDefinitionRegistry registry) {
			//标识位
        scanned = true;
        //校验扫描路径
        if (CollectionUtils.isEmpty(packagesToScan)) {
            if (logger.isWarnEnabled()) {
                logger.warn(
                        CONFIG_NO_BEANS_SCANNED,
                        "",
                        "",
                        "packagesToScan is empty , ServiceBean registry will be ignored!");
            }
            return;
        }
			//核心执行扫描的类
        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) {

            // avoid duplicated scans
            if (servicePackagesHolder.isPackageScanned(packageToScan)) {
                if (logger.isInfoEnabled()) {
                    logger.info("Ignore package who has already bean scanned: " + packageToScan);
                }
                continue;
            }

            // 核心扫描事件
            scanner.scan(packageToScan);

            // Finds all BeanDefinitionHolders of @Service whether @ComponentScan scans or not. 查询全部的bean实例
            Set<BeanDefinitionHolder> beanDefinitionHolders =
                    findServiceBeanDefinitionHolders(scanner, packageToScan, registry, beanNameGenerator);

            if (!CollectionUtils.isEmpty(beanDefinitionHolders)) {
                if (logger.isInfoEnabled()) {
                    List<String> serviceClasses = new ArrayList<>(beanDefinitionHolders.size());
                    for (BeanDefinitionHolder beanDefinitionHolder : beanDefinitionHolders) {
                        serviceClasses.add(
                                beanDefinitionHolder.getBeanDefinition().getBeanClassName());
                    }
                    logger.info("Found " + beanDefinitionHolders.size()
                            + " classes annotated by Dubbo @Service under package [" + packageToScan + "]: "
                            + serviceClasses);
                }

                for (BeanDefinitionHolder beanDefinitionHolder : beanDefinitionHolders) {
                	//注册被@Service或者 @DubboService修饰的类,核心
                    processScannedBeanDefinition(beanDefinitionHolder);
                    servicePackagesHolder.addScannedClass(
                            beanDefinitionHolder.getBeanDefinition().getBeanClassName());
                }
            } else {
                if (logger.isWarnEnabled()) {
                    logger.warn(
                            CONFIG_NO_ANNOTATIONS_FOUND,
                            "No annotations were found on the class",
                            "",
                            "No class annotated by Dubbo @DubboService or @Service was found under package ["
                                    + packageToScan + "], ignore re-scanned classes: "
                                    + scanExcludeFilter.getExcludedCount());
                }
            }

            servicePackagesHolder.addScannedPackage(packageToScan);
        }
    }

processScannedBeanDefinition注册扫描到的被@DubboService或@Service修饰的类

    private void processScannedBeanDefinition(BeanDefinitionHolder beanDefinitionHolder) {
				//解析类
        Class<?> beanClass = resolveClass(beanDefinitionHolder);
				//获取当前类的注解
        Annotation service = findServiceAnnotation(beanClass);

        // T获取注解的属性
        Map<String, Object> serviceAnnotationAttributes = AnnotationUtils.getAttributes(service, true);
			//解析服务的接口
        String serviceInterface = resolveInterfaceName(serviceAnnotationAttributes, beanClass);
				//获取当前类的benaName
        String annotatedServiceBeanName = beanDefinitionHolder.getBeanName();

        // ServiceBean Bean name
        String beanName = generateServiceBeanName(serviceAnnotationAttributes, serviceInterface);
        // // ① 创建一个新的 BeanDefinition —— ServiceBean
        AbstractBeanDefinition serviceBeanDefinition =
                buildServiceBeanDefinition(serviceAnnotationAttributes, serviceInterface, annotatedServiceBeanName);
        //注册新的 BeanDefinition
        registerServiceBeanDefinition(beanName, serviceBeanDefinition, serviceInterface);
    }

获取Referen修饰的属性

在这里插入图片描述

public class DubboConfigConfigurationRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        // 初始化dubbo 的bean实例
        DubboSpringInitializer.initialize(registry);
    }
}

DubboSpringInitializer#initContext()方法

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

        // customize context, you can change the bind module model via DubboSpringInitCustomizer SPI
        customize(context);

        // 初始化模型模块
        ModuleModel moduleModel = context.getModuleModel();
        if (moduleModel == null) {
            ApplicationModel applicationModel;
            if (findContextForApplication(ApplicationModel.defaultModel()) == null) {
                // first spring context use default application instance
                applicationModel = ApplicationModel.defaultModel();
                logger.info("Use default application: " + applicationModel.getDesc());
            } else {
                // 创建一个新的实例模块
                applicationModel = FrameworkModel.defaultModel().newApplication();
                logger.info("Create new application: " + applicationModel.getDesc());
            }

            // init ModuleModel
            moduleModel = applicationModel.getDefaultModule();
            context.setModuleModel(moduleModel);
            logger.info("Use default module model of target application: " + moduleModel.getDesc());
        } else {
            logger.info("Use module model from customizer: " + moduleModel.getDesc());
        }
        logger.info(
                "Bind " + moduleModel.getDesc() + " to spring container: " + ObjectUtils.identityToString(registry));

        // set module attributes
        Map<String, Object> moduleAttributes = context.getModuleAttributes();
        if (moduleAttributes.size() > 0) {
            moduleModel.getAttributes().putAll(moduleAttributes);
        }

        // 绑定dubbo的实力到spring容器中
        registerContextBeans(beanFactory, context);

        // mark context as bound
        context.markAsBound();
        moduleModel.setLifeCycleManagedExternally(true);

        // 注册公共的实例信息
        DubboBeanUtils.registerCommonBeans(registry);
    }
	//注册公共的实例信息
	 static void registerCommonBeans(BeanDefinitionRegistry registry) {
	
	        registerInfrastructureBean(registry, ServicePackagesHolder.BEAN_NAME, ServicePackagesHolder.class);
	//注册referenceBeanManager实例
	        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);
	    }

注册 ReferenceAnnotationBeanPostProcessor类,实例化后执行postProcessBeanFactory()方法

 public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
			//获取spring容器中的所有的bean实例
        String[] beanNames = beanFactory.getBeanDefinitionNames();
        //遍历bean实例,找出这些实例中被@DubboReference或者@Reference注解修饰
        for (String beanName : beanNames) {
            Class<?> beanType;
           if (beanFactory.isFactoryBean(beanName)) {
                BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
                if (isReferenceBean(beanDefinition)) {
                    continue;
                }
                if (isAnnotatedReferenceBean(beanDefinition)) {
                    // process @DubboReference at java-config @bean method
                    processReferenceAnnotatedBeanDefinition(beanName, (AnnotatedBeanDefinition) beanDefinition);
                    continue;
                }

                String beanClassName = beanDefinition.getBeanClassName();
                beanType = ClassUtils.resolveClass(beanClassName, getClassLoader());
            } 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);
                }
            }
        }

        if (beanFactory instanceof AbstractBeanFactory) {
            List<BeanPostProcessor> beanPostProcessors = ((AbstractBeanFactory) beanFactory).getBeanPostProcessors();
            for (BeanPostProcessor beanPostProcessor : beanPostProcessors) {
                if (beanPostProcessor == this) {
                    // This bean has been registered as BeanPostProcessor at
                    // org.apache.dubbo.config.spring.context.DubboInfraBeanRegisterPostProcessor.postProcessBeanFactory()
                    // so destroy this bean here, prevent register it as BeanPostProcessor again, avoid cause
                    // BeanPostProcessorChecker detection error
                    beanDefinitionRegistry.removeBeanDefinition(BEAN_NAME);
                    break;
                }
            }
        }

        try {
            // this is an early event, it will be notified at
            // org.springframework.context.support.AbstractApplicationContext.registerListeners()
            applicationContext.publishEvent(new DubboConfigInitEvent(applicationContext));
        } catch (Exception e) {
            // if spring version is less than 4.2, it does not support early application event
            logger.warn(
                    CONFIG_DUBBO_BEAN_INITIALIZER,
                    "",
                    "",
                    "publish early application event failed, please upgrade spring version to 4.2.x or later: " + e);
        }
    }

请求调用流程

消费者如何订阅到生产者

消费者初始化订阅的对象
在这里插入图片描述

创建ReferenceBean对象后会执行AfterPropertesSet()方法

 public void afterPropertiesSet() throws Exception {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();

        // pre init xml reference bean or @DubboReference annotation
        Assert.notEmptyString(getId(), "The id of ReferenceBean cannot be empty");
        BeanDefinition beanDefinition = beanFactory.getBeanDefinition(getId());
        this.interfaceClass = (Class<?>) beanDefinition.getAttribute(ReferenceAttributes.INTERFACE_CLASS);
        this.interfaceName = (String) beanDefinition.getAttribute(ReferenceAttributes.INTERFACE_NAME);
        Assert.notNull(this.interfaceClass, "The interface class of ReferenceBean is not initialized");

        if (beanDefinition.hasAttribute(Constants.REFERENCE_PROPS)) {
            // @DubboReference annotation at java-config class @Bean method
            // @DubboReference annotation at reference field or setter method
            referenceProps = (Map<String, Object>) beanDefinition.getAttribute(Constants.REFERENCE_PROPS);
        } else {
            if (beanDefinition instanceof AnnotatedBeanDefinition) {
                // Return ReferenceBean in java-config class @Bean method
                if (referenceProps == null) {
                    referenceProps = new LinkedHashMap<>();
                }
                ReferenceBeanSupport.convertReferenceProps(referenceProps, interfaceClass);
                if (this.interfaceName == null) {
                    this.interfaceName = (String) referenceProps.get(ReferenceAttributes.INTERFACE);
                }
            } else {
                // xml reference bean
                propertyValues = beanDefinition.getPropertyValues();
            }
        }

        if (referenceProps != null) {
            this.proxy = (String) referenceProps.get(ReferenceAttributes.PROXY);
        }
        Assert.notNull(this.interfaceName, "The interface name of ReferenceBean is not initialized");
			//创建referenceBeanManager对象
        this.referenceBeanManager = beanFactory.getBean(ReferenceBeanManager.BEAN_NAME, ReferenceBeanManager.class);
        //执行addreference方法
        referenceBeanManager.addReference(this);
    }

核心方法addreference()

 public void addReference(ReferenceBean referenceBean) throws Exception {
        String referenceBeanName = referenceBean.getId();
        Assert.notEmptyString(referenceBeanName, "The id of ReferenceBean cannot be empty");

        if (!initialized) {
            // TODO add issue url to describe early initialization
            logger.warn(
                    CONFIG_DUBBO_BEAN_INITIALIZER,
                    "",
                    "",
                    "Early initialize reference bean before DubboConfigBeanInitializer,"
                            + " the BeanPostProcessor has not been loaded at this time, which may cause abnormalities in some components (such as seata): "
                            + referenceBeanName
                            + " = " + ReferenceBeanSupport.generateReferenceKey(referenceBean, applicationContext));
        }
        //生成referencename的名称
        String referenceKey = getReferenceKeyByBeanName(referenceBeanName);
        if (StringUtils.isEmpty(referenceKey)) {
            referenceKey = ReferenceBeanSupport.generateReferenceKey(referenceBean, applicationContext);
        }
        //判断缓存中是否已经含有的此对象
        ReferenceBean oldReferenceBean = referenceBeanMap.get(referenceBeanName);
        if (oldReferenceBean != null) {
            if (referenceBean != oldReferenceBean) {
                String oldReferenceKey =
                        ReferenceBeanSupport.generateReferenceKey(oldReferenceBean, applicationContext);
                throw new IllegalStateException("Found duplicated ReferenceBean with id: " + referenceBeanName
                        + ", old: " + oldReferenceKey + ", new: " + referenceKey);
            }
            return;
        }
        //放到map缓存中
        referenceBeanMap.put(referenceBeanName, referenceBean);
        // save cache, map reference key to referenceBeanName
        this.registerReferenceKeyAndBeanName(referenceKey, referenceBeanName);

        // if add reference after prepareReferenceBeans(), should init it immediately.
        if (initialized) {
        		//初始化referenceBean创建referenceConfig
            initReferenceBean(referenceBean);
        }
    }

initReferenceBean方法

 public synchronized void initReferenceBean(ReferenceBean referenceBean) throws Exception {
				//判断当前的referenceBean是否已经含有配置信息
        if (referenceBean.getReferenceConfig() != null) {
            return;
        }

        // TOTO check same unique service name but difference reference key (means difference attributes).

        // 生成reference的名称
        String referenceKey = getReferenceKeyByBeanName(referenceBean.getId());
        //如果为null,则重新生成
        if (StringUtils.isEmpty(referenceKey)) {
            referenceKey = ReferenceBeanSupport.generateReferenceKey(referenceBean, applicationContext);
        }
				//从map中获取referenceConfig
        ReferenceConfig referenceConfig = referenceConfigMap.get(referenceKey);
        //缓存中获取到的为null
        if (referenceConfig == null) {
            // 创建真正的referencebean信息
            Map<String, Object> referenceAttributes = ReferenceBeanSupport.getReferenceAttributes(referenceBean);
            referenceConfig = ReferenceCreator.create(referenceAttributes, applicationContext)
                    .defaultInterfaceClass(referenceBean.getObjectType())
                    .build();

            // 设置id
            if (referenceBean.getId() != null && !referenceBean.getId().contains("#")) {
                referenceConfig.setId(referenceBean.getId());
            }

            // 放到缓存中
            referenceConfigMap.put(referenceKey, referenceConfig);

            // register ReferenceConfig
            moduleModel.getConfigManager().addReference(referenceConfig);
            moduleModel.getDeployer().setPending();
        }

        // 将referenceConfig和referenceBean关联
        referenceBean.setKeyAndReferenceConfig(referenceKey, referenceConfig);
    }

DubboDeployApplicationListener.onContextRefreshedEvent()对象

 private void onContextRefreshedEvent(ContextRefreshedEvent event) {
 			//获取模块模型的ModuleDeployer
        ModuleDeployer deployer = moduleModel.getDeployer();
        Assert.notNull(deployer, "Module deployer is null");
        Object singletonMutex = LockUtils.getSingletonMutex(applicationContext);
        // start module
        Future future = null;
        synchronized (singletonMutex) {
        		//开启startModel
            future = deployer.start();
        }

        // if the module does not start in background, await finish
        if (!deployer.isBackground()) {
            try {
                future.get();
            } catch (InterruptedException e) {
                logger.warn(
                        CONFIG_FAILED_START_MODEL,
                        "",
                        "",
                        "Interrupted while waiting for dubbo module start: " + e.getMessage());
            } catch (Exception e) {
                logger.warn(
                        CONFIG_FAILED_START_MODEL,
                        "",
                        "",
                        "An error occurred while waiting for dubbo module start: " + e.getMessage(),
                        e);
            }
        }
    }
Logo

鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。

更多推荐