<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> I have searched the <a href="https://github.com/apache/dubbo/issues">issues</a> of this repository and believe that this is not a duplicate.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> I have checked the <a href="https://github.com/apache/dubbo/blob/master/FAQ.md">FAQ</a> of this repository and believe that this is not a duplicate.</li>
</ul>
<h3 dir="auto">Environment</h3>
<ul dir="auto">
<li>Dubbo version: 2.7.4-SNAPSHOT</li>
<li>Operating System version: MacOS</li>
<li>Java version: java11</li>
</ul>
<h3 dir="auto">Steps to reproduce this issue</h3>
<ol dir="auto">
<li>Config reference like</li>
</ol>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="    @Reference(id = &quot;referenceId1&quot; , methods = {@Method(name = METHOD, timeout = 7000, arguments = @Argument(index = 0))})
    private DemoService demoService;"><pre class="notranslate">    <span class="pl-c1">@</span><span class="pl-c1">Reference</span>(<span class="pl-s1">id</span> = <span class="pl-s">"referenceId1"</span> , <span class="pl-s1">methods</span> = {<span class="pl-c1">@</span><span class="pl-c1">Method</span>(<span class="pl-s1">name</span> = <span class="pl-c1">METHOD</span>, <span class="pl-s1">timeout</span> = <span class="pl-c1">7000</span>, <span class="pl-s1">arguments</span> = <span class="pl-c1">@</span><span class="pl-c1">Argument</span>(<span class="pl-s1">index</span> = <span class="pl-c1">0</span>))})
    <span class="pl-k">private</span> <span class="pl-smi">DemoService</span> <span class="pl-s1">demoService</span>;</pre></div>
<ol start="2" dir="auto">
<li>debug the application, observe if the methods config works</li>
</ol>
<h3 dir="auto">Expected Result</h3>
<p dir="auto">the methods config works</p>
<h3 dir="auto">Actual Result</h3>
<p dir="auto">the methods config doesn't work</p>
<p dir="auto">If there is an exception, please attach the exception trace:</p>
<p dir="auto">I find that it seems the code following generate the effect</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="package org.apache.dubbo.config.spring.util;

public class AnnotationUtils {"><pre class="notranslate"><span class="pl-k">package</span> <span class="pl-s1">org</span>.<span class="pl-s1">apache</span>.<span class="pl-s1">dubbo</span>.<span class="pl-s1">config</span>.<span class="pl-s1">spring</span>.<span class="pl-s1">util</span>;

<span class="pl-k">public</span> <span class="pl-k">class</span> <span class="pl-smi">AnnotationUtils</span> {</pre></div>
<p dir="auto">in the method public static Map&lt;String, Object&gt; getAttributes(Annotation annotation, PropertyResolver propertyResolver, boolean ignoreDefaultValue, String... ignoreAttributeNames)</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="            if (attributeValue.getClass().isAnnotation()) {
                continue;
            }
            if (attributeValue.getClass().isArray() &amp;&amp; attributeValue.getClass().getComponentType().isAnnotation()) {
                continue;
            }"><pre class="notranslate">            <span class="pl-k">if</span> (<span class="pl-s1">attributeValue</span>.<span class="pl-en">getClass</span>().<span class="pl-en">isAnnotation</span>()) {
                <span class="pl-k">continue</span>;
            }
            <span class="pl-k">if</span> (<span class="pl-s1">attributeValue</span>.<span class="pl-en">getClass</span>().<span class="pl-en">isArray</span>() &amp;&amp; <span class="pl-s1">attributeValue</span>.<span class="pl-en">getClass</span>().<span class="pl-en">getComponentType</span>().<span class="pl-en">isAnnotation</span>()) {
                <span class="pl-k">continue</span>;
            }</pre></div>
