• 简单读读源码


    1. 消费者端dubbo的yml配置

      dubbo:
        consumer:
          timeout: 300000
        protocol:
          name: dubbo
          port: -1
        cloud:
          subscribed-services: order-server
      #    subscribed-services: hello-server,account-server,storage-server,order-server
      
    2. 按住ctrl + 鼠标左击subscribed-services如下图:

      按住鼠标左击

    3. 这里是对应的setter方法,上面找到定义地方

      	/**
      	 * All services of Dubbo.
      	 */
      	public static final String ALL_DUBBO_SERVICES = "*";
      
      	/**
      	 * The subscribed services, the default value is "*". The multiple value will use
      	 * comma(",") as the separator.
      	 *
      	 * @see #ALL_DUBBO_SERVICES
      	 */
      	private String subscribedServices = ALL_DUBBO_SERVICES;
      

      读一读就知道答案了。默认为*,多个值时候用,隔开。


      接下来,走走最表面的流程,就是看看怎么处理我们输入的数据的,至于是怎么找到提供者的,先不管。

    4. 光标点到类DubboCloudProperties上面,这里ctrl+单击是点不进去的,但是你点一下有提醒

      No usages found in Project Files 
      Press Ctrl+Alt+F7 again to search in 'Project and Libraries
      
    5. 跟着提醒,Ctrl+Alt+F7,如果提醒关闭了,就双击F7,出来下图。

      ctrl+alt+f7

    6. 直接回车,就是高亮的这一行。回去复制ubscribedServices,不要开头的s,不管大写还是小写,Ctrl+F搜出来看看。

    7. 通过点击向上向下的箭头,或者F3(下一个)/Shift+F3(上一个)来读一读源码。这里我们看到他在237行时候进行了初始化。

      初始化

    8. 老样子,ctrl+单击initSubscribedServices()方法。

      初始化方法

      读一下,如果ALL_DUBBO_SERVICES等于我们输入的提供者,就是输出巴拉巴拉。

    9. 那么ALL_DUBBO_SERVICES是啥,ctrl点,发现又跳回第一个文件了:

      @ConfigurationProperties(prefix = CONFIG_PROPERTY_PREFIX)
      public class DubboCloudProperties {
      
      	/**
      	 * All services of Dubbo.
      	 */
      	public static final String ALL_DUBBO_SERVICES = "*";
          
          // 这里是默认为*,如果set方法没有执行,那么get时候获得的就是*
          private String subscribedServices = ALL_DUBBO_SERVICES;
          
          /* ... */
          
      }
      
    #### **现在测试一下输出那个东西,启动一个提供者,然后消费者订阅的提供者写成`*`或者注释掉。启动消费者。**
    
    查看日志:
    
    ```txt
    2021-05-27 16:28:24.950  WARN 6564 --- [client.listener] a.c.d.m.r.DubboServiceMetadataRepository : Current application will subscribe all services(size:20) in registry, a lot of memory and CPU cycles may be used, thus it's strongly recommend you using the externalized property 'dubbo.cloud.subscribed-services' to specify the services
    ```
    
    与步骤8中一致。
    
    1. 接着读else,如果我们填入内容了,就subscribedServices()后加入到那个集合中

      newSubscribedServices.addAll(dubboCloudProperties.subscribedServices());
      

      ctrl点subscribedServices(),然后发现又转到第一个文件了:

      转回来了

      再继续读一下:使用commaDelimitedListToStringArray将我们输入的东西转化了字符串数组,处理返回。

    2. 我们来看看commaDelimitedListToStringArray怎么处理的,找到导入它的地方:

      import static org.springframework.util.StringUtils.commaDelimitedListToStringArray;

      然后ctrl点:

      	/**
      	 * Convert a comma delimited list (e.g., a row from a CSV file) into an
      	 * array of strings.
      	 * @param str the input {@code String} (potentially {@code null} or empty)
      	 * @return an array of strings, or the empty array in case of empty input
      	 */
      	public static String[] commaDelimitedListToStringArray(@Nullable String str) {
      		return delimitedListToStringArray(str, ",");
      	}
      

      这里与标题3.中The multiple value will use comma(",") as the separator.对应。

    3. 结论:

      • 不写或者*会订阅所有的。
      • 写多就使用,隔开。

    泛型接口多种实现方法的提供者上nacos的解决方法。

    参考:Dubbo配合SpringBoot,实现接口多个实现(group)

    yml文件的dubbo部分与平时没有两样

    (这是提供者和消费者都是自己的情况,如果分开就是scanregistry加上面是提供者,cloud加上面的是消费者(不包括scan和registry))

    dubbo:
      consumer:
        retries: 5
      protocol:
        port: -1
        name: dubbo
      scan: #将那个目录下的文件上nacos作为提供者
        base-packages: com.example.service.impl
      registry: #注册中心
        address: nacos://127.0.0.1:8848
      cloud: #订阅提供者
        subscribed-services: my-application
    

    只是在提供者的实现方法1的注解@Service后添加组,代码如下:

    package com.example.service.impl;
    
    import com.alibaba.dubbo.config.annotation.Service;
    
    @Service(group = "service1")
    public class TestServiceOneImpl implements TestService {
        /* ... */
    }
    

    提供者的实现方法2的注解@Service后也添加组,代码如下:

    package com.example.service.impl;
    
    import com.alibaba.dubbo.config.annotation.Service;
    
    @Service(group = "service2")
    public class TestServiceOneImpl implements TestService {
        /* ... */
    }
    

    在消费者端使用时候,同样注解@Reference后面添加组,代码如下:

    package com.example.controller;
    
    import com.alibaba.dubbo.config.annotation.Reference;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class TestController {
    
        @Reference(group = "service1")
        private TestService testServiceOne;
        
        @PostMapping("/test")
        public String testMethod() {
            testServiceOne...
                
            return null;
        }
        
    }
    

    至此就可以指定同接口提供的不同实现类接口了。

    ​ 若接口是泛型定义的,也即不确定参数或者返回类型,那么在定义接口时候使用TestService<T>,实现类可以指定实现类型方式 implements TestService<MyOwnClass>这个泛型接口是与分组不冲突的。


    扩展:

    关于DubboReference和DubboService这两个注解。

    参考:Dubbo整合Spring原理之@Reference和@DubboReference生效机制(3)

  • 相关阅读:
    虚拟机网络配置常见问题总结
    Python
    Python
    Python
    Python
    Python
    Python
    MySQL
    MySQL
    MySQL
  • 原文地址:https://www.cnblogs.com/Ddlm2wxm/p/14818979.html
Copyright © 2020-2023  润新知