zoukankan      html  css  js  c++  java
  • Dubbo服务注册原理

    文章目录

    • 1注册步骤
    • 2 猜想:
    • 3源码分析
      • 3.1 @DubboComponentScan
        • 3.1.1 图片总结
      • 3.2 DubboBootstrapApplicationListener.java

    1注册步骤

    1. 使用注解@DubboService或@Service
    2. 扫描注解@DubboComponentScan

    2 猜想:

    (1)扫描注解
    (2)组装url
    (3)启动服务(根据url中配置的协议、端口去发布对应的服务)
    (4)注册到注册中心

    3源码分析

    3.1 @DubboComponentScan

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import({DubboComponentScanRegistrar.class})
    public @interface DubboComponentScan {
        String[] value() default {};
    
        String[] basePackages() default {};
    
        Class<?>[] basePackageClasses() default {};
    }
    

    DubboComponentScanRegistrar:动态注册bean到IOC中,但是是注册哪个bean?需要分析下源码

        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    //获取@DubboComponentScan注解中配置的包路径
            Set<String> packagesToScan = getPackagesToScan(importingClassMetadata);
    //注册bean到IOC容器中
            registerServiceAnnotationBeanPostProcessor(packagesToScan, registry);
    
            // @since 2.7.6 Register the common beans
            registerCommonBeans(registry);
        }
    

    点击 registerServiceAnnotationBeanPostProcessor(packagesToScan, registry),可以看到将ServiceAnnotationBeanPostProcessor加载到IOC容器中

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

    来看下 ServiceAnnotationBeanPostProcessor.java

      public ServiceAnnotationBeanPostProcessor(Set<String> packagesToScan) {
            super(packagesToScan);
        }
    

    点击父类ServiceClassPostProcessor.java的构造器,在bean加载到IOC之后会触发postProcessBeanDefinitionRegistry方法

    @Override
        public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    
            // @since 2.7.5
            //注册基础bean
            registerInfrastructureBean(registry, DubboBootstrapApplicationListener.BEAN_NAME, DubboBootstrapApplicationListener.class);
    
            Set<String> resolvedPackagesToScan = resolvePackagesToScan(packagesToScan);
              //如果扫描的包路径不为空,注册服务bean:serviceBean
            if (!CollectionUtils.isEmpty(resolvedPackagesToScan)) {
                registerServiceBeans(resolvedPackagesToScan, registry);
            } else {
                if (logger.isWarnEnabled()) {
                    logger.warn("packagesToScan is empty , ServiceBean registry will be ignored!");
                }
            }
    
        }
    

    registerInfrastructureBean()方法中将DubboBootstrapApplicationListener注册到容器中,
    DubboBootstrapApplicationListener中的onApplicationContextEvent()方法会在spring 容器的上下文装载完成之后,触发监听

     @Override
        public void onApplicationContextEvent(ApplicationContextEvent event) {
            if (event instanceof ContextRefreshedEvent) {
                onContextRefreshedEvent((ContextRefreshedEvent) event);
            } else if (event instanceof ContextClosedEvent) {
                onContextClosedEvent((ContextClosedEvent) event);
            }
        }
    

    再来看下registerServiceBeans(resolvedPackagesToScan, registry) 代码
    扫描所有加了@DubboService或@Service注解的bean,但不是注册到IOC容器里

     private void registerServiceBeans(Set<String> packagesToScan, BeanDefinitionRegistry registry) {
    
           DubboClassPathBeanDefinitionScanner scanner =
                   new DubboClassPathBeanDefinitionScanner(registry, environment, resourceLoader);
    
           BeanNameGenerator beanNameGenerator = resolveBeanNameGenerator(registry);
    
           scanner.setBeanNameGenerator(beanNameGenerator);
    
           // refactor @since 2.7.7
           serviceAnnotationTypes.forEach(annotationType -> {
               scanner.addIncludeFilter(new AnnotationTypeFilter(annotationType));
           });
    
           for (String packageToScan : packagesToScan) {
    
               // Registers @Service Bean first
               scanner.scan(packageToScan);
    
               // Finds all BeanDefinitionHolders of @Service whether @ComponentScan scans or not.
               Set<BeanDefinitionHolder> beanDefinitionHolders =
                       findServiceBeanDefinitionHolders(scanner, packageToScan, registry, beanNameGenerator);
    
               if (!CollectionUtils.isEmpty(beanDefinitionHolders)) {
    
                   for (BeanDefinitionHolder beanDefinitionHolder : beanDefinitionHolders) {
                       registerServiceBean(beanDefinitionHolder, registry, scanner);
                   }
    
                   if (logger.isInfoEnabled()) {
                       logger.info(beanDefinitionHolders.size() + " annotated Dubbo's @Service Components { " +
                               beanDefinitionHolders +
                               " } were scanned under package[" + packageToScan + "]");
                   }
    
               } else {
    
                   if (logger.isWarnEnabled()) {
                       logger.warn("No Spring Bean annotating Dubbo's @Service was found under package["
                               + packageToScan + "]");
                   }
    
               }
    
           }
    
       }
    

    点击 registerServiceBean(beanDefinitionHolder, registry, scanner);

    private void registerServiceBean(BeanDefinitionHolder beanDefinitionHolder, BeanDefinitionRegistry registry,
                                        DubboClassPathBeanDefinitionScanner scanner) {
    
           Class<?> beanClass = resolveClass(beanDefinitionHolder);
    
           Annotation service = findServiceAnnotation(beanClass);
    
           /**
            * The {@link AnnotationAttributes} of @Service annotation
            */
           AnnotationAttributes serviceAnnotationAttributes = getAnnotationAttributes(service, false, false);
    
           Class<?> interfaceClass = resolveServiceInterfaceClass(serviceAnnotationAttributes, beanClass);
    
           String annotatedServiceBeanName = beanDefinitionHolder.getBeanName();
    
           AbstractBeanDefinition serviceBeanDefinition =
                   buildServiceBeanDefinition(service, serviceAnnotationAttributes, interfaceClass, annotatedServiceBeanName);
    
           // ServiceBean Bean name
           String beanName = generateServiceBeanName(serviceAnnotationAttributes, interfaceClass);
    
           if (scanner.checkCandidate(beanName, serviceBeanDefinition)) { // check duplicated candidate bean
               registry.registerBeanDefinition(beanName, serviceBeanDefinition);
    
               if (logger.isInfoEnabled()) {
                   logger.info("The BeanDefinition[" + serviceBeanDefinition +
                           "] of ServiceBean has been registered with name : " + beanName);
               }
    
           } else {
    
               if (logger.isWarnEnabled()) {
                   logger.warn("The Duplicated BeanDefinition[" + serviceBeanDefinition +
                           "] of ServiceBean[ bean name : " + beanName +
                           "] was be found , Did @DubboComponentScan scan to same package in many times?");
               }
    
           }
    
       }
    

    buildServiceBeanDefinition

     private AbstractBeanDefinition buildServiceBeanDefinition(Annotation serviceAnnotation,
                                                                 AnnotationAttributes serviceAnnotationAttributes,
                                                                 Class<?> interfaceClass,
                                                                 String annotatedServiceBeanName) {
    
           BeanDefinitionBuilder builder = rootBeanDefinition(ServiceBean.class);
           //省略代码
    

    最终将org.apache.dubbo.config.spring.ServiceBean注册到IOC容器中

    3.1.1 图片总结

    在这里插入图片描述

    3.2 DubboBootstrapApplicationListener.java

    DubboBootstrapApplicationListener.java实现了监听接口,最终会调用ServiceConfig#export()方法,调用过程如下图:
    在这里插入图片描述

     http://www.exyb.cn/news/show-333.html

  • 相关阅读:
    [node.js学习]为node.js写的一个操作mysql的类
    极光IM简单接入步骤
    windows自带的netsh 端口转发
    nodejs 做的带管理后台的东东,主要学习到 ....我忘了学到什么了
    利用来JS控制页面控件显示和隐藏有两种方法
    phpstudy 出现You don't have permission to access / on this server.
    禁用input自动填充
    一般充值的流程
    jq传输json字符串
    ECSHOP更改后台顶部图片
  • 原文地址:https://www.cnblogs.com/cndeveloper/p/14745432.html
Copyright © 2011-2022 走看看