<p dir="auto">Should we delete these code ?</p>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have searched the <a href="https://github.com/apache/dubbo/issues">issues</a> of this repository and believe that this is not a duplicate.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> I have checked the <a href="https://github.com/apache/dubbo/blob/master/FAQ.md">FAQ</a> of this repository and believe that this is not a duplicate.</li>
</ul>
<p dir="auto">All problem already resolve by Dubbo SPI on my framework, but I think I should share those problems and the reason why those problems come up.</p>
<p dir="auto">Please Dubbo team fix those issue for good.</p>
<h3 dir="auto">Environment</h3>
<ul dir="auto">
<li>Dubbo version: Dubbo 2.7.5</li>
<li>Operating System version: MacOS</li>
<li>Java version: Oracle JDK 8</li>
</ul>
<p dir="auto">Finally I back to the Vertion 2.7.4.1, And This is all issue of the Dubbo 2.7.5 I found:</p>
<ul dir="auto">
<li>
<p dir="auto"><strong>Failure due to the Dubbo starting early</strong>. This is my environment:</p>
<ul dir="auto">
<li>Dubbo 2.7.5 + Nacos 1.1.4</li>
<li>Use Dynamic Config Center</li>
<li>Spring boot 2.1.9</li>
<li>Use YAML Config</li>
</ul>
<p dir="auto">In this case, the Dubbo will be startup before the  <code class="notranslate">ConfigCenterConfig</code> inject into <code class="notranslate">DubboBootstrap</code>, it make Dubbo use default config and starting failure. And the reason of the Dubbo startup is <strong>Spring framework scan Dubbo Service Interface and initial it, and the Dubbo Service Interface active the Dubbo framework</strong>. the Dubbo framework not even get the <code class="notranslate">ConfigCenterConfig</code> at that time.</p>
<p dir="auto">After reading the Dubbo source code, I found some key code in the class <code class="notranslate">DubboBootstrap</code>, method name <code class="notranslate">startConfigCenter</code>, line 560.</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// Get the class &quot;ConfigCenterConfig&quot;
Collection&lt;ConfigCenterConfig&gt; configCenters = configManager.getConfigCenters();

if (CollectionUtils.isNotEmpty(configCenters)) {
  CompositeDynamicConfiguration compositeDynamicConfiguration = new CompositeDynamicConfiguration();
  for (ConfigCenterConfig configCenter : configCenters) {
    configCenter.refresh();
    ConfigValidationUtils.validateConfigCenterConfig(configCenter);
  
    // The method &quot;prepareEnvironment&quot; get all dubbo config from remote server
    compositeDynamicConfiguration.addConfiguration(prepareEnvironment(configCenter));
  }
  environment.setDynamicConfiguration(compositeDynamicConfiguration);
}
configManager.refreshAll();"><pre class="notranslate"><span class="pl-c">// Get the class "ConfigCenterConfig"</span>
<span class="pl-smi">Collection</span>&lt;<span class="pl-smi">ConfigCenterConfig</span>&gt; <span class="pl-s1">configCenters</span> = <span class="pl-s1">configManager</span>.<span class="pl-en">getConfigCenters</span>();

<span class="pl-k">if</span> (<span class="pl-smi">CollectionUtils</span>.<span class="pl-en">isNotEmpty</span>(<span class="pl-s1">configCenters</span>)) {
  <span class="pl-smi">CompositeDynamicConfiguration</span> <span class="pl-s1">compositeDynamicConfiguration</span> = <span class="pl-k">new</span> <span class="pl-smi">CompositeDynamicConfiguration</span>();
  <span class="pl-k">for</span> (<span class="pl-smi">ConfigCenterConfig</span> <span class="pl-s1">configCenter</span> : <span class="pl-s1">configCenters</span>) {
    <span class="pl-s1">configCenter</span>.<span class="pl-en">refresh</span>();
    <span class="pl-smi">ConfigValidationUtils</span>.<span class="pl-en">validateConfigCenterConfig</span>(<span class="pl-s1">configCenter</span>);
  
    <span class="pl-c">// The method "prepareEnvironment" get all dubbo config from remote server</span>
    <span class="pl-s1">compositeDynamicConfiguration</span>.<span class="pl-en">addConfiguration</span>(<span class="pl-en">prepareEnvironment</span>(<span class="pl-s1">configCenter</span>));
  }
  <span class="pl-s1">environment</span>.<span class="pl-en">setDynamicConfiguration</span>(<span class="pl-s1">compositeDynamicConfiguration</span>);
}
<span class="pl-s1">configManager</span>.<span class="pl-en">refreshAll</span>();</pre></div>
<p dir="auto">And this is the code I use to fix that problem( This code can not fix the problem in some case because it still depend on the order of the Bean initialize in Spring framework, that is the reason why I specified name at <code class="notranslate">@Configuration</code>. for the <code class="notranslate">@DependOn</code>  ):</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="@Order(-1)
@AllArgsConstructor
@Configuration(&quot;apacheDubboBootstrap&quot;)
@ConditionalOnClass(name = &quot;org.apache.dubbo.config.ConfigCenterConfig&quot;)
public static class ApacheDubboBootstrap {

