zoukankan      html  css  js  c++  java
  • Dubbo源码解析(三)之provider初始化

    dubbo 的服务由 ServiceBean 暴露,ServiceBean的层次结构:

    ServiceBean 实现了 InitializingBean,InitializingBean 接口的作用不必多说,实现了 InitializingBean 的 bean ,Spring 会在填充 bean 的属性之后调用它的 afterPropertiesSet 方法:
    ServiceBean:

    public void afterPropertiesSet() throws Exception {
    // 判断是否解析过 provider 配置,解析过则不再解析
    if (getProvider() == null) {
    // 获取所有 ProviderConfig 类型的 bean
    Map<String, ProviderConfig> providerConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProviderConfig.class, false, false);
    if (providerConfigMap != null && providerConfigMap.size() > 0) {
    // 获取所有 ProtocolConfig 类型的 bean
    Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class, false, false);
    // 向后兼容,判断是否 protocol 为空并且 provider 不为空
    if ((protocolConfigMap == null || protocolConfigMap.size() == 0)
    && providerConfigMap.size() > 1) {
    List<ProviderConfig> providerConfigs = new ArrayList<ProviderConfig>();
    for (ProviderConfig config : providerConfigMap.values()) {
    if (config.isDefault() != null && config.isDefault().booleanValue()) {
    // 添加默认的 ProviderConfig
    providerConfigs.add(config);
    }
    }
    if (providerConfigs.size() > 0) {
    // 将 ProviderConfig 转换为 ProtocolConfig 赋值给 protocols 成员属性
    setProviders(providerConfigs);
    }
    } else {
    ProviderConfig providerConfig = null;
    for (ProviderConfig config : providerConfigMap.values()) {
    if (config.isDefault() == null || config.isDefault().booleanValue()) {
    // 默认的 ProviderConfig 只能有一个
    if (providerConfig != null) {
    throw new IllegalStateException("Duplicate provider configs: " + providerConfig + " and " + config);
    }
    providerConfig = config;
    }
    }
    if (providerConfig != null) {
    // 设置 provider 配置
    setProvider(providerConfig);
    }
    }
    }
    }
    // 判断是否解析过 application 配置,解析过则不再解析
    if (getApplication() == null
    && (getProvider() == null || getProvider().getApplication() == null)) {
    // 获取所有 ApplicationConfig 类型的 bean
    Map<String, ApplicationConfig> applicationConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ApplicationConfig.class, false, false);
    if (applicationConfigMap != null && applicationConfigMap.size() > 0) {
    ApplicationConfig applicationConfig = null;
    for (ApplicationConfig config : applicationConfigMap.values()) {
    if (config.isDefault() == null || config.isDefault().booleanValue()) {
    // 默认的 ApplicationConfig 只能有一个
    if (applicationConfig != null) {
    throw new IllegalStateException("Duplicate application configs: " + applicationConfig + " and " + config);
    }
    applicationConfig = config;
    }
    }
    if (applicationConfig != null) {
    // 设置 application 配置
    setApplication(applicationConfig);
    }
    }
    }
    // 判断是否解析过 module 配置,解析过则不再解析
    if (getModule() == null
    && (getProvider() == null || getProvider().getModule() == null)) {
    // 获取所有 ModuleConfig 类型的 bean
    Map<String, ModuleConfig> moduleConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ModuleConfig.class, false, false);
    if (moduleConfigMap != null && moduleConfigMap.size() > 0) {
    ModuleConfig moduleConfig = null;
    for (ModuleConfig config : moduleConfigMap.values()) {
    if (config.isDefault() == null || config.isDefault().booleanValue()) {
    // 默认的 ModuleConfig 只能有一个
    if (moduleConfig != null) {
    throw new IllegalStateException("Duplicate module configs: " + moduleConfig + " and " + config);
    }
    moduleConfig = config;
    }
    }
    if (moduleConfig != null) {
    // 设置 module 配置
    setModule(moduleConfig);
    }
    }
    }
    // 判断是否解析过 registry 配置,解析过则不再解析
    if ((getRegistries() == null || getRegistries().size() == 0)
    && (getProvider() == null || getProvider().getRegistries() == null || getProvider().getRegistries().size() == 0)
    && (getApplication() == null || getApplication().getRegistries() == null || getApplication().getRegistries().size() == 0)) {
    // 获取所有 RegistryConfig 类型的 bean
    Map<String, RegistryConfig> registryConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RegistryConfig.class, false, false);
    if (registryConfigMap != null && registryConfigMap.size() > 0) {
    List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>();
    for (RegistryConfig config : registryConfigMap.values()) {
    if (config.isDefault() == null || config.isDefault().booleanValue()) {
    // 添加 RegistryConfig 配置
    registryConfigs.add(config);
    }
    }
    if (registryConfigs != null && registryConfigs.size() > 0) {
    // 设置 registry 配置
    super.setRegistries(registryConfigs);
    }
    }
    }
    // 判断是否解析过 monitor 配置,解析过则不再解析
    if (getMonitor() == null
    && (getProvider() == null || getProvider().getMonitor() == null)
    && (getApplication() == null || getApplication().getMonitor() == null)) {
    // 获取所有 MonitorConfig 类型的 bean
    Map<String, MonitorConfig> monitorConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, MonitorConfig.class, false, false);
    if (monitorConfigMap != null && monitorConfigMap.size() > 0) {
    MonitorConfig monitorConfig = null;
    for (MonitorConfig config : monitorConfigMap.values()) {
    if (config.isDefault() == null || config.isDefault().booleanValue()) {
    // 默认的 MonitorConfig 只能有一个
    if (monitorConfig != null) {
    throw new IllegalStateException("Duplicate monitor configs: " + monitorConfig + " and " + config);
    }
    monitorConfig = config;
    }
    }
    if (monitorConfig != null) {
    // 设置 monitor 配置
    setMonitor(monitorConfig);
    }
    }
    }
    // 判断是否解析过 protocol 配置,解析过则不再解析
    if ((getProtocols() == null || getProtocols().size() == 0)
    && (getProvider() == null || getProvider().getProtocols() == null || getProvider().getProtocols().size() == 0)) {
    // 获取所有 ProtocolConfig 类型的bean
    Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class, false, false);
    if (protocolConfigMap != null && protocolConfigMap.size() > 0) {
    List<ProtocolConfig> protocolConfigs = new ArrayList<ProtocolConfig>();
    for (ProtocolConfig config : protocolConfigMap.values()) {
    if (config.isDefault() == null || config.isDefault().booleanValue()) {
    // 添加 ProtocolConfig 配置
    protocolConfigs.add(config);
    }
    }
    if (protocolConfigs != null && protocolConfigs.size() > 0) {
    // 设置 protocol 配置
    super.setProtocols(protocolConfigs);
    }
    }
    }
    // 判断是否解析过 path 配置,解析过则不再解析
    if (getPath() == null || getPath().length() == 0) {
    // interface 就是我们配置的 interface
    if (beanName != null && beanName.length() > 0
    && getInterface() != null && getInterface().length() > 0
    && beanName.startsWith(getInterface())) {
    // 检查 beanName 的格式(长度、正则)并设置为 path
    setPath(beanName);
    }
    }
    if (!isDelay()) {
    /* 没有设置延迟暴露则直接暴露 */
    export();
    }
    }
    ServiceConfig:
    public synchronized void export() {
    if (provider != null) {
    // 确定是否暴露过
    if (export == null) {
    export = provider.getExport();
    }
    // 确定是否延迟暴露
    if (delay == null) {
    delay = provider.getDelay();
    }
    }
    // 暴露过不在暴露
    if (export != null && !export) {
    return;
    }
    // 延迟暴露
    if (delay != null && delay > 0) {
    delayExportExecutor.schedule(new Runnable() {
    public void run() {
    /* 作为 ScheduledExecutorService 的一个作业进行暴露 */
    doExport();
    }
    }, delay, TimeUnit.MILLISECONDS);
    } else {
    /* 暴露 */
    doExport();
    }
    }
    ServiceConfig:
    protected synchronized void doExport() {
    if (unexported) {
    throw new IllegalStateException("Already unexported!");
    }
    // 暴露过直接返回
    if (exported) {
    return;
    }
    exported = true;
    if (interfaceName == null || interfaceName.length() == 0) {
    throw new IllegalStateException("<dubbo:service interface="" /> interface not allow null!");
    }
    /* 检查默认配置 */
    checkDefault();
    // 下面为一些配置成员属性的赋值
    if (provider != null) {
    if (application == null) {
    application = provider.getApplication();
    }
    if (module == null) {
    module = provider.getModule();
    }
    if (registries == null) {
    registries = provider.getRegistries();
    }
    if (monitor == null) {
    monitor = provider.getMonitor();
    }
    if (protocols == null) {
    protocols = provider.getProtocols();
    }
    }
    if (module != null) {
    if (registries == null) {
    registries = module.getRegistries();
    }
    if (monitor == null) {
    monitor = module.getMonitor();
    }
    }
    if (application != null) {
    if (registries == null) {
    registries = application.getRegistries();
    }
    if (monitor == null) {
    monitor = application.getMonitor();
    }
    }
    // 泛化调用判断
    if (ref instanceof GenericService) {
    interfaceClass = GenericService.class;
    if (StringUtils.isEmpty(generic)) {
    generic = Boolean.TRUE.toString();
    }
    } else {
    try {
    interfaceClass = Class.forName(interfaceName, true, Thread.currentThread()
    .getContextClassLoader());
    } catch (ClassNotFoundException e) {
    throw new IllegalStateException(e.getMessage(), e);
    }
    // 检查接口和方法,接口不能为 null 并且必须是 interface,方法必须属于接口
    checkInterfaceAndMethods(interfaceClass, methods);
    // 检查 ref 配置,不能为 null,并且必须是配置的接口的实现类
    checkRef();
    generic = Boolean.FALSE.toString();
    }
    if (local != null) {
    if ("true".equals(local)) {
    local = interfaceName + "Local";
    }
    Class<?> localClass;
    try {
    localClass = ClassHelper.forNameWithThreadContextClassLoader(local);
    } catch (ClassNotFoundException e) {
    throw new IllegalStateException(e.getMessage(), e);
    }
    if (!interfaceClass.isAssignableFrom(localClass)) {
    throw new IllegalStateException("The local implementation class " + localClass.getName() + " not implement interface " + interfaceName);
    }
    }
    if (stub != null) {
    if ("true".equals(stub)) {
    stub = interfaceName + "Stub";
    }
    Class<?> stubClass;
    try {
    stubClass = ClassHelper.forNameWithThreadContextClassLoader(stub);
    } catch (ClassNotFoundException e) {
    throw new IllegalStateException(e.getMessage(), e);
    }
    if (!interfaceClass.isAssignableFrom(stubClass)) {
    throw new IllegalStateException("The stub implementation class " + stubClass.getName() + " not implement interface " + interfaceName);
    }
    }
    /* 检查 application 配置 */
    checkApplication();
    /* 检查 registry 配置 */
    checkRegistry();
    /* 检查 protocol 配置 */
    checkProtocol();
    /* 追加 properties 配置 */
    appendProperties(this);
    /* 检查 stub、mock 配置 */
    checkStubAndMock(interfaceClass);
    if (path == null || path.length() == 0) {
    path = interfaceName;
    }
    /* 暴露 url */
    doExportUrls();
    // 构造 ProviderModel,将服务的方法封装成 ProviderMethodModel 保存到集合中,并将集合与方法名称做映射保存
    ProviderModel providerModel = new ProviderModel(getUniqueServiceName(), this, ref);
    // 获取服务唯一名称,注册到已提供服务列表中
    ApplicationModel.initProviderModel(getUniqueServiceName(), providerModel);
    }
    ServiceConfig:
    private void checkDefault() {
    if (provider == null) {
    provider = new ProviderConfig();
    }
    /* 追加 properties 配置 */
    appendProperties(provider);
    }
    AbstractConfig:
    protected static void appendProperties(AbstractConfig config) {
    if (config == null) {
    return;
    }
    // 获取标签名称(config 名称除去 Config 或 Bean 后缀转成小写,例如 ProviderConfig --> provider、ServiceBean --> service),拼接前缀,eg:ProviderConfig --> dubbo.provider.
    String prefix = "dubbo." + getTagName(config.getClass()) + ".";
    Method[] methods = config.getClass().getMethods();
    for (Method method : methods) {
    try {
    String name = method.getName();
    // 判断 setter 方法访问修饰符为 public 并且参数只有一个且是基本类型(包括包装类型、String 和 Object)
    if (name.length() > 3 && name.startsWith("set") && Modifier.isPublic(method.getModifiers())
    && method.getParameterTypes().length == 1 && isPrimitive(method.getParameterTypes()[0])) {
    // 将 setter 驼峰命名去掉 set 后转成.连接的命名,如 setDumpDirectory --> dump.directory
    String property = StringUtils.camelToSplitName(name.substring(3, 4).toLowerCase() + name.substring(4), ".");
    String value = null;
    if (config.getId() != null && config.getId().length() > 0) {
    // 如果 id 属性不为空,携带 id 拼接 key 尝试从系统属性中获取相关配置
    String pn = prefix + config.getId() + "." + property;
    value = System.getProperty(pn);
    if (!StringUtils.isBlank(value)) {
    logger.info("Use System Property " + pn + " to config dubbo");
    }
    }
    if (value == null || value.length() == 0) {
    // 如果 id 属性为空,不带 id 拼接 key 尝试从系统属性中获取相关配置
    String pn = prefix + property;
    value = System.getProperty(pn);
    if (!StringUtils.isBlank(value)) {
    logger.info("Use System Property " + pn + " to config dubbo");
    }
    }
    if (value == null || value.length() == 0) {
    Method getter;
    try {
    // 如果从系统属性中没有获取到配置,则尝试获取响应 getter 方法
    getter = config.getClass().getMethod("get" + name.substring(3), new Class<?>[0]);
    } catch (NoSuchMethodException e) {
    try {
    // boolean 类型的属性的 getter 方法可能以 is 开头
    getter = config.getClass().getMethod("is" + name.substring(3), new Class<?>[0]);
    } catch (NoSuchMethodException e2) {
    getter = null;
    }
    }
    if (getter != null) {
    // 判断调用 getter 方法的返回值是否为 null
    if (getter.invoke(config, new Object[0]) == null) {
    if (config.getId() != null && config.getId().length() > 0) {
    /* 如果 id 属性不为空,携带 id 拼接 key 尝试获取相关配置 */
    value = ConfigUtils.getProperty(prefix + config.getId() + "." + property);
    }
    if (value == null || value.length() == 0) {
    /* 如果 value 为空,不带 id 拼接 key 尝试获取相关配置 */
    value = ConfigUtils.getProperty(prefix + property);
    }
    if (value == null || value.length() == 0) {
    // 从预制的 key 映射中获取 key
    String legacyKey = legacyProperties.get(prefix + property);
    if (legacyKey != null && legacyKey.length() > 0) {
    /* 尝试获取配置并转换(dubbo.service.max.retry.providers 和dubbo.service.allow.no.provider 两个配置需要转换) */
    value = convertLegacyValue(legacyKey, ConfigUtils.getProperty(legacyKey));
    }
    }
    }
    }
    }
    if (value != null && value.length() > 0) {
    // 如果到这里 value 不为空,则调用 setter 方法为属性赋值
    method.invoke(config, new Object[]{convertPrimitive(method.getParameterTypes()[0], value)});
    }
    }
    } catch (Exception e) {
    logger.error(e.getMessage(), e);
    }
    }
    }
    ConfigUtils:
    public static String getProperty(String key) {
    /* 获取配置 */
    return getProperty(key, null);
    }
    ConfigUtils:
    public static String getProperty(String key, String defaultValue) {
    String value = System.getProperty(key);
    if (value != null && value.length() > 0) {
    return value;
    }
    /* 获取 properties 配置 */
    Properties properties = getProperties();
    /* 将$和${}表达式替换为对应配置 */
    return replaceProperty(properties.getProperty(key, defaultValue), (Map) properties);
    }
    ConfigUtils:
    public static String replaceProperty(String expression, Map<String, String> params) {
    // 表达式不含$忽略
    if (expression == null || expression.length() == 0 || expression.indexOf('$') < 0) {
    return expression;
    }
    // 正则为$s*{?s*([._0-9a-zA-Z]+)s*}?
    Matcher matcher = VARIABLE_PATTERN.matcher(expression);
    StringBuffer sb = new StringBuffer();
    while (matcher.find()) {
    String key = matcher.group(1);
    // 首先尝试从系统属性中获取
    String value = System.getProperty(key);
    if (value == null && params != null) {
    // 没有再尝试从 properties 中获取
    value = params.get(key);
    }
    if (value == null) {
    value = "";
    }
    // 替换表达式为配置值
    matcher.appendReplacement(sb, Matcher.quoteReplacement(value));
    }
    matcher.appendTail(sb);
    return sb.toString();
    }
    AbstractInterfaceConfig:
    protected void checkApplication() {
    // 向后兼容
    if (application == null) {
    // 没有 application 配置则尝试从系统属性中获取
    String applicationName = ConfigUtils.getProperty("dubbo.application.name");
    if (applicationName != null && applicationName.length() > 0) {
    application = new ApplicationConfig();
    }
    }
    // 没有配置 <dubbo:application/> 并且系统属性中也没有,则抛出异常
    if (application == null) {
    throw new IllegalStateException(
    "No such application config! Please add <dubbo:application name="..." /> to your spring config.");
    }
    // 追加配置
    appendProperties(application);
    // 如果配置了 shutdown wait,设置到系统属性中
    String wait = ConfigUtils.getProperty(Constants.SHUTDOWN_WAIT_KEY);
    if (wait != null && wait.trim().length() > 0) {
    System.setProperty(Constants.SHUTDOWN_WAIT_KEY, wait.trim());
    } else {
    wait = ConfigUtils.getProperty(Constants.SHUTDOWN_WAIT_SECONDS_KEY);
    if (wait != null && wait.trim().length() > 0) {
    System.setProperty(Constants.SHUTDOWN_WAIT_SECONDS_KEY, wait.trim());
    }
    }
    }
    AbstractInterfaceConfig:
    protected void checkRegistry() {
    // 向后兼容
    if (registries == null || registries.size() == 0) {
    // 获取 registry 配置
    String address = ConfigUtils.getProperty("dubbo.registry.address");
    if (address != null && address.length() > 0) {
    registries = new ArrayList<RegistryConfig>();
    String[] as = address.split("\s*[|]+\s*");
    for (String a : as) {
    RegistryConfig registryConfig = new RegistryConfig();
    registryConfig.setAddress(a);
    // 有相关配置,增加到集合中
    registries.add(registryConfig);
    }
    }
    }
    // registry 不能为空
    if ((registries == null || registries.size() == 0)) {
    throw new IllegalStateException((getClass().getSimpleName().startsWith("Reference")
    ? "No such any registry to refer service in consumer "
    : "No such any registry to export service in provider ")
    + NetUtils.getLocalHost()
    + " use dubbo version "
    + Version.getVersion()
    + ", Please add <dubbo:registry address="..." /> to your spring config. If you want unregister, please set <dubbo:service registry="N/A" />");
    }
    for (RegistryConfig registryConfig : registries) {
    // 追加配置
    appendProperties(registryConfig);
    }
    }
    ServiceConfig:
    private void checkProtocol() {
    if ((protocols == null || protocols.size() == 0)
    && provider != null) {
    setProtocols(provider.getProtocols());
    }
    // 向后兼容
    if (protocols == null || protocols.size() == 0) {
    setProtocol(new ProtocolConfig());
    }
    for (ProtocolConfig protocolConfig : protocols) {
    if (StringUtils.isEmpty(protocolConfig.getName())) {
    protocolConfig.setName("dubbo");
    }
    // 追加配置
    appendProperties(protocolConfig);
    }
    }
    AbstractInterfaceConfig:
    protected void checkStubAndMock(Class<?> interfaceClass) {
    if (ConfigUtils.isNotEmpty(local)) {
    // 缺省类名,即:接口名 + Local 后缀
    Class<?> localClass = ConfigUtils.isDefault(local) ? ReflectUtils.forName(interfaceClass.getName() + "Local") : ReflectUtils.forName(local);
    // 必须实现服务接口
    if (!interfaceClass.isAssignableFrom(localClass)) {
    throw new IllegalStateException("The local implementation class " + localClass.getName() + " not implement interface " + interfaceClass.getName());
    }
    try {
    // 构造函数必须允许传入服务对象
    ReflectUtils.findConstructor(localClass, interfaceClass);
    } catch (NoSuchMethodException e) {
    throw new IllegalStateException("No such constructor "public " + localClass.getSimpleName() + "(" + interfaceClass.getName() + ")" in local implementation class " + localClass.getName());
    }
    }
    if (ConfigUtils.isNotEmpty(stub)) {
    // 缺省类名,即:接口名 + Stub 后缀
    Class<?> localClass = ConfigUtils.isDefault(stub) ? ReflectUtils.forName(interfaceClass.getName() + "Stub") : ReflectUtils.forName(stub);
    // 必须实现服务接口
    if (!interfaceClass.isAssignableFrom(localClass)) {
    throw new IllegalStateException("The local implementation class " + localClass.getName() + " not implement interface " + interfaceClass.getName());
    }
    try {
    // 构造函数必须允许传入服务对象
    ReflectUtils.findConstructor(localClass, interfaceClass);
    } catch (NoSuchMethodException e) {
    throw new IllegalStateException("No such constructor "public " + localClass.getSimpleName() + "(" + interfaceClass.getName() + ")" in local implementation class " + localClass.getName());
    }
    }
    if (ConfigUtils.isNotEmpty(mock)) {
    if (mock.startsWith(Constants.RETURN_PREFIX)) {
    String value = mock.substring(Constants.RETURN_PREFIX.length());
    try {
    // 如果是 return 作为前缀,则解析mock的值(值可以为 empty、null、true、false、json 字符串等)
    MockInvoker.parseMockValue(value);
    } catch (Exception e) {
    throw new IllegalStateException("Illegal mock json value in <dubbo:service ... mock="" + mock + "" />");
    }
    } else {
    // 缺省类名,即:接口名 + Mock 后缀
    Class<?> mockClass = ConfigUtils.isDefault(mock) ? ReflectUtils.forName(interfaceClass.getName() + "Mock") : ReflectUtils.forName(mock);
    // 必须实现服务接口
    if (!interfaceClass.isAssignableFrom(mockClass)) {
    throw new IllegalStateException("The mock implementation class " + mockClass.getName() + " not implement interface " + interfaceClass.getName());
    }
    try {
    // 需要有无参构造函数
    mockClass.getConstructor(new Class<?>[0]);
    } catch (NoSuchMethodException e) {
    throw new IllegalStateException("No such empty constructor "public " + mockClass.getSimpleName() + "()" in mock implementation class " + mockClass.getName());
    }
    }
    }
    }
    ServiceConfig:
    private void doExportUrls() {
    /* 加载注册中心配置 */
    List<URL> registryURLs = loadRegistries(true);
    for (ProtocolConfig protocolConfig : protocols) {
    /* 为每个协议暴露服务 */
    doExportUrlsFor1Protocol(protocolConfig, registryURLs);
    }
    }
    AbstractInterfaceConfig:
    protected List<URL> loadRegistries(boolean provider) {
    /* 检查 registry 配置 */
    checkRegistry();
    List<URL> registryList = new ArrayList<URL>();
    if (registries != null && registries.size() > 0) {
    for (RegistryConfig config : registries) {
    String address = config.getAddress();
    if (address == null || address.length() == 0) {
    // 0.0.0.0
    address = Constants.ANYHOST_VALUE;
    }
    // 获取系统属性的注册中心地址配置
    String sysaddress = System.getProperty("dubbo.registry.address");
    if (sysaddress != null && sysaddress.length() > 0) {
    address = sysaddress;
    }
    if (address != null && address.length() > 0
    && !RegistryConfig.NO_AVAILABLE.equalsIgnoreCase(address)) {
    Map<String, String> map = new HashMap<String, String>();
    /* 追加参数 */
    appendParameters(map, application);
    /* 追加参数 */
    appendParameters(map, config);
    map.put("path", RegistryService.class.getName());
    map.put("dubbo", Version.getVersion());
    map.put(Constants.TIMESTAMP_KEY, String.valueOf(System.currentTimeMillis()));
    if (ConfigUtils.getPid() > 0) {
    // 尝试通过 java API 获取进程 id 并记录
    map.put(Constants.PID_KEY, String.valueOf(ConfigUtils.getPid()));
    }
    if (!map.containsKey("protocol")) {
    // 判断是否有 remote 扩展,这里涉及到 dubbo SPI 的内容,我们会用单独的文章进行分析
    if (ExtensionLoader.getExtensionLoader(RegistryFactory.class).hasExtension("remote")) {
    map.put("protocol", "remote");
    } else {
    map.put("protocol", "dubbo");
    }
    }
    /* 解析 URL */
    List<URL> urls = UrlUtils.parseURLs(address, map);
    for (URL url : urls) {
    url = url.addParameter(Constants.REGISTRY_KEY, url.getProtocol());
    url = url.setProtocol(Constants.REGISTRY_PROTOCOL);
    if ((provider && url.getParameter(Constants.REGISTER_KEY, true))
    || (!provider && url.getParameter(Constants.SUBSCRIBE_KEY, true))) {
    // 添加注册中心地址
    registryList.add(url);
    }
    }
    }
    }
    }
    return registryList;
    }
    AbstractConfig:
    protected static void appendParameters(Map<String, String> parameters, Object config) {
    /* 追加参数 */
    appendParameters(parameters, config, null);
    }
    AbstractConfig:
    protected static void appendParameters(Map<String, String> parameters, Object config, String prefix) {
    if (config == null) {
    return;
    }
    Method[] methods = config.getClass().getMethods();
    for (Method method : methods) {
    try {
    String name = method.getName();
    // getter 方法,过滤掉 getClass 方法,public 修饰符并且没有参数并且返回值为基本类型(包括 String、包装类和 Object)
    if ((name.startsWith("get") || name.startsWith("is"))
    && !"getClass".equals(name)
    && Modifier.isPublic(method.getModifiers())
    && method.getParameterTypes().length == 0
    && isPrimitive(method.getReturnType())) {
    Parameter parameter = method.getAnnotation(Parameter.class);
    // 忽略返回值类型为 Object 或注解 excluded 属性设置为 true 的 getter 方法
    if (method.getReturnType() == Object.class || parameter != null && parameter.excluded()) {
    continue;
    }
    int i = name.startsWith("get") ? 3 : 2;
    // 将 getter 驼峰命名去掉 get 或 is 后转成.连接的命名,如 getDumpDirectory --> dump.directory
    String prop = StringUtils.camelToSplitName(name.substring(i, i + 1).toLowerCase() + name.substring(i + 1), ".");
    String key;
    // 确定 key 的值,注解的 key 属性值优先
    if (parameter != null && parameter.key() != null && parameter.key().length() > 0) {
    key = parameter.key();
    } else {
    key = prop;
    }
    // 执行 getter 方法获取返回值
    Object value = method.invoke(config, new Object[0]);
    String str = String.valueOf(value).trim();
    if (value != null && str.length() > 0) {
    if (parameter != null && parameter.escaped()) {
    // URL 编码
    str = URL.encode(str);
    }
    if (parameter != null && parameter.append()) {
    // 注解设置了追加属性,则追加前缀
    String pre = (String) parameters.get(Constants.DEFAULT_KEY + "." + key);
    if (pre != null && pre.length() > 0) {
    str = pre + "," + str;
    }
    pre = (String) parameters.get(key);
    if (pre != null && pre.length() > 0) {
    str = pre + "," + str;
    }
    }
    if (prefix != null && prefix.length() > 0) {
    key = prefix + "." + key;
    }
    // 设置参数映射
    parameters.put(key, str);
    } else if (parameter != null && parameter.required()) {
    throw new IllegalStateException(config.getClass().getSimpleName() + "." + key + " == null");
    }
    // getParameters 方法
    } else if ("getParameters".equals(name)
    && Modifier.isPublic(method.getModifiers())
    && method.getParameterTypes().length == 0
    && method.getReturnType() == Map.class) {
    // 执行方法获取返回值
    Map<String, String> map = (Map<String, String>) method.invoke(config, new Object[0]);
    if (map != null && map.size() > 0) {
    String pre = (prefix != null && prefix.length() > 0 ? prefix + "." : "");
    for (Map.Entry<String, String> entry : map.entrySet()) {
    // 将 key 的-替换为.并追加指定的前缀,重新设置参数映射
    parameters.put(pre + entry.getKey().replace('-', '.'), entry.getValue());
    }
    }
    }
    } catch (Exception e) {
    throw new IllegalStateException(e.getMessage(), e);
    }
    }
    }
    UrlUtils:
    public static List<URL> parseURLs(String address, Map<String, String> defaults) {
    if (address == null || address.length() == 0) {
    return null;
    }
    // 分割地址
    String[] addresses = Constants.REGISTRY_SPLIT_PATTERN.split(address);
    if (addresses == null || addresses.length == 0) {
    return null;
    }
    List<URL> registries = new ArrayList<URL>();
    for (String addr : addresses) {
    registries.add(parseURL(addr, defaults));
    }
    return registries;
    }
    UrlUtils:
    public static URL parseURL(String address, Map<String, String> defaults) {
    if (address == null || address.length() == 0) {
    return null;
    }
    String url;
    if (address.indexOf(":// ") >= 0) {
    url = address;
    } else {
    String[] addresses = Constants.COMMA_SPLIT_PATTERN.split(address);
    url = addresses[0];
    if (addresses.length > 1) {
    StringBuilder backup = new StringBuilder();
    for (int i = 1; i < addresses.length; i++) {
    if (i > 1) {
    backup.append(",");
    }
    backup.append(addresses[i]);
    }
    // 设置 backup,如192.168.1.1,192.168.1.2 --> 192.168.1.1?backup=192.168.1.2
    url += "?" + Constants.BACKUP_KEY + "=" + backup.toString();
    }
    }
    String defaultProtocol = defaults == null ? null : defaults.get("protocol");
    if (defaultProtocol == null || defaultProtocol.length() == 0) {
    // 默认协议为 dubbo
    defaultProtocol = "dubbo";
    }
    // 获取一些默认配置
    String defaultUsername = defaults == null ? null : defaults.get("username");
    String defaultPassword = defaults == null ? null : defaults.get("password");
    int defaultPort = StringUtils.parseInteger(defaults == null ? null : defaults.get("port"));
    String defaultPath = defaults == null ? null : defaults.get("path");
    Map<String, String> defaultParameters = defaults == null ? null : new HashMap<String, String>(defaults);
    if (defaultParameters != null) {
    defaultParameters.remove("protocol");
    defaultParameters.remove("username");
    defaultParameters.remove("password");
    defaultParameters.remove("host");
    defaultParameters.remove("port");
    defaultParameters.remove("path");
    }
    // 将 url 解析成 URL 对象
    URL u = URL.valueOf(url);
    boolean changed = false;
    String protocol = u.getProtocol();
    String username = u.getUsername();
    String password = u.getPassword();
    String host = u.getHost();
    int port = u.getPort();
    String path = u.getPath();
    Map<String, String> parameters = new HashMap<String, String>(u.getParameters());
    // 判断几个属性的值是否为空,如果为空赋为默认值
    if ((protocol == null || protocol.length() == 0) && defaultProtocol != null && defaultProtocol.length() > 0) {
    changed = true;
    protocol = defaultProtocol;
    }
    if ((username == null || username.length() == 0) && defaultUsername != null && defaultUsername.length() > 0) {
    changed = true;
    username = defaultUsername;
    }
    if ((password == null || password.length() == 0) && defaultPassword != null && defaultPassword.length() > 0) {
    changed = true;
    password = defaultPassword;
    }
    if (port <= 0) {
    if (defaultPort > 0) {
    changed = true;
    port = defaultPort;
    } else {
    changed = true;
    port = 9090;
    }
    }
    if (path == null || path.length() == 0) {
    if (defaultPath != null && defaultPath.length() > 0) {
    changed = true;
    path = defaultPath;
    }
    }
    if (defaultParameters != null && defaultParameters.size() > 0) {
    for (Map.Entry<String, String> entry : defaultParameters.entrySet()) {
    String key = entry.getKey();
    String defaultValue = entry.getValue();
    if (defaultValue != null && defaultValue.length() > 0) {
    String value = parameters.get(key);
    if (value == null || value.length() == 0) {
    changed = true;
    parameters.put(key, defaultValue);
    }
    }
    }
    }
    if (changed) {
    // 如果属性值有改变,则用新的属性值构建新的 URL 对象
    u = new URL(protocol, username, password, host, port, path, parameters);
    }
    return u;
    }
    到这里,整个 dubbo provider 初始化的源码分析就完成了。
  • 相关阅读:
    Kafka:ZK+Kafka+Spark Streaming集群环境搭建(二十六)Structured Streaming:WARN clients.NetworkClient: Error while fetching metadata with correlation id 1 : {my-topic=LEADER_NOT_AVAILABLE}
    Kafka:ZK+Kafka+Spark Streaming集群环境搭建(二十五)Structured Streaming:同一个topic中包含一组数据的多个部分,按照key它们拼接为一条记录(以及遇到的问题)。
    Kafka:ZK+Kafka+Spark Streaming集群环境搭建(二十四)Structured Streaming:Encoder
    Kafka:ZK+Kafka+Spark Streaming集群环境搭建(二十三)Structured Streaming遇到问题:Set(TopicName-0) are gone. Some data may have been missed
    Structured Streaming编程向导
    Kafka:ZK+Kafka+Spark Streaming集群环境搭建(二十二)Spark Streaming接收流数据及使用窗口函数
    Linux:磁盘挂载
    Kafka:ZK+Kafka+Spark Streaming集群环境搭建(二十一)NIFI1.7.1安装
    Spark参数设置的方式
    mydumper安装、原理介绍
  • 原文地址:https://www.cnblogs.com/lanblogs/p/15262458.html
Copyright © 2011-2022 走看看