  private final DynamicConfigProperties properties;
    
  @PostConstruct
  public void init() {
    // 在 Spring boot 环境下由于 Dubbo 接口的代理类创建间接触发了 Dubbo 框架流程
    // 这一行代码是为了解决启动优先级的问题, 在触发 Dubbo 框架流程之前注入动态配置中心配置
    // 而依赖 Spring boot 进行注入有可能会因为 Dubbo 先启动而不知道存在配置中心导致启动失败
    DubboBootstrap.getInstance().configCenter(properties.ofConfigCenterConfig());
  }
}"><pre class="notranslate"><span class="pl-c1">@</span><span class="pl-c1">Order</span>(-<span class="pl-c1">1</span>)
<span class="pl-c1">@</span><span class="pl-c1">AllArgsConstructor</span>
<span class="pl-c1">@</span><span class="pl-c1">Configuration</span>(<span class="pl-s">"apacheDubboBootstrap"</span>)
<span class="pl-c1">@</span><span class="pl-c1">ConditionalOnClass</span>(<span class="pl-s1">name</span> = <span class="pl-s">"org.apache.dubbo.config.ConfigCenterConfig"</span>)
<span class="pl-k">public</span> <span class="pl-k">static</span> <span class="pl-k">class</span> <span class="pl-smi">ApacheDubboBootstrap</span> {

  <span class="pl-k">private</span> <span class="pl-k">final</span> <span class="pl-smi">DynamicConfigProperties</span> <span class="pl-s1">properties</span>;
    
  <span class="pl-c1">@</span><span class="pl-c1">PostConstruct</span>
  <span class="pl-k">public</span> <span class="pl-smi">void</span> <span class="pl-en">init</span>() {
    <span class="pl-c">// 在 Spring boot 环境下由于 Dubbo 接口的代理类创建间接触发了 Dubbo 框架流程</span>
    <span class="pl-c">// 这一行代码是为了解决启动优先级的问题, 在触发 Dubbo 框架流程之前注入动态配置中心配置</span>
    <span class="pl-c">// 而依赖 Spring boot 进行注入有可能会因为 Dubbo 先启动而不知道存在配置中心导致启动失败</span>
    <span class="pl-smi">DubboBootstrap</span>.<span class="pl-en">getInstance</span>().<span class="pl-en">configCenter</span>(<span class="pl-s1">properties</span>.<span class="pl-en">ofConfigCenterConfig</span>());
  }
}</pre></div>
</li>
<li>
<p dir="auto"><strong>Not friendly with the YAML config</strong></p>
<p dir="auto">For the history reason, the Dubbo framework use XML as config foramt at early, then Properties come up. And now I found that the Dubbo not identify and not inject the YAML config, only XML and Properties can.</p>
<h6 dir="auto">For example, This is the qos server config in YAML:</h6>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Wrong config
# This config ( just qos-enable ) problem seem like fixed in Dubbo 2.7.5 ? But I haven't verified yet
dubbo:
  application:
    qos-enable: true
    
# Correct config
dubbo:
  application:
    qos.enable: true"><pre class="notranslate"><span class="pl-c"><span class="pl-c">#</span> Wrong config</span>
<span class="pl-c"><span class="pl-c">#</span> This config ( just qos-enable ) problem seem like fixed in Dubbo 2.7.5 ? But I haven't verified yet</span>
<span class="pl-ent">dubbo</span>:
  <span class="pl-ent">application</span>:
    <span class="pl-ent">qos-enable</span>: <span class="pl-c1">true</span>
    
<span class="pl-c"><span class="pl-c">#</span> Correct config</span>
<span class="pl-ent">dubbo</span>:
  <span class="pl-ent">application</span>:
    <span class="pl-ent">qos.enable</span>: <span class="pl-c1">true</span></pre></div>
<p dir="auto">If you run Dubbo as debug mode and put some breakpoint in the class <code class="notranslate">ApplicationConfig</code>, you can see the method <code class="notranslate">setQosEnable</code> only be called when you write <code class="notranslate">qos.enable</code> . And what about <code class="notranslate">qos-enable</code> ? Just nothing happen.</p>
<h6 dir="auto">And other example, The <code class="notranslate">ConfigCenterConfig</code>:</h6>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="dubbo:
  config-center:
    address: nacos://xxxx
    config-file: xxxxxx
    group: xxxxxx
    namespace: xxxxxx"><pre class="notranslate"><span class="pl-ent">dubbo</span>:
  <span class="pl-ent">config-center</span>:
    <span class="pl-ent">address</span>: <span class="pl-s">nacos://xxxx</span>
    <span class="pl-ent">config-file</span>: <span class="pl-s">xxxxxx</span>
    <span class="pl-ent">group</span>: <span class="pl-s">xxxxxx</span>
    <span class="pl-ent">namespace</span>: <span class="pl-s">xxxxxx</span></pre></div>
<p dir="auto">Only <code class="notranslate">address</code> is effective in those configs( The method <code class="notranslate">setAddress</code> has been called ) and other config still keep that default value( Nothing happen on the setter of those property ). So that I have to write my configuration and use it config Dubbo:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="public class DynamicConfigProperties {
  public static final String PREFIX = &quot;dubbo.config-server&quot;;

    /**
     * Nacos 服务 Ip 地址
     */
    private String serverAddr;
  
  // some property...
  
  public org.apache.dubbo.config.ConfigCenterConfig ofConfigCenterConfig() {
    org.apache.dubbo.config.ConfigCenterConfig config = new ConfigCenterConfig();

    Map&lt;String, String&gt; parameters = new HashMap&lt;&gt;(4);

    setParameter(parameters, PropertyKeyConst.ACCESS_KEY, accessKey);
    setParameter(parameters, PropertyKeyConst.SECRET_KEY, secretKey);
    setParameter(parameters, PropertyKeyConst.ENDPOINT, endpoint);

    config.setParameters(parameters);

    config.setHighestPriority(allowOverride);
    config.setNamespace(namespace);
    config.setAddress(serverAddr);
    config.setConfigFile(dataId);
    config.setCheck(abortOnFail);
    config.setTimeout(timeout);
    config.setGroup(group);

    return config;
  }
}"><pre class="notranslate"><span class="pl-k">public</span> <span class="pl-k">class</span> <span class="pl-smi">DynamicConfigProperties</span> {
  <span class="pl-k">public</span> <span class="pl-k">static</span> <span class="pl-k">final</span> <span class="pl-smi">String</span> <span class="pl-c1">PREFIX</span> = <span class="pl-s">"dubbo.config-server"</span>;

    <span class="pl-c">/**</span>
<span class="pl-c">     * Nacos 服务 Ip 地址</span>
<span class="pl-c">     */</span>
    <span class="pl-k">private</span> <span class="pl-smi">String</span> <span class="pl-s1">serverAddr</span>;
  
  <span class="pl-c">// some property...</span>
  
  <span class="pl-k">public</span> <span class="pl-smi">org</span>.<span class="pl-smi">apache</span>.<span class="pl-smi">dubbo</span>.<span class="pl-smi">config</span>.<span class="pl-smi">ConfigCenterConfig</span> <span class="pl-en">ofConfigCenterConfig</span>() {
    <span class="pl-smi">org</span>.<span class="pl-smi">apache</span>.<span class="pl-smi">dubbo</span>.<span class="pl-smi">config</span>.<span class="pl-smi">ConfigCenterConfig</span> <span class="pl-s1">config</span> = <span class="pl-k">new</span> <span class="pl-smi">ConfigCenterConfig</span>();

    <span class="pl-smi">Map</span>&lt;<span class="pl-smi">String</span>, <span class="pl-smi">String</span>&gt; <span class="pl-s1">parameters</span> = <span class="pl-k">new</span> <span class="pl-smi">HashMap</span>&lt;&gt;(<span class="pl-c1">4</span>);

    <span class="pl-en">setParameter</span>(<span class="pl-s1">parameters</span>, <span class="pl-smi">PropertyKeyConst</span>.<span class="pl-c1">ACCESS_KEY</span>, <span class="pl-s1">accessKey</span>);
    <span class="pl-en">setParameter</span>(<span class="pl-s1">parameters</span>, <span class="pl-smi">PropertyKeyConst</span>.<span class="pl-c1">SECRET_KEY</span>, <span class="pl-s1">secretKey</span>);
    <span class="pl-en">setParameter</span>(<span class="pl-s1">parameters</span>, <span class="pl-smi">PropertyKeyConst</span>.<span class="pl-c1">ENDPOINT</span>, <span class="pl-s1">endpoint</span>);

    <span class="pl-s1">config</span>.<span class="pl-en">setParameters</span>(<span class="pl-s1">parameters</span>);

    <span class="pl-s1">config</span>.<span class="pl-en">setHighestPriority</span>(<span class="pl-s1">allowOverride</span>);
    <span class="pl-s1">config</span>.<span class="pl-en">setNamespace</span>(<span class="pl-s1">namespace</span>);
    <span class="pl-s1">config</span>.<span class="pl-en">setAddress</span>(<span class="pl-s1">serverAddr</span>);
    <span class="pl-s1">config</span>.<span class="pl-en">setConfigFile</span>(<span class="pl-s1">dataId</span>);
    <span class="pl-s1">config</span>.<span class="pl-en">setCheck</span>(<span class="pl-s1">abortOnFail</span>);
    <span class="pl-s1">config</span>.<span class="pl-en">setTimeout</span>(<span class="pl-s1">timeout</span>);
    <span class="pl-s1">config</span>.<span class="pl-en">setGroup</span>(<span class="pl-s1">group</span>);

    <span class="pl-k">return</span> <span class="pl-s1">config</span>;
  }
}</pre></div>
<h6 dir="auto">The last example, let see the <code class="notranslate">DubboBootstrap</code>, method <code class="notranslate">prepareEnvironment</code>, line 828 &amp; 829.</h6>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="DynamicConfiguration dynamicConfiguration = getDynamicConfiguration(configCenter.toUrl());

// Get config from remote server.
String configContent = dynamicConfiguration.getProperties(configCenter.getConfigFile(), configCenter.getGroup());

String appGroup = getApplication().getName();
String appConfigContent = null;
if (isNotEmpty(appGroup)) {
    appConfigContent = dynamicConfiguration.getProperties
            (isNotEmpty(configCenter.getAppConfigFile()) ? configCenter.getAppConfigFile() : configCenter.getConfigFile(),
                    appGroup
            );
}
try {
    environment.setConfigCenterFirst(configCenter.isHighestPriority());
  
    // It force all remote config must use &quot;properties&quot; format.
    environment.updateExternalConfigurationMap(parseProperties(configContent));
    environment.updateAppExternalConfigurationMap(parseProperties(appConfigContent));
  
  
} catch (IOException e) {
    throw new IllegalStateException(&quot;Failed to parse configurations from Config Center.&quot;, e);
}"><pre class="notranslate"><span class="pl-smi">DynamicConfiguration</span> <span class="pl-s1">dynamicConfiguration</span> = <span class="pl-en">getDynamicConfiguration</span>(<span class="pl-s1">configCenter</span>.<span class="pl-en">toUrl</span>());

<span class="pl-c">// Get config from remote server.</span>
<span class="pl-smi">String</span> <span class="pl-s1">configContent</span> = <span class="pl-s1">dynamicConfiguration</span>.<span class="pl-en">getProperties</span>(<span class="pl-s1">configCenter</span>.<span class="pl-en">getConfigFile</span>(), <span class="pl-s1">configCenter</span>.<span class="pl-en">getGroup</span>());

<span class="pl-smi">String</span> <span class="pl-s1">appGroup</span> = <span class="pl-en">getApplication</span>().<span class="pl-en">getName</span>();
<span class="pl-smi">String</span> <span class="pl-s1">appConfigContent</span> = <span class="pl-c1">null</span>;
<span class="pl-k">if</span> (<span class="pl-en">isNotEmpty</span>(<span class="pl-s1">appGroup</span>)) {
    <span class="pl-s1">appConfigContent</span> = <span class="pl-s1">dynamicConfiguration</span>.<span class="pl-en">getProperties</span>
            (<span class="pl-en">isNotEmpty</span>(<span class="pl-s1">configCenter</span>.<span class="pl-en">getAppConfigFile</span>()) ? <span class="pl-s1">configCenter</span>.<span class="pl-en">getAppConfigFile</span>() : <span class="pl-s1">configCenter</span>.<span class="pl-en">getConfigFile</span>(),
                    <span class="pl-s1">appGroup</span>
            );
}
<span class="pl-k">try</span> {
    <span class="pl-s1">environment</span>.<span class="pl-en">setConfigCenterFirst</span>(<span class="pl-s1">configCenter</span>.<span class="pl-en">isHighestPriority</span>());
  
    <span class="pl-c">// It force all remote config must use "properties" format.</span>
    <span class="pl-s1">environment</span>.<span class="pl-en">updateExternalConfigurationMap</span>(<span class="pl-en">parseProperties</span>(<span class="pl-s1">configContent</span>));
    <span class="pl-s1">environment</span>.<span class="pl-en">updateAppExternalConfigurationMap</span>(<span class="pl-en">parseProperties</span>(<span class="pl-s1">appConfigContent</span>));
  
  
} <span class="pl-k">catch</span> (<span class="pl-smi">IOException</span> <span class="pl-s1">e</span>) {
    <span class="pl-k">throw</span> <span class="pl-k">new</span> <span class="pl-smi">IllegalStateException</span>(<span class="pl-s">"Failed to parse configurations from Config Center."</span>, <span class="pl-s1">e</span>);
}</pre></div>
<p dir="auto">Because the method <code class="notranslate">parseProperties</code>, I have to create my own protocol <code class="notranslate">banacos</code> and <code class="notranslate">BanacosDynamicConfiguration</code>, the goal is parse yaml and tranform to properties format.</p>
<p dir="auto">It should be add a property name <code class="notranslate">format</code>( or <code class="notranslate">file-extension</code> like nacos client ? ) to decide what parser should be Dubbo use, rather than write those dead code.</p>
</li>
<li>
<p dir="auto"><strong>Metadata server not effective, and the <code class="notranslate">ServiceNameMapping</code> write meta data anywhere</strong></p>
<p dir="auto">The reason of meta server not effective is same with my first issue "<strong>Failure due to the Dubbo starting early</strong>". Let see <code class="notranslate">DubboBootstrap</code> again, the method <code class="notranslate">startMetadataReport</code>:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="ApplicationConfig applicationConfig = getApplication();

String metadataType = applicationConfig.getMetadataType();
// FIXME, multiple metadata config support.
Collection&lt;MetadataReportConfig&gt; metadataReportConfigs = configManager.getMetadataConfigs();
if (CollectionUtils.isEmpty(metadataReportConfigs)) {
  if (REMOTE_METADATA_STORAGE_TYPE.equals(metadataType)) {
    throw new IllegalStateException(&quot;No MetadataConfig found, you must specify the remote Metadata Center address when 'metadata=remote' is enabled.&quot;);
  }
  return;
}
MetadataReportConfig metadataReportConfig = metadataReportConfigs.iterator().next();
ConfigValidationUtils.validateMetadataConfig(metadataReportConfig);
if (!metadataReportConfig.isValid()) {
  return;
}

MetadataReportInstance.init(metadataReportConfig.toUrl());"><pre class="notranslate"><span class="pl-smi">ApplicationConfig</span> <span class="pl-s1">applicationConfig</span> = <span class="pl-en">getApplication</span>();

<span class="pl-smi">String</span> <span class="pl-s1">metadataType</span> = <span class="pl-s1">applicationConfig</span>.<span class="pl-en">getMetadataType</span>();
<span class="pl-c">// FIXME, multiple metadata config support.</span>
<span class="pl-smi">Collection</span>&lt;<span class="pl-smi">MetadataReportConfig</span>&gt; <span class="pl-s1">metadataReportConfigs</span> = <span class="pl-s1">configManager</span>.<span class="pl-en">getMetadataConfigs</span>();
<span class="pl-k">if</span> (<span class="pl-smi">CollectionUtils</span>.<span class="pl-en">isEmpty</span>(<span class="pl-s1">metadataReportConfigs</span>)) {
  <span class="pl-k">if</span> (<span class="pl-smi">REMOTE_METADATA_STORAGE_TYPE</span>.<span class="pl-en">equals</span>(<span class="pl-s1">metadataType</span>)) {
    <span class="pl-k">throw</span> <span class="pl-k">new</span> <span class="pl-smi">IllegalStateException</span>(<span class="pl-s">"No MetadataConfig found, you must specify the remote Metadata Center address when 'metadata=remote' is enabled."</span>);
  }
  <span class="pl-k">return</span>;
}
<span class="pl-smi">MetadataReportConfig</span> <span class="pl-s1">metadataReportConfig</span> = <span class="pl-s1">metadataReportConfigs</span>.<span class="pl-en">iterator</span>().<span class="pl-en">next</span>();
<span class="pl-smi">ConfigValidationUtils</span>.<span class="pl-en">validateMetadataConfig</span>(<span class="pl-s1">metadataReportConfig</span>);
<span class="pl-k">if</span> (!<span class="pl-s1">metadataReportConfig</span>.<span class="pl-en">isValid</span>()) {
  <span class="pl-k">return</span>;
}

<span class="pl-smi">MetadataReportInstance</span>.<span class="pl-en">init</span>(<span class="pl-s1">metadataReportConfig</span>.<span class="pl-en">toUrl</span>());</pre></div>
<p dir="auto">Is it familiar ? Dubbo activate too soon, even before any config injected, that is the reason why some functions is not work on Dubbo 2.7.5 . We should pay attention to the Bean initialize, especially startup Dubbo under Spring framrwork.</p>
<p dir="auto">And this is the last issue for this article, the class <code class="notranslate">DynamicConfigurationServiceNameMapping</code> push metadata to anywhere:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="@Override
public void map(String serviceInterface, String group, String version, String protocol) {

  if (IGNORED_SERVICE_INTERFACES.contains(serviceInterface)) {
    return;
  }

  // The value of variable 'dynamicConfiguration' is CompositeDynamicConfiguration
  DynamicConfiguration dynamicConfiguration = DynamicConfiguration.getDynamicConfiguration();
}"><pre class="notranslate"><span class="pl-c1">@</span><span class="pl-c1">Override</span>
<span class="pl-k">public</span> <span class="pl-smi">void</span> <span class="pl-s1">map</span>(<span class="pl-smi">String</span> <span class="pl-s1">serviceInterface</span>, <span class="pl-smi">String</span> <span class="pl-s1">group</span>, <span class="pl-smi">String</span> <span class="pl-s1">version</span>, <span class="pl-smi">String</span> <span class="pl-s1">protocol</span>) {

  <span class="pl-k">if</span> (<span class="pl-smi">IGNORED_SERVICE_INTERFACES</span>.<span class="pl-en">contains</span>(<span class="pl-s1">serviceInterface</span>)) {
    <span class="pl-k">return</span>;
  }

  <span class="pl-c">// The value of variable 'dynamicConfiguration' is CompositeDynamicConfiguration</span>
  <span class="pl-smi">DynamicConfiguration</span> <span class="pl-s1">dynamicConfiguration</span> = <span class="pl-smi">DynamicConfiguration</span>.<span class="pl-en">getDynamicConfiguration</span>();
}</pre></div>
<p dir="auto">The javadoc of the class <code class="notranslate">CompositeDynamicConfiguration</code>  is <em><strong>support multiple config center, simply iterating each concrete config center</strong></em>. It mean this class will push metadata to any config center we configed.</p>
<p dir="auto">In my opinion, those "metadata" should push to metadata server rather than config server. Now every I startup Dubbo service as provider, my config server always fill all data that useless in my view. Just a mess on my config server If I startup all Dubbo service.</p>
</li>
</ul>