You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by il...@apache.org on 2018/12/17 15:29:27 UTC
[incubator-dubbo-website] 03/03: update
This is an automated email from the ASF dual-hosted git repository.
iluo pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/incubator-dubbo-website.git
commit e582612248c4d61fb34f98988c10da36f077de05
Author: beiwei30 <ia...@gmail.com>
AuthorDate: Mon Dec 17 23:29:04 2018 +0800
update
---
en-us/docs/admin/install/provider-demo.html | 2 +-
en-us/docs/admin/install/provider-demo.json | 2 +-
en-us/docs/admin/ops/pinpoint.html | 4 +-
en-us/docs/admin/ops/pinpoint.json | 2 +-
en-us/docs/dev/SPI.html | 18 +-
en-us/docs/dev/SPI.json | 2 +-
en-us/docs/dev/code-smell.html | 10 +-
en-us/docs/dev/code-smell.json | 2 +-
en-us/docs/dev/implementation.html | 4 +-
en-us/docs/dev/implementation.json | 2 +-
en-us/docs/dev/impls/cache.html | 16 +-
en-us/docs/dev/impls/cache.json | 2 +-
en-us/docs/dev/impls/cluster.html | 34 +-
en-us/docs/dev/impls/cluster.json | 2 +-
en-us/docs/dev/impls/compiler.html | 12 +-
en-us/docs/dev/impls/compiler.json | 2 +-
en-us/docs/dev/impls/container.html | 16 +-
en-us/docs/dev/impls/container.json | 2 +-
en-us/docs/dev/impls/dispatcher.html | 18 +-
en-us/docs/dev/impls/dispatcher.json | 2 +-
en-us/docs/dev/impls/exchanger.html | 18 +-
en-us/docs/dev/impls/exchanger.json | 2 +-
en-us/docs/dev/impls/exporter-listener.html | 14 +-
en-us/docs/dev/impls/exporter-listener.json | 2 +-
en-us/docs/dev/impls/extension-factory.html | 12 +-
en-us/docs/dev/impls/extension-factory.json | 2 +-
en-us/docs/dev/impls/filter.html | 42 +-
en-us/docs/dev/impls/filter.json | 2 +-
en-us/docs/dev/impls/invoker-listener.html | 14 +-
en-us/docs/dev/impls/invoker-listener.json | 2 +-
en-us/docs/dev/impls/load-balance.html | 20 +-
en-us/docs/dev/impls/load-balance.json | 2 +-
en-us/docs/dev/impls/logger-adapter.html | 20 +-
en-us/docs/dev/impls/logger-adapter.json | 2 +-
en-us/docs/dev/impls/merger.html | 16 +-
en-us/docs/dev/impls/merger.json | 2 +-
en-us/docs/dev/impls/monitor.html | 18 +-
en-us/docs/dev/impls/monitor.json | 2 +-
en-us/docs/dev/impls/networker.html | 12 +-
en-us/docs/dev/impls/networker.json | 2 +-
en-us/docs/dev/impls/page.html | 16 +-
en-us/docs/dev/impls/page.json | 2 +-
en-us/docs/dev/impls/protocol.html | 26 +-
en-us/docs/dev/impls/protocol.json | 2 +-
en-us/docs/dev/impls/proxy-factory.html | 16 +-
en-us/docs/dev/impls/proxy-factory.json | 2 +-
en-us/docs/dev/impls/registry.html | 28 +-
en-us/docs/dev/impls/registry.json | 2 +-
en-us/docs/dev/impls/remoting.html | 22 +-
en-us/docs/dev/impls/remoting.json | 2 +-
en-us/docs/dev/impls/router.html | 20 +-
en-us/docs/dev/impls/router.json | 2 +-
en-us/docs/dev/impls/serialize.html | 24 +-
en-us/docs/dev/impls/serialize.json | 2 +-
en-us/docs/dev/impls/status-checker.html | 22 +-
en-us/docs/dev/impls/status-checker.json | 2 +-
en-us/docs/dev/impls/telnet-handler.html | 30 +-
en-us/docs/dev/impls/telnet-handler.json | 2 +-
en-us/docs/dev/impls/threadpool.html | 12 +-
en-us/docs/dev/impls/threadpool.json | 2 +-
en-us/docs/dev/impls/validation.html | 12 +-
en-us/docs/dev/impls/validation.json | 2 +-
en-us/docs/user/configuration/annotation.html | 10 +-
en-us/docs/user/configuration/annotation.json | 2 +-
en-us/docs/user/configuration/api.html | 16 +-
en-us/docs/user/configuration/api.json | 2 +-
en-us/docs/user/configuration/xml.html | 4 +-
en-us/docs/user/configuration/xml.json | 2 +-
en-us/docs/user/demos/events-notify.html | 8 +-
en-us/docs/user/demos/events-notify.json | 2 +-
en-us/docs/user/demos/generic-reference.html | 4 +-
en-us/docs/user/demos/generic-reference.json | 2 +-
en-us/docs/user/demos/generic-service.html | 2 +-
en-us/docs/user/demos/generic-service.json | 2 +-
en-us/docs/user/demos/parameter-validation.html | 10 +-
en-us/docs/user/demos/parameter-validation.json | 2 +-
en-us/docs/user/demos/serialization.html | 2 +-
en-us/docs/user/demos/serialization.json | 2 +-
en-us/docs/user/demos/service-container.html | 6 +-
en-us/docs/user/demos/service-container.json | 2 +-
en-us/docs/user/references/api.html | 38 +-
en-us/docs/user/references/api.json | 2 +-
en-us/docs/user/references/protocol/http.html | 2 +-
en-us/docs/user/references/protocol/http.json | 2 +-
.../docs/user/references/protocol/webservice.html | 2 +-
.../docs/user/references/protocol/webservice.json | 2 +-
en-us/docs/user/references/qos.html | 8 +-
en-us/docs/user/references/qos.json | 2 +-
en-us/docs/user/references/registry/simple.html | 6 +-
en-us/docs/user/references/registry/simple.json | 2 +-
.../user/references/xml/dubbo-application.html | 2 +-
.../user/references/xml/dubbo-application.json | 2 +-
en-us/docs/user/references/xml/dubbo-argument.html | 2 +-
en-us/docs/user/references/xml/dubbo-argument.json | 2 +-
en-us/docs/user/references/xml/dubbo-consumer.html | 2 +-
en-us/docs/user/references/xml/dubbo-consumer.json | 2 +-
en-us/docs/user/references/xml/dubbo-method.html | 2 +-
en-us/docs/user/references/xml/dubbo-method.json | 2 +-
en-us/docs/user/references/xml/dubbo-module.html | 2 +-
en-us/docs/user/references/xml/dubbo-module.json | 2 +-
en-us/docs/user/references/xml/dubbo-monitor.html | 2 +-
en-us/docs/user/references/xml/dubbo-monitor.json | 2 +-
en-us/docs/user/references/xml/dubbo-protocol.html | 2 +-
en-us/docs/user/references/xml/dubbo-protocol.json | 2 +-
en-us/docs/user/references/xml/dubbo-provider.html | 2 +-
en-us/docs/user/references/xml/dubbo-provider.json | 2 +-
.../docs/user/references/xml/dubbo-reference.html | 2 +-
.../docs/user/references/xml/dubbo-reference.json | 2 +-
en-us/docs/user/references/xml/dubbo-registry.html | 2 +-
en-us/docs/user/references/xml/dubbo-registry.json | 2 +-
en-us/docs/user/references/xml/dubbo-service.html | 2 +-
en-us/docs/user/references/xml/dubbo-service.json | 2 +-
en-us/docs/user/rest.html | 10 +-
en-us/docs/user/rest.json | 2 +-
en-us/docs/user/simple-monitor.html | 10 +-
en-us/docs/user/simple-monitor.json | 2 +-
md_json/docs.json | 72 +
zh-cn/docs/admin/install/consumer-demo.html | 2 +-
zh-cn/docs/admin/install/consumer-demo.json | 2 +-
zh-cn/docs/admin/install/provider-demo.html | 2 +-
zh-cn/docs/admin/install/provider-demo.json | 2 +-
zh-cn/docs/admin/ops/pinpoint.html | 4 +-
zh-cn/docs/admin/ops/pinpoint.json | 2 +-
zh-cn/docs/dev/SPI.html | 18 +-
zh-cn/docs/dev/SPI.json | 2 +-
zh-cn/docs/dev/code-smell.html | 10 +-
zh-cn/docs/dev/code-smell.json | 2 +-
zh-cn/docs/dev/implementation.html | 4 +-
zh-cn/docs/dev/implementation.json | 2 +-
zh-cn/docs/dev/impls/cache.html | 16 +-
zh-cn/docs/dev/impls/cache.json | 2 +-
zh-cn/docs/dev/impls/cluster.html | 34 +-
zh-cn/docs/dev/impls/cluster.json | 2 +-
zh-cn/docs/dev/impls/compiler.html | 12 +-
zh-cn/docs/dev/impls/compiler.json | 2 +-
zh-cn/docs/dev/impls/container.html | 16 +-
zh-cn/docs/dev/impls/container.json | 2 +-
zh-cn/docs/dev/impls/dispatcher.html | 18 +-
zh-cn/docs/dev/impls/dispatcher.json | 2 +-
zh-cn/docs/dev/impls/exchanger.html | 18 +-
zh-cn/docs/dev/impls/exchanger.json | 2 +-
zh-cn/docs/dev/impls/exporter-listener.html | 14 +-
zh-cn/docs/dev/impls/exporter-listener.json | 2 +-
zh-cn/docs/dev/impls/extension-factory.html | 12 +-
zh-cn/docs/dev/impls/extension-factory.json | 2 +-
zh-cn/docs/dev/impls/filter.html | 42 +-
zh-cn/docs/dev/impls/filter.json | 2 +-
zh-cn/docs/dev/impls/invoker-listener.html | 14 +-
zh-cn/docs/dev/impls/invoker-listener.json | 2 +-
zh-cn/docs/dev/impls/load-balance.html | 20 +-
zh-cn/docs/dev/impls/load-balance.json | 2 +-
zh-cn/docs/dev/impls/logger-adapter.html | 20 +-
zh-cn/docs/dev/impls/logger-adapter.json | 2 +-
zh-cn/docs/dev/impls/merger.html | 16 +-
zh-cn/docs/dev/impls/merger.json | 2 +-
zh-cn/docs/dev/impls/monitor.html | 18 +-
zh-cn/docs/dev/impls/monitor.json | 2 +-
zh-cn/docs/dev/impls/networker.html | 12 +-
zh-cn/docs/dev/impls/networker.json | 2 +-
zh-cn/docs/dev/impls/page.html | 16 +-
zh-cn/docs/dev/impls/page.json | 2 +-
zh-cn/docs/dev/impls/protocol.html | 26 +-
zh-cn/docs/dev/impls/protocol.json | 2 +-
zh-cn/docs/dev/impls/proxy-factory.html | 16 +-
zh-cn/docs/dev/impls/proxy-factory.json | 2 +-
zh-cn/docs/dev/impls/registry.html | 28 +-
zh-cn/docs/dev/impls/registry.json | 2 +-
zh-cn/docs/dev/impls/remoting.html | 22 +-
zh-cn/docs/dev/impls/remoting.json | 2 +-
zh-cn/docs/dev/impls/router.html | 20 +-
zh-cn/docs/dev/impls/router.json | 2 +-
zh-cn/docs/dev/impls/serialize.html | 24 +-
zh-cn/docs/dev/impls/serialize.json | 2 +-
zh-cn/docs/dev/impls/status-checker.html | 22 +-
zh-cn/docs/dev/impls/status-checker.json | 2 +-
zh-cn/docs/dev/impls/telnet-handler.html | 30 +-
zh-cn/docs/dev/impls/telnet-handler.json | 2 +-
zh-cn/docs/dev/impls/threadpool.html | 12 +-
zh-cn/docs/dev/impls/threadpool.json | 2 +-
zh-cn/docs/dev/impls/validation.html | 12 +-
zh-cn/docs/dev/impls/validation.json | 2 +-
zh-cn/docs/dev/principals/extension.html | 2 +-
zh-cn/docs/dev/principals/extension.json | 2 +-
.../docs/source_code_guide/adaptive-extension.html | 697 ++++++++++
.../docs/source_code_guide/adaptive-extension.json | 10 +
zh-cn/docs/source_code_guide/cluster.html | 559 ++++++++
zh-cn/docs/source_code_guide/cluster.json | 10 +
zh-cn/docs/source_code_guide/directory.html | 516 ++++++++
zh-cn/docs/source_code_guide/directory.json | 10 +
zh-cn/docs/source_code_guide/dubbo-spi.html | 393 ++++++
zh-cn/docs/source_code_guide/dubbo-spi.json | 10 +
zh-cn/docs/source_code_guide/export-service.html | 1387 ++++++++++++++++++++
zh-cn/docs/source_code_guide/export-service.json | 10 +
zh-cn/docs/source_code_guide/loadbalance.html | 745 +++++++++++
zh-cn/docs/source_code_guide/loadbalance.json | 10 +
zh-cn/docs/source_code_guide/refer-service.html | 856 ++++++++++++
zh-cn/docs/source_code_guide/refer-service.json | 10 +
zh-cn/docs/source_code_guide/router.html | 460 +++++++
zh-cn/docs/source_code_guide/router.json | 10 +
zh-cn/docs/user/configuration/annotation.html | 10 +-
zh-cn/docs/user/configuration/annotation.json | 2 +-
zh-cn/docs/user/configuration/api.html | 16 +-
zh-cn/docs/user/configuration/api.json | 2 +-
zh-cn/docs/user/configuration/xml.html | 4 +-
zh-cn/docs/user/configuration/xml.json | 2 +-
zh-cn/docs/user/demos/events-notify.html | 8 +-
zh-cn/docs/user/demos/events-notify.json | 2 +-
zh-cn/docs/user/demos/generic-reference.html | 4 +-
zh-cn/docs/user/demos/generic-reference.json | 2 +-
zh-cn/docs/user/demos/generic-service.html | 2 +-
zh-cn/docs/user/demos/generic-service.json | 2 +-
zh-cn/docs/user/demos/parameter-validation.html | 10 +-
zh-cn/docs/user/demos/parameter-validation.json | 2 +-
zh-cn/docs/user/demos/serialization.html | 2 +-
zh-cn/docs/user/demos/serialization.json | 2 +-
zh-cn/docs/user/demos/service-container.html | 6 +-
zh-cn/docs/user/demos/service-container.json | 2 +-
zh-cn/docs/user/demos/set-host.html | 2 +-
zh-cn/docs/user/demos/set-host.json | 2 +-
zh-cn/docs/user/quick-start.html | 14 +-
zh-cn/docs/user/quick-start.json | 2 +-
zh-cn/docs/user/references/api.html | 38 +-
zh-cn/docs/user/references/api.json | 2 +-
zh-cn/docs/user/references/protocol/http.html | 2 +-
zh-cn/docs/user/references/protocol/http.json | 2 +-
zh-cn/docs/user/references/protocol/rest.html | 10 +-
zh-cn/docs/user/references/protocol/rest.json | 2 +-
.../docs/user/references/protocol/webservice.html | 2 +-
.../docs/user/references/protocol/webservice.json | 2 +-
zh-cn/docs/user/references/qos.html | 8 +-
zh-cn/docs/user/references/qos.json | 2 +-
zh-cn/docs/user/references/registry/simple.html | 6 +-
zh-cn/docs/user/references/registry/simple.json | 2 +-
.../user/references/xml/dubbo-application.html | 2 +-
.../user/references/xml/dubbo-application.json | 2 +-
zh-cn/docs/user/references/xml/dubbo-argument.html | 2 +-
zh-cn/docs/user/references/xml/dubbo-argument.json | 2 +-
zh-cn/docs/user/references/xml/dubbo-consumer.html | 2 +-
zh-cn/docs/user/references/xml/dubbo-consumer.json | 2 +-
zh-cn/docs/user/references/xml/dubbo-method.html | 2 +-
zh-cn/docs/user/references/xml/dubbo-method.json | 2 +-
zh-cn/docs/user/references/xml/dubbo-module.html | 2 +-
zh-cn/docs/user/references/xml/dubbo-module.json | 2 +-
zh-cn/docs/user/references/xml/dubbo-monitor.html | 2 +-
zh-cn/docs/user/references/xml/dubbo-monitor.json | 2 +-
zh-cn/docs/user/references/xml/dubbo-protocol.html | 2 +-
zh-cn/docs/user/references/xml/dubbo-protocol.json | 2 +-
zh-cn/docs/user/references/xml/dubbo-provider.html | 2 +-
zh-cn/docs/user/references/xml/dubbo-provider.json | 2 +-
.../docs/user/references/xml/dubbo-reference.html | 2 +-
.../docs/user/references/xml/dubbo-reference.json | 2 +-
zh-cn/docs/user/references/xml/dubbo-registry.html | 2 +-
zh-cn/docs/user/references/xml/dubbo-registry.json | 2 +-
zh-cn/docs/user/references/xml/dubbo-service.html | 2 +-
zh-cn/docs/user/references/xml/dubbo-service.json | 2 +-
zh-cn/docs/user/rest.html | 10 +-
zh-cn/docs/user/rest.json | 2 +-
zh-cn/docs/user/serialization.html | 2 +-
zh-cn/docs/user/serialization.json | 2 +-
zh-cn/docs/user/simple-monitor.html | 10 +-
zh-cn/docs/user/simple-monitor.json | 2 +-
261 files changed, 6611 insertions(+), 846 deletions(-)
diff --git a/en-us/docs/admin/install/provider-demo.html b/en-us/docs/admin/install/provider-demo.html
index 7fc0d7a..a075cab 100644
--- a/en-us/docs/admin/install/provider-demo.html
+++ b/en-us/docs/admin/install/provider-demo.html
@@ -16,7 +16,7 @@
<p>install:</p>
<pre><code class="language-sh">git <span class="hljs-built_in">clone</span> https://github.com/apache/incubator-dubbo.git
<span class="hljs-built_in">cd</span> incubator-dubbo
-run com.alibaba.dubbo.demo.provider.Provider under dubbo-demo-provider module
+run org.apache.dubbo.demo.provider.Provider under dubbo-demo-provider module
add -Djava.net.preferIPv4Stack=<span class="hljs-literal">true</span> <span class="hljs-keyword">if</span> your IDE is Intellij Idea
</code></pre>
<p>configuration:</p>
diff --git a/en-us/docs/admin/install/provider-demo.json b/en-us/docs/admin/install/provider-demo.json
index 377624a..90e786a 100644
--- a/en-us/docs/admin/install/provider-demo.json
+++ b/en-us/docs/admin/install/provider-demo.json
@@ -1,6 +1,6 @@
{
"filename": "provider-demo.md",
- "__html": "<h1>install demo provider</h1>\n<p>install:</p>\n<pre><code class=\"language-sh\">git <span class=\"hljs-built_in\">clone</span> https://github.com/apache/incubator-dubbo.git\n<span class=\"hljs-built_in\">cd</span> incubator-dubbo\nrun com.alibaba.dubbo.demo.provider.Provider under dubbo-demo-provider module\nadd -Djava.net.preferIPv4Stack=<span class=\"hljs-literal\">true</span> <span class=\"hljs-keyword\">if</span> your IDE is Intellij Idea\n</code></pre>\n<p>configurati [...]
+ "__html": "<h1>install demo provider</h1>\n<p>install:</p>\n<pre><code class=\"language-sh\">git <span class=\"hljs-built_in\">clone</span> https://github.com/apache/incubator-dubbo.git\n<span class=\"hljs-built_in\">cd</span> incubator-dubbo\nrun org.apache.dubbo.demo.provider.Provider under dubbo-demo-provider module\nadd -Djava.net.preferIPv4Stack=<span class=\"hljs-literal\">true</span> <span class=\"hljs-keyword\">if</span> your IDE is Intellij Idea\n</code></pre>\n<p>configuratio [...]
"link": "/en-us/docs/admin/install/provider-demo.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/admin/ops/pinpoint.html b/en-us/docs/admin/ops/pinpoint.html
index 3ff5bf4..b9e5328 100644
--- a/en-us/docs/admin/ops/pinpoint.html
+++ b/en-us/docs/admin/ops/pinpoint.html
@@ -150,7 +150,7 @@ public interface HelloService {
</ol>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.example.demoprovider.provider;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.config.annotation.Service;
+<span class="hljs-keyword">import</span> org.apache.dubbo.config.annotation.Service;
<span class="hljs-keyword">import</span> com.example.demoapi.HelloService;
<span class="hljs-meta">@Service</span>(version = <span class="hljs-string">"${demo.service.version}"</span>,
@@ -295,7 +295,7 @@ public interface HelloService {
</ol>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.example.democonsumer.controller;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.config.annotation.Reference;
+<span class="hljs-keyword">import</span> org.apache.dubbo.config.annotation.Reference;
<span class="hljs-keyword">import</span> com.example.demoapi.HelloService;
<span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.RequestMapping;
<span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.RequestParam;
diff --git a/en-us/docs/admin/ops/pinpoint.json b/en-us/docs/admin/ops/pinpoint.json
index 5fb6d94..7451bde 100644
--- a/en-us/docs/admin/ops/pinpoint.json
+++ b/en-us/docs/admin/ops/pinpoint.json
@@ -1,6 +1,6 @@
{
"filename": "pinpoint.md",
- "__html": "<h1>Tracking with Pinpoint</h1>\n<p>After using Dubbo to serve or integrate applications, assuming that a service backstage log shows an exception and that the service is invoked by multiple applications, it is often difficult to determine which application is called, and what is the cause of the problem, so we need a set of distributed tracking systems to quickly locate the problem. Pinpoint can help us quickly locate problems (of course, there are more than one solution).< [...]
+ "__html": "<h1>Tracking with Pinpoint</h1>\n<p>After using Dubbo to serve or integrate applications, assuming that a service backstage log shows an exception and that the service is invoked by multiple applications, it is often difficult to determine which application is called, and what is the cause of the problem, so we need a set of distributed tracking systems to quickly locate the problem. Pinpoint can help us quickly locate problems (of course, there are more than one solution).< [...]
"link": "/en-us/docs/admin/ops/pinpoint.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/SPI.html b/en-us/docs/dev/SPI.html
index 71499f4..69133e2 100644
--- a/en-us/docs/dev/SPI.html
+++ b/en-us/docs/dev/SPI.html
@@ -25,13 +25,13 @@
<h3>Appointment:</h3>
<p>In the jar file containing extension class <sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>,places a config file <code>META-INF/dubbo/full interface name</code>,file content pattern:<code>SPI name=the fully qualified name for the extension class</code>,use new line seperator for multiple implementation.</p>
<h3>Example:</h3>
-<p>To extend Dubbo Protocol,placee a text file in the extension jar file:<code>META-INF/dubbo/com.alibaba.dubbo.rpc.Protocol</code>,content:</p>
+<p>To extend Dubbo Protocol,placee a text file in the extension jar file:<code>META-INF/dubbo/org.apache.dubbo.rpc.Protocol</code>,content:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.alibaba.xxx.XxxProtocol</span>
</code></pre>
<p>content of the implementation <sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup>:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.alibaba.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Protocol;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Protocol;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxProtocol</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Protocol</span> </span>{
<span class="hljs-comment">// ...</span>
@@ -47,7 +47,7 @@
<p>Wrapper class content:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.alibaba.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Protocol;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Protocol;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxProtocolWrapper</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Protocol</span> </span>{
Protocol impl;
@@ -148,8 +148,8 @@ Wheel wheel = wheelMaker.makeWheel(url);
<p>for the method bind(),Adaptive will firstly search <code>server</code> key,if no Key were founded then will search <code>transport</code> key ,to determine the implementation that the proxy represent for.</p>
<h3>SPI Auto Activation</h3>
<p>As for Collections SPI, such as:<code>Filter</code>, <code>InvokerListener</code>, <code>ExportListener</code>, <code>TelnetHandler</code>, <code>StatusChecker</code> etc,multi implementations can be loaded at one time. User can simplify configuration by using auto activation,Like:</p>
-<pre><code class="language-java"><span class="hljs-keyword">import</span> com.alibaba.dubbo.common.extension.Activate;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Filter;
+<pre><code class="language-java"><span class="hljs-keyword">import</span> org.apache.dubbo.common.extension.Activate;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Filter;
<span class="hljs-meta">@Activate</span> <span class="hljs-comment">// Active for any condition</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxFilter</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Filter</span> </span>{
@@ -157,8 +157,8 @@ Wheel wheel = wheelMaker.makeWheel(url);
}
</code></pre>
<p>Or:</p>
-<pre><code class="language-java"><span class="hljs-keyword">import</span> com.alibaba.dubbo.common.extension.Activate;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Filter;
+<pre><code class="language-java"><span class="hljs-keyword">import</span> org.apache.dubbo.common.extension.Activate;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Filter;
<span class="hljs-meta">@Activate</span>(<span class="hljs-string">"xxx"</span>) <span class="hljs-comment">// when configed xxx parameter and the parameter has a valid value,the SPI is activated,for example configed cache="lru",auto acitivate CacheFilter。</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxFilter</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Filter</span> </span>{
@@ -166,8 +166,8 @@ Wheel wheel = wheelMaker.makeWheel(url);
}
</code></pre>
<p>Or:</p>
-<pre><code class="language-java"><span class="hljs-keyword">import</span> com.alibaba.dubbo.common.extension.Activate;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Filter;
+<pre><code class="language-java"><span class="hljs-keyword">import</span> org.apache.dubbo.common.extension.Activate;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Filter;
<span class="hljs-meta">@Activate</span>(group = <span class="hljs-string">"provider"</span>, value = <span class="hljs-string">"xxx"</span>) <span class="hljs-comment">// only activate for provider,group can be "provider" or "consumer"</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxFilter</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Filter</span> </span>{
diff --git a/en-us/docs/dev/SPI.json b/en-us/docs/dev/SPI.json
index 16d3abb..bd463a7 100644
--- a/en-us/docs/dev/SPI.json
+++ b/en-us/docs/dev/SPI.json
@@ -1,6 +1,6 @@
{
"filename": "SPI.md",
- "__html": "<h1>SPI Loading</h1>\n<h2>SPI Config</h2>\n<h3>Source:</h3>\n<p>Dubbo SPI is inherited from standard JDK SPI(Service Provider Interface) and makes it more powerful.</p>\n<p>Dubbo fixed below issues of the standard JDK SPI:</p>\n<ul>\n<li>the standard JDK SPI will load and instantize all implementation at once. It will be a waste of resources if the implementation is timecosted ,but never be used.</li>\n<li>We cann't accquire the SPI name,if loading the SPI implementation i [...]
+ "__html": "<h1>SPI Loading</h1>\n<h2>SPI Config</h2>\n<h3>Source:</h3>\n<p>Dubbo SPI is inherited from standard JDK SPI(Service Provider Interface) and makes it more powerful.</p>\n<p>Dubbo fixed below issues of the standard JDK SPI:</p>\n<ul>\n<li>the standard JDK SPI will load and instantize all implementation at once. It will be a waste of resources if the implementation is timecosted ,but never be used.</li>\n<li>We cann't accquire the SPI name,if loading the SPI implementation i [...]
"link": "/en-us/docs/dev/SPI.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/code-smell.html b/en-us/docs/dev/code-smell.html
index 889b35c..3089ccf 100644
--- a/en-us/docs/dev/code-smell.html
+++ b/en-us/docs/dev/code-smell.html
@@ -24,11 +24,11 @@
</code></pre>
<h3>2. Export servie by registry</h3>
<p>export service to registry:</p>
-<pre><code>EXPORT(registry://registry-address/com.alibaba.dubbo.registry.RegistrySerevice?registry=dubbo&export=ENCODE(dubbo://provider-address/com.xxx.XxxService?version=1.0.0))
+<pre><code>EXPORT(registry://registry-address/org.apache.dubbo.registry.RegistrySerevice?registry=dubbo&export=ENCODE(dubbo://provider-address/com.xxx.XxxService?version=1.0.0))
</code></pre>
<p>accquire registry:</p>
<pre><code>url.setProtocol(url.getParameter("registry", "dubbo"))
-GETREGISTRY(dubbo://registry-address/com.alibaba.dubbo.registry.RegistrySerevice)
+GETREGISTRY(dubbo://registry-address/org.apache.dubbo.registry.RegistrySerevice)
</code></pre>
<p>registry service address:</p>
<pre><code>url.getParameterAndDecoded("export"))
@@ -36,11 +36,11 @@ REGISTER(dubbo://provider-address/com.xxx.XxxService?version=1.0.0)
</code></pre>
<h3>3. Refer service from registry</h3>
<p>refer service from registry:</p>
-<pre><code>REFER(registry://registry-address/com.alibaba.dubbo.registry.RegistrySerevice?registry=dubbo&refer=ENCODE(version=1.0.0))
+<pre><code>REFER(registry://registry-address/org.apache.dubbo.registry.RegistrySerevice?registry=dubbo&refer=ENCODE(version=1.0.0))
</code></pre>
<p>accquire registry:</p>
<pre><code>url.setProtocol(url.getParameter("registry", "dubbo"))
-GETREGISTRY(dubbo://registry-address/com.alibaba.dubbo.registry.RegistrySerevice)
+GETREGISTRY(dubbo://registry-address/org.apache.dubbo.registry.RegistrySerevice)
</code></pre>
<p>subscribe service address:</p>
<pre><code>url.addParameters(url.getParameterAndDecoded("refer"))
@@ -111,7 +111,7 @@ GETROUTE(script://path/file.js?type=js&rule=ENCODE(function{...}))
}
</code></pre>
<p><code>@Adaptive</code> annotation usage:</p>
-<p>If no value is configed for those Keys in URL,default SPI implementation is used。For example ,String[] {"key1", "key2"},firstly Dubbo will look up value for key1 and use it as SPI name;if key1 value is not founded then look up for key2,if value of key2 is also not found ,then use default spi implementation. If no default implementation is configed, then the method will throw IllegalStateException。if not configed , then default implement is lower case of the interfa [...]
+<p>If no value is configed for those Keys in URL,default SPI implementation is used。For example ,String[] {"key1", "key2"},firstly Dubbo will look up value for key1 and use it as SPI name;if key1 value is not founded then look up for key2,if value of key2 is also not found ,then use default spi implementation. If no default implementation is configed, then the method will throw IllegalStateException。if not configed , then default implement is lower case of the interfa [...]
<h2>Callback Function</h2>
<h3>1. Parameter Callback</h3>
<p>main theory : in the persistent connection for one consumer->provider,export a service in Consumer side,provider side can reversely call the instance in consumer side.</p>
diff --git a/en-us/docs/dev/code-smell.json b/en-us/docs/dev/code-smell.json
index 1db05cc..9ec087a 100644
--- a/en-us/docs/dev/code-smell.json
+++ b/en-us/docs/dev/code-smell.json
@@ -1,6 +1,6 @@
{
"filename": "code-smell.md",
- "__html": "<h1>Bad Smell</h1>\n<p>Ugly Dubbo design or implementation will be record here.</p>\n<h2>URL Convertion</h2>\n<h3>1. Point to Point Service export and refer</h3>\n<p>service directly export:</p>\n<pre><code>EXPORT(dubbo://provider-address/com.xxx.XxxService?version=1.0.0")\n</code></pre>\n<p>service directly refer:</p>\n<pre><code>REFER(dubbo://provider-address/com.xxx.XxxService?version=1.0.0)\n</code></pre>\n<h3>2. Export servie by registry</h3>\n<p>export service to [...]
+ "__html": "<h1>Bad Smell</h1>\n<p>Ugly Dubbo design or implementation will be record here.</p>\n<h2>URL Convertion</h2>\n<h3>1. Point to Point Service export and refer</h3>\n<p>service directly export:</p>\n<pre><code>EXPORT(dubbo://provider-address/com.xxx.XxxService?version=1.0.0")\n</code></pre>\n<p>service directly refer:</p>\n<pre><code>REFER(dubbo://provider-address/com.xxx.XxxService?version=1.0.0)\n</code></pre>\n<h3>2. Export servie by registry</h3>\n<p>export service to [...]
"link": "/en-us/docs/dev/code-smell.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/implementation.html b/en-us/docs/dev/implementation.html
index 570a02b..24a3540 100644
--- a/en-us/docs/dev/implementation.html
+++ b/en-us/docs/dev/implementation.html
@@ -25,7 +25,7 @@
<code>dubbo://service-host/com.foo.FooService?version=1.0.0</code>.</p>
<p>Based on extension point adaptive mechanism, call <code>export()</code> method of <code>DubboProtocol</code> and open server port by identifying <code>dubbo://</code> protocol header of URL.</p>
<h4>2. Expose to Registry:</h4>
-<p>Expose provider address to Registry <sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup>, the URL format which parsing by <code>ServiceConfig</code>: <code>registry://registry-host/com.alibaba.dubbo.registry.RegistryService?export=URL.encode("dubbo://service-host/com.foo.FooService?version=1.0.0")</code>,</p>
+<p>Expose provider address to Registry <sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup>, the URL format which parsing by <code>ServiceConfig</code>: <code>registry://registry-host/org.apache.dubbo.registry.RegistryService?export=URL.encode("dubbo://service-host/com.foo.FooService?version=1.0.0")</code>,</p>
<p>Based on extension point adaptive mechanism, call <code>export()</code> method of <code>RegistryProtocol</code> by identifying <code>registry://</code> protocol header, register the provider URL parameter of <code>export</code> to Registry.</p>
<p>Resend to <code>Protocol</code> extension point to do exposure: <code>dubbo://service-host/com.foo.FooService?version=1.0.0</code>, then based on extension point adaptive mechanism, call <code>export()</code> method of <code>DubboProtocol</code> and open server port by identifying <code>dubbo://</code> protocol header of provider URL.</p>
<h3>Service Reference</h3>
@@ -34,7 +34,7 @@
<p>Based on extension point adaptive mechanism, call <code>refer()</code> method of <code>DubboProtocol</code> by identifying <code>dubbo://</code> protocol header of URL, and return provider reference.</p>
<h4>2. Service Registry discovery</h4>
<p>Discover provider address by Registry <sup class="footnote-ref"><a href="#fn4" id="fnref4">[4]</a></sup>, the URL format which parsing by <code>ReferenceConfig</code>:
-<code>registry://registry-host/com.alibaba.dubbo.registry.RegistryService?refer=URL.encode("consumer://consumer-host/com.foo.FooService?version=1.0.0")</code>.</p>
+<code>registry://registry-host/org.apache.dubbo.registry.RegistryService?refer=URL.encode("consumer://consumer-host/com.foo.FooService?version=1.0.0")</code>.</p>
<p>Based on extension point adaptive mechanism, call <code>refer()</code> method of <code>RegistryProtocol</code> by identifying <code>registry://</code> protocol header of URL, then based on the condition of parameter of <code>refer</code> to search provider URL, for example: <code>dubbo://service-host/com.foo.FooService?version=1.0.0</code>.</p>
<p>Then based on extension point adaptive mechanism, call <code>refer()</code> method of <code>DubboProtocol</code> to get provider reference by identifying <code>dubbo://</code> protocol header of provider URL.</p>
<p>Then <code>RegistryProtocol</code> disguise various provider references to single provider by <code>Cluster</code> extension point and return.</p>
diff --git a/en-us/docs/dev/implementation.json b/en-us/docs/dev/implementation.json
index 0cdee0c..05b2205 100644
--- a/en-us/docs/dev/implementation.json
+++ b/en-us/docs/dev/implementation.json
@@ -1,6 +1,6 @@
{
"filename": "implementation.md",
- "__html": "<h1>Implementation details</h1>\n<h2>Initialization details</h2>\n<h3>Service parsing</h3>\n<p>Based on <code>META-INF/spring.handlers</code> config in dubbo.jar, Spring calls <code>DubboNamespaceHandler</code> when meeting dubbo namespace.</p>\n<p>All Dubbo tags are parsed by <code>DubboBeanDefinitionParser</code>, based on one to one attribute mapping, the XML label is parsed as a Bean object.</p>\n<p>Transfer Bean object to URL, and transfer all attributes of Bean to URL [...]
+ "__html": "<h1>Implementation details</h1>\n<h2>Initialization details</h2>\n<h3>Service parsing</h3>\n<p>Based on <code>META-INF/spring.handlers</code> config in dubbo.jar, Spring calls <code>DubboNamespaceHandler</code> when meeting dubbo namespace.</p>\n<p>All Dubbo tags are parsed by <code>DubboBeanDefinitionParser</code>, based on one to one attribute mapping, the XML label is parsed as a Bean object.</p>\n<p>Transfer Bean object to URL, and transfer all attributes of Bean to URL [...]
"link": "/en-us/docs/dev/implementation.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/cache.html b/en-us/docs/dev/impls/cache.html
index e7b755d..cedaf1d 100644
--- a/en-us/docs/dev/impls/cache.html
+++ b/en-us/docs/dev/impls/cache.html
@@ -16,7 +16,7 @@
<h2>Summary</h2>
<p>Cache the return value, use request parameter as the key.</p>
<h2>Extension Interface</h2>
-<p><code>com.alibaba.dubbo.cache.CacheFactory</code></p>
+<p><code>org.apache.dubbo.cache.CacheFactory</code></p>
<h2>Extension Configuration</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">cache</span>=<span class="hljs-string">"lru"</span> /></span>
<span class="hljs-comment"><!-- method level cache --></span>
@@ -27,9 +27,9 @@
</code></pre>
<h2>Existing Extensions</h2>
<ul>
-<li><code>com.alibaba.dubbo.cache.support.lru.LruCacheFactory</code></li>
-<li><code>com.alibaba.dubbo.cache.support.threadlocal.ThreadLocalCacheFactory</code></li>
-<li><code>com.alibaba.dubbo.cache.support.jcache.JCacheFactory</code></li>
+<li><code>org.apache.dubbo.cache.support.lru.LruCacheFactory</code></li>
+<li><code>org.apache.dubbo.cache.support.threadlocal.ThreadLocalCacheFactory</code></li>
+<li><code>org.apache.dubbo.cache.support.jcache.JCacheFactory</code></li>
</ul>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
@@ -42,12 +42,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.cache.CacheFactory (plain text file with contents: xxx=com.xxx.XxxCacheFactory)
+ |-org.apache.dubbo.cache.CacheFactory (plain text file with contents: xxx=com.xxx.XxxCacheFactory)
</code></pre>
<p>XxxCacheFactory.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.cache.CacheFactory;
+<span class="hljs-keyword">import</span> org.apache.dubbo.cache.CacheFactory;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxCacheFactory</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">CacheFactory</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Cache <span class="hljs-title">getCache</span><span class="hljs-params">(URL url, String name)</span> </span>{
@@ -58,7 +58,7 @@
<p>XxxCacheFactory.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.cache.Cache;
+<span class="hljs-keyword">import</span> org.apache.dubbo.cache.Cache;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxCache</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Cache</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Cache</span><span class="hljs-params">(URL url, String name)</span> </span>{
@@ -72,7 +72,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.cache.CacheFactory:</p>
+<p>META-INF/dubbo/org.apache.dubbo.cache.CacheFactory:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxCacheFactory</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/cache.json b/en-us/docs/dev/impls/cache.json
index ff1ad89..b8a6ab5 100644
--- a/en-us/docs/dev/impls/cache.json
+++ b/en-us/docs/dev/impls/cache.json
@@ -1,6 +1,6 @@
{
"filename": "cache.md",
- "__html": "<h1>Cache Extension</h1>\n<h2>Summary</h2>\n<p>Cache the return value, use request parameter as the key.</p>\n<h2>Extension Interface</h2>\n<p><code>com.alibaba.dubbo.cache.CacheFactory</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:service</span> <span class=\"hljs-attr\">cache</span>=<span class=\"hljs-string\">\"lru\"</span> /></span>\n<span class=\"hljs-comment\"><!-- meth [...]
+ "__html": "<h1>Cache Extension</h1>\n<h2>Summary</h2>\n<p>Cache the return value, use request parameter as the key.</p>\n<h2>Extension Interface</h2>\n<p><code>org.apache.dubbo.cache.CacheFactory</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:service</span> <span class=\"hljs-attr\">cache</span>=<span class=\"hljs-string\">\"lru\"</span> /></span>\n<span class=\"hljs-comment\"><!-- metho [...]
"link": "/en-us/docs/dev/impls/cache.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/cluster.html b/en-us/docs/dev/impls/cluster.html
index 7ed81b8..32d08a0 100644
--- a/en-us/docs/dev/impls/cluster.html
+++ b/en-us/docs/dev/impls/cluster.html
@@ -16,7 +16,7 @@
<h2>Summary</h2>
<p>Group service providers in a cluster, and treat them as one single provider.</p>
<h2>Extension Interface</h2>
-<p><code>com.alibaba.dubbo.rpc.cluster.Cluster</code></p>
+<p><code>org.apache.dubbo.rpc.cluster.Cluster</code></p>
<h2>Extension Configuration</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">cluster</span>=<span class="hljs-string">"xxx"</span> /></span>
<span class="hljs-comment"><!-- default configuration, will take affect if cluster attribute is not configured in <dubbo:protocol> --></span>
@@ -24,12 +24,12 @@
</code></pre>
<h2>Existing Extensions</h2>
<ul>
-<li><code>com.alibaba.dubbo.rpc.cluster.support.FailoverCluster</code></li>
-<li><code>com.alibaba.dubbo.rpc.cluster.support.FailfastCluster</code></li>
-<li><code>com.alibaba.dubbo.rpc.cluster.support.FailsafeCluster</code></li>
-<li><code>com.alibaba.dubbo.rpc.cluster.support.FailbackCluster</code></li>
-<li><code>com.alibaba.dubbo.rpc.cluster.support.ForkingCluster</code></li>
-<li><code>com.alibaba.dubbo.rpc.cluster.support.AvailableCluster</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.support.FailoverCluster</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.support.FailfastCluster</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.support.FailsafeCluster</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.support.FailbackCluster</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.support.ForkingCluster</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.support.AvailableCluster</code></li>
</ul>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
@@ -42,19 +42,19 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.rpc.cluster.Cluster (plain text file with the content: xxx=com.xxx.XxxCluster)
+ |-org.apache.dubbo.rpc.cluster.Cluster (plain text file with the content: xxx=com.xxx.XxxCluster)
</code></pre>
<p>XxxCluster.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.cluster.Cluster;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.cluster.Directory;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.cluster.LoadBalance;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Invoker;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Invocation;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Result;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.RpcException;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.cluster.Cluster;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.cluster.Directory;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.cluster.LoadBalance;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Invoker;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Invocation;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Result;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.RpcException;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxCluster</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Cluster</span> </span>{
<span class="hljs-keyword">public</span> <T> <span class="hljs-function">Invoker<T> <span class="hljs-title">merge</span><span class="hljs-params">(Directory<T> directory)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
@@ -66,7 +66,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.rpc.cluster.Cluster:</p>
+<p>META-INF/dubbo/org.apache.dubbo.rpc.cluster.Cluster:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxCluster</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/cluster.json b/en-us/docs/dev/impls/cluster.json
index f939340..488e489 100644
--- a/en-us/docs/dev/impls/cluster.json
+++ b/en-us/docs/dev/impls/cluster.json
@@ -1,6 +1,6 @@
{
"filename": "cluster.md",
- "__html": "<h1>Cluster Extension</h1>\n<h2>Summary</h2>\n<p>Group service providers in a cluster, and treat them as one single provider.</p>\n<h2>Extension Interface</h2>\n<p><code>com.alibaba.dubbo.rpc.cluster.Cluster</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">cluster</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n<span class=\"hl [...]
+ "__html": "<h1>Cluster Extension</h1>\n<h2>Summary</h2>\n<p>Group service providers in a cluster, and treat them as one single provider.</p>\n<h2>Extension Interface</h2>\n<p><code>org.apache.dubbo.rpc.cluster.Cluster</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">cluster</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n<span class=\"hlj [...]
"link": "/en-us/docs/dev/impls/cluster.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/compiler.html b/en-us/docs/dev/impls/compiler.html
index eb69144..b411fa8 100644
--- a/en-us/docs/dev/impls/compiler.html
+++ b/en-us/docs/dev/impls/compiler.html
@@ -16,13 +16,13 @@
<h2>Summary</h2>
<p>Java compiler, used for byte code dynamic generation for RPC invocation.</p>
<h2>Extension Interface</h2>
-<p><code>com.alibaba.dubbo.common.compiler.Compiler</code></p>
+<p><code>org.apache.dubbo.common.compiler.Compiler</code></p>
<h2>Extension Configuration</h2>
<p>No configuration required, the extension will be automatically discovered and loaded.</p>
<h2>Existing Extensions</h2>
<ul>
-<li><code>com.alibaba.dubbo.common.compiler.support.JdkCompiler</code></li>
-<li><code>com.alibaba.dubbo.common.compiler.support.JavassistCompiler</code></li>
+<li><code>org.apache.dubbo.common.compiler.support.JdkCompiler</code></li>
+<li><code>org.apache.dubbo.common.compiler.support.JavassistCompiler</code></li>
</ul>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
@@ -35,12 +35,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.common.compiler.Compiler (plain text file with the content: xxx=com.xxx.XxxCompiler)
+ |-org.apache.dubbo.common.compiler.Compiler (plain text file with the content: xxx=com.xxx.XxxCompiler)
</code></pre>
<p>XxxCompiler.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.compiler.Compiler;
+<span class="hljs-keyword">import</span> org.apache.dubbo.common.compiler.Compiler;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxCompiler</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Compiler</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Object <span class="hljs-title">getExtension</span><span class="hljs-params">(Class<?> type, String name)</span> </span>{
@@ -48,7 +48,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.common.compiler.Compiler:</p>
+<p>META-INF/dubbo/org.apache.dubbo.common.compiler.Compiler:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxCompiler</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/compiler.json b/en-us/docs/dev/impls/compiler.json
index d4a55bf..c19cfb9 100644
--- a/en-us/docs/dev/impls/compiler.json
+++ b/en-us/docs/dev/impls/compiler.json
@@ -1,6 +1,6 @@
{
"filename": "compiler.md",
- "__html": "<h1>Compiler Extension</h1>\n<h2>Summary</h2>\n<p>Java compiler, used for byte code dynamic generation for RPC invocation.</p>\n<h2>Extension Interface</h2>\n<p><code>com.alibaba.dubbo.common.compiler.Compiler</code></p>\n<h2>Extension Configuration</h2>\n<p>No configuration required, the extension will be automatically discovered and loaded.</p>\n<h2>Existing Extensions</h2>\n<ul>\n<li><code>com.alibaba.dubbo.common.compiler.support.JdkCompiler</code></li>\n<li><code>com.al [...]
+ "__html": "<h1>Compiler Extension</h1>\n<h2>Summary</h2>\n<p>Java compiler, used for byte code dynamic generation for RPC invocation.</p>\n<h2>Extension Interface</h2>\n<p><code>org.apache.dubbo.common.compiler.Compiler</code></p>\n<h2>Extension Configuration</h2>\n<p>No configuration required, the extension will be automatically discovered and loaded.</p>\n<h2>Existing Extensions</h2>\n<ul>\n<li><code>org.apache.dubbo.common.compiler.support.JdkCompiler</code></li>\n<li><code>org.apac [...]
"link": "/en-us/docs/dev/impls/compiler.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/container.html b/en-us/docs/dev/impls/container.html
index 9f1d1ca..d596235 100644
--- a/en-us/docs/dev/impls/container.html
+++ b/en-us/docs/dev/impls/container.html
@@ -16,15 +16,15 @@
<h2>Summary</h2>
<p>Service container extension, useful for loading custom contents.</p>
<h2>Extension Interface</h2>
-<p><code>com.alibaba.dubbo.container.Container</code></p>
+<p><code>org.apache.dubbo.container.Container</code></p>
<h2>Extension Configuration</h2>
-<pre><code class="language-sh">java com.alibaba.dubbo.container.Main spring jetty log4j
+<pre><code class="language-sh">java org.apache.dubbo.container.Main spring jetty log4j
</code></pre>
<h2>Existing Extensions</h2>
<ul>
-<li><code>com.alibaba.dubbo.container.spring.SpringContainer</code></li>
-<li><code>com.alibaba.dubbo.container.spring.JettyContainer</code></li>
-<li><code>com.alibaba.dubbo.container.spring.Log4jContainer</code></li>
+<li><code>org.apache.dubbo.container.spring.SpringContainer</code></li>
+<li><code>org.apache.dubbo.container.spring.JettyContainer</code></li>
+<li><code>org.apache.dubbo.container.spring.Log4jContainer</code></li>
</ul>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
@@ -37,12 +37,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.container.Container (plain text file with the content: xxx=com.xxx.XxxContainer)
+ |-org.apache.dubbo.container.Container (plain text file with the content: xxx=com.xxx.XxxContainer)
</code></pre>
<p>XxxContainer.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-com.alibaba.dubbo.container.Container;
+org.apache.dubbo.container.Container;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxContainer</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Container</span> </span>{
@@ -54,7 +54,7 @@ com.alibaba.dubbo.container.Container;
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.container.Container:</p>
+<p>META-INF/dubbo/org.apache.dubbo.container.Container:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxContainer</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/container.json b/en-us/docs/dev/impls/container.json
index 95ae2c8..ba6f49d 100644
--- a/en-us/docs/dev/impls/container.json
+++ b/en-us/docs/dev/impls/container.json
@@ -1,6 +1,6 @@
{
"filename": "container.md",
- "__html": "<h1>Container Extension</h1>\n<h2>Summary</h2>\n<p>Service container extension, useful for loading custom contents.</p>\n<h2>Extension Interface</h2>\n<p><code>com.alibaba.dubbo.container.Container</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-sh\">java com.alibaba.dubbo.container.Main spring jetty log4j\n</code></pre>\n<h2>Existing Extensions</h2>\n<ul>\n<li><code>com.alibaba.dubbo.container.spring.SpringContainer</code></li>\n<li><code>com.aliba [...]
+ "__html": "<h1>Container Extension</h1>\n<h2>Summary</h2>\n<p>Service container extension, useful for loading custom contents.</p>\n<h2>Extension Interface</h2>\n<p><code>org.apache.dubbo.container.Container</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-sh\">java org.apache.dubbo.container.Main spring jetty log4j\n</code></pre>\n<h2>Existing Extensions</h2>\n<ul>\n<li><code>org.apache.dubbo.container.spring.SpringContainer</code></li>\n<li><code>org.apache.d [...]
"link": "/en-us/docs/dev/impls/container.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/dispatcher.html b/en-us/docs/dev/impls/dispatcher.html
index 7ba7132..8699c72 100644
--- a/en-us/docs/dev/impls/dispatcher.html
+++ b/en-us/docs/dev/impls/dispatcher.html
@@ -16,7 +16,7 @@
<h2>Summary</h2>
<p>Thread pool dispatch strategy.</p>
<h2>Extension Interface</h2>
-<p><code>com.alibaba.dubbo.remoting.Dispatcher</code></p>
+<p><code>org.apache.dubbo.remoting.Dispatcher</code></p>
<h2>Extension Configuration</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">dispatcher</span>=<span class="hljs-string">"xxx"</span> /></span>
<span class="hljs-comment"><!-- default configuration, will take effect if dispatcher attribute is not set in <dubbo:protocol> --></span>
@@ -24,11 +24,11 @@
</code></pre>
<h2>Existing Extensions</h2>
<ul>
-<li><code>com.alibaba.dubbo.remoting.transport.dispatcher.all.AllDispatcher</code></li>
-<li><code>com.alibaba.dubbo.remoting.transport.dispatcher.direct.DirectDispatcher</code></li>
-<li><code>com.alibaba.dubbo.remoting.transport.dispatcher.message.MessageOnlyDispatcher</code></li>
-<li><code>com.alibaba.dubbo.remoting.transport.dispatcher.execution.ExecutionDispatcher</code></li>
-<li><code>com.alibaba.dubbo.remoting.transport.dispatcher.connection.ConnectionOrderedDispatcher</code></li>
+<li><code>org.apache.dubbo.remoting.transport.dispatcher.all.AllDispatcher</code></li>
+<li><code>org.apache.dubbo.remoting.transport.dispatcher.direct.DirectDispatcher</code></li>
+<li><code>org.apache.dubbo.remoting.transport.dispatcher.message.MessageOnlyDispatcher</code></li>
+<li><code>org.apache.dubbo.remoting.transport.dispatcher.execution.ExecutionDispatcher</code></li>
+<li><code>org.apache.dubbo.remoting.transport.dispatcher.connection.ConnectionOrderedDispatcher</code></li>
</ul>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
@@ -41,12 +41,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.remoting.Dispatcher (plain text file with the content: xxx=com.xxx.XxxDispatcher)
+ |-org.apache.dubbo.remoting.Dispatcher (plain text file with the content: xxx=com.xxx.XxxDispatcher)
</code></pre>
<p>XxxDispatcher.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.remoting.Dispatcher;
+<span class="hljs-keyword">import</span> org.apache.dubbo.remoting.Dispatcher;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxDispatcher</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Dispatcher</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Group <span class="hljs-title">lookup</span><span class="hljs-params">(URL url)</span> </span>{
@@ -54,7 +54,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.remoting.Dispatcher:</p>
+<p>META-INF/dubbo/org.apache.dubbo.remoting.Dispatcher:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxDispatcher</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/dispatcher.json b/en-us/docs/dev/impls/dispatcher.json
index 63ad45c..45fd337 100644
--- a/en-us/docs/dev/impls/dispatcher.json
+++ b/en-us/docs/dev/impls/dispatcher.json
@@ -1,6 +1,6 @@
{
"filename": "dispatcher.md",
- "__html": "<h1>Dispatcher Extension</h1>\n<h2>Summary</h2>\n<p>Thread pool dispatch strategy.</p>\n<h2>Extension Interface</h2>\n<p><code>com.alibaba.dubbo.remoting.Dispatcher</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">dispatcher</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n<span class=\"hljs-comment\"><!-- default configurati [...]
+ "__html": "<h1>Dispatcher Extension</h1>\n<h2>Summary</h2>\n<p>Thread pool dispatch strategy.</p>\n<h2>Extension Interface</h2>\n<p><code>org.apache.dubbo.remoting.Dispatcher</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">dispatcher</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n<span class=\"hljs-comment\"><!-- default configuratio [...]
"link": "/en-us/docs/dev/impls/dispatcher.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/exchanger.html b/en-us/docs/dev/impls/exchanger.html
index 759c5e0..ddc185a 100644
--- a/en-us/docs/dev/impls/exchanger.html
+++ b/en-us/docs/dev/impls/exchanger.html
@@ -17,9 +17,9 @@
<p>Exchange message between request and response on network transport layer.</p>
<h2>Extension Interface</h2>
<ul>
-<li><code>com.alibaba.dubbo.remoting.exchange.Exchanger</code></li>
-<li><code>com.alibaba.dubbo.remoting.exchange.ExchangeServer</code></li>
-<li><code>com.alibaba.dubbo.remoting.exchange.ExchangeClient</code></li>
+<li><code>org.apache.dubbo.remoting.exchange.Exchanger</code></li>
+<li><code>org.apache.dubbo.remoting.exchange.ExchangeServer</code></li>
+<li><code>org.apache.dubbo.remoting.exchange.ExchangeClient</code></li>
</ul>
<h2>Extension Configuration</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">exchanger</span>=<span class="hljs-string">"xxx"</span> /></span>
@@ -27,7 +27,7 @@
<span class="hljs-tag"><<span class="hljs-name">dubbo:provider</span> <span class="hljs-attr">exchanger</span>=<span class="hljs-string">"xxx"</span> /></span>
</code></pre>
<h2>Existing Extension</h2>
-<p><code>com.alibaba.dubbo.remoting.exchange.exchanger.HeaderExchanger</code></p>
+<p><code>org.apache.dubbo.remoting.exchange.exchanger.HeaderExchanger</code></p>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
<pre><code>src
@@ -41,12 +41,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.remoting.exchange.Exchanger (plain text file with the content: xxx=com.xxx.XxxExchanger)
+ |-org.apache.dubbo.remoting.exchange.Exchanger (plain text file with the content: xxx=com.xxx.XxxExchanger)
</code></pre>
<p>XxxExchanger.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.remoting.exchange.Exchanger;
+<span class="hljs-keyword">import</span> org.apache.dubbo.remoting.exchange.Exchanger;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxExchanger</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Exchanger</span> </span>{
@@ -62,7 +62,7 @@
<pre><code class="language-java">
<span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.remoting.exchange.ExchangeServer;
+<span class="hljs-keyword">import</span> org.apache.dubbo.remoting.exchange.ExchangeServer;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxExchangeServer</span> <span class="hljs-title">impelements</span> <span class="hljs-title">ExchangeServer</span> </span>{
<span class="hljs-comment">// ...</span>
@@ -71,13 +71,13 @@
<p>XxxExchangeClient.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.remoting.exchange.ExchangeClient;
+<span class="hljs-keyword">import</span> org.apache.dubbo.remoting.exchange.ExchangeClient;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxExchangeClient</span> <span class="hljs-title">impelments</span> <span class="hljs-title">ExchangeClient</span> </span>{
<span class="hljs-comment">// ...</span>
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.remoting.exchange.Exchanger:</p>
+<p>META-INF/dubbo/org.apache.dubbo.remoting.exchange.Exchanger:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxExchanger</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/exchanger.json b/en-us/docs/dev/impls/exchanger.json
index a946c92..9b2a571 100644
--- a/en-us/docs/dev/impls/exchanger.json
+++ b/en-us/docs/dev/impls/exchanger.json
@@ -1,6 +1,6 @@
{
"filename": "exchanger.md",
- "__html": "<h1>Exchanger Extension</h1>\n<h2>Summary</h2>\n<p>Exchange message between request and response on network transport layer.</p>\n<h2>Extension Interface</h2>\n<ul>\n<li><code>com.alibaba.dubbo.remoting.exchange.Exchanger</code></li>\n<li><code>com.alibaba.dubbo.remoting.exchange.ExchangeServer</code></li>\n<li><code>com.alibaba.dubbo.remoting.exchange.ExchangeClient</code></li>\n</ul>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-ta [...]
+ "__html": "<h1>Exchanger Extension</h1>\n<h2>Summary</h2>\n<p>Exchange message between request and response on network transport layer.</p>\n<h2>Extension Interface</h2>\n<ul>\n<li><code>org.apache.dubbo.remoting.exchange.Exchanger</code></li>\n<li><code>org.apache.dubbo.remoting.exchange.ExchangeServer</code></li>\n<li><code>org.apache.dubbo.remoting.exchange.ExchangeClient</code></li>\n</ul>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\" [...]
"link": "/en-us/docs/dev/impls/exchanger.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/exporter-listener.html b/en-us/docs/dev/impls/exporter-listener.html
index 2eb18e5..0a7e158 100644
--- a/en-us/docs/dev/impls/exporter-listener.html
+++ b/en-us/docs/dev/impls/exporter-listener.html
@@ -16,7 +16,7 @@
<h2>Summary</h2>
<p>Fire events when there's any service exported.</p>
<h2>Extension Interface</h2>
-<p><code>com.alibaba.dubbo.rpc.ExporterListener</code></p>
+<p><code>org.apache.dubbo.rpc.ExporterListener</code></p>
<h2>Extension Configuration</h2>
<pre><code class="language-xml"><span class="hljs-comment"><!-- service exporter listener --></span>
<span class="hljs-tag"><<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">listener</span>=<span class="hljs-string">"xxx,yyy"</span> /></span>
@@ -24,7 +24,7 @@
<span class="hljs-tag"><<span class="hljs-name">dubbo:provider</span> <span class="hljs-attr">listener</span>=<span class="hljs-string">"xxx,yyy"</span> /></span>
</code></pre>
<h2>Existing Extension</h2>
-<p><code>com.alibaba.dubbo.registry.directory.RegistryExporterListener</code></p>
+<p><code>org.apache.dubbo.registry.directory.RegistryExporterListener</code></p>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
<pre><code>src
@@ -36,14 +36,14 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.rpc.ExporterListener (plain text file with the content: xxx=com.xxx.XxxExporterListener)
+ |-org.apache.dubbo.rpc.ExporterListener (plain text file with the content: xxx=com.xxx.XxxExporterListener)
</code></pre>
<p>XxxExporterListener.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.ExporterListener;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Exporter;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.RpcException;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.ExporterListener;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Exporter;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.RpcException;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxExporterListener</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">ExporterListener</span> </span>{
@@ -55,7 +55,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.rpc.ExporterListener:</p>
+<p>META-INF/dubbo/org.apache.dubbo.rpc.ExporterListener:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxExporterListener</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/exporter-listener.json b/en-us/docs/dev/impls/exporter-listener.json
index 52f2dbe..ea8d4a6 100644
--- a/en-us/docs/dev/impls/exporter-listener.json
+++ b/en-us/docs/dev/impls/exporter-listener.json
@@ -1,6 +1,6 @@
{
"filename": "exporter-listener.md",
- "__html": "<h1>ExporterListener Extension</h1>\n<h2>Summary</h2>\n<p>Fire events when there's any service exported.</p>\n<h2>Extension Interface</h2>\n<p><code>com.alibaba.dubbo.rpc.ExporterListener</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-comment\"><!-- service exporter listener --></span>\n<span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:service</span> <span class=\"hljs-attr\">listener</span>=<span class=\"h [...]
+ "__html": "<h1>ExporterListener Extension</h1>\n<h2>Summary</h2>\n<p>Fire events when there's any service exported.</p>\n<h2>Extension Interface</h2>\n<p><code>org.apache.dubbo.rpc.ExporterListener</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-comment\"><!-- service exporter listener --></span>\n<span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:service</span> <span class=\"hljs-attr\">listener</span>=<span class=\"hl [...]
"link": "/en-us/docs/dev/impls/exporter-listener.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/extension-factory.html b/en-us/docs/dev/impls/extension-factory.html
index 05a8736..6d11ea9 100644
--- a/en-us/docs/dev/impls/extension-factory.html
+++ b/en-us/docs/dev/impls/extension-factory.html
@@ -16,14 +16,14 @@
<h2>Summary</h2>
<p>Factory to load dubbo extensions.</p>
<h2>Extension Interface</h2>
-<p><code>com.alibaba.dubbo.common.extension.ExtensionFactory</code></p>
+<p><code>org.apache.dubbo.common.extension.ExtensionFactory</code></p>
<h2>Extension Configuration</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:application</span> <span class="hljs-attr">compiler</span>=<span class="hljs-string">"jdk"</span> /></span>
</code></pre>
<h2>Existing Extension</h2>
<ul>
-<li><code>com.alibaba.dubbo.common.extension.factory.SpiExtensionFactory</code></li>
-<li><code>com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory</code></li>
+<li><code>org.apache.dubbo.common.extension.factory.SpiExtensionFactory</code></li>
+<li><code>org.apache.dubbo.config.spring.extension.SpringExtensionFactory</code></li>
</ul>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
@@ -36,12 +36,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.common.extension.ExtensionFactory (plain text file with the content: xxx=com.xxx.XxxExtensionFactory)
+ |-org.apache.dubbo.common.extension.ExtensionFactory (plain text file with the content: xxx=com.xxx.XxxExtensionFactory)
</code></pre>
<p>XxxExtensionFactory.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.extension.ExtensionFactory;
+<span class="hljs-keyword">import</span> org.apache.dubbo.common.extension.ExtensionFactory;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxExtensionFactory</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">ExtensionFactory</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Object <span class="hljs-title">getExtension</span><span class="hljs-params">(Class<?> type, String name)</span> </span>{
@@ -49,7 +49,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.common.extension.ExtensionFactory:</p>
+<p>META-INF/dubbo/org.apache.dubbo.common.extension.ExtensionFactory:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxExtensionFactory</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/extension-factory.json b/en-us/docs/dev/impls/extension-factory.json
index 8d6b433..7163c9b 100644
--- a/en-us/docs/dev/impls/extension-factory.json
+++ b/en-us/docs/dev/impls/extension-factory.json
@@ -1,6 +1,6 @@
{
"filename": "extension-factory.md",
- "__html": "<h1>ExtensionFactory Extension</h1>\n<h2>Summary</h2>\n<p>Factory to load dubbo extensions.</p>\n<h2>Extension Interface</h2>\n<p><code>com.alibaba.dubbo.common.extension.ExtensionFactory</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:application</span> <span class=\"hljs-attr\">compiler</span>=<span class=\"hljs-string\">\"jdk\"</span> /></span>\n</code></pre>\n<h2>Existing Exte [...]
+ "__html": "<h1>ExtensionFactory Extension</h1>\n<h2>Summary</h2>\n<p>Factory to load dubbo extensions.</p>\n<h2>Extension Interface</h2>\n<p><code>org.apache.dubbo.common.extension.ExtensionFactory</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:application</span> <span class=\"hljs-attr\">compiler</span>=<span class=\"hljs-string\">\"jdk\"</span> /></span>\n</code></pre>\n<h2>Existing Exten [...]
"link": "/en-us/docs/dev/impls/extension-factory.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/filter.html b/en-us/docs/dev/impls/filter.html
index 8e6379c..20ddfab 100644
--- a/en-us/docs/dev/impls/filter.html
+++ b/en-us/docs/dev/impls/filter.html
@@ -23,7 +23,7 @@
<li>When provider and service have filter configured at the same moment, all filters are accumulated together instead of override, for example: for <code><dubbo:provider filter="xxx,yyy"/></code> and <code><dubbo:service filter="aaa,bbb" /></code>,<code>xxx</code>, <code>yyy</code>, <code>aaa</code>, <code>bbb</code> are all count as filters. In order to change to override, use: <code><dubbo:service filter="-xxx,-yyy,aaa,bbb" /></code></li>
</ul>
<h2>Extension Interface</h2>
-<p><code>com.alibaba.dubbo.rpc.Filter</code></p>
+<p><code>org.apache.dubbo.rpc.Filter</code></p>
<h2>Extension Configuration</h2>
<pre><code class="language-xml"><span class="hljs-comment"><!-- filter for consumer --></span>
<span class="hljs-tag"><<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">filter</span>=<span class="hljs-string">"xxx,yyy"</span> /></span>
@@ -36,19 +36,19 @@
</code></pre>
<h2>Existing Extension</h2>
<ul>
-<li><code>com.alibaba.dubbo.rpc.filter.EchoFilter</code></li>
-<li><code>com.alibaba.dubbo.rpc.filter.GenericFilter</code></li>
-<li><code>com.alibaba.dubbo.rpc.filter.GenericImplFilter</code></li>
-<li><code>com.alibaba.dubbo.rpc.filter.TokenFilter</code></li>
-<li><code>com.alibaba.dubbo.rpc.filter.AccessLogFilter</code></li>
-<li><code>com.alibaba.dubbo.rpc.filter.CountFilter</code></li>
-<li><code>com.alibaba.dubbo.rpc.filter.ActiveLimitFilter</code></li>
-<li><code>com.alibaba.dubbo.rpc.filter.ClassLoaderFilter</code></li>
-<li><code>com.alibaba.dubbo.rpc.filter.ContextFilter</code></li>
-<li><code>com.alibaba.dubbo.rpc.filter.ConsumerContextFilter</code></li>
-<li><code>com.alibaba.dubbo.rpc.filter.ExceptionFilter</code></li>
-<li><code>com.alibaba.dubbo.rpc.filter.ExecuteLimitFilter</code></li>
-<li><code>com.alibaba.dubbo.rpc.filter.DeprecatedFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.EchoFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.GenericFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.GenericImplFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.TokenFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.AccessLogFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.CountFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.ActiveLimitFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.ClassLoaderFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.ContextFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.ConsumerContextFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.ExceptionFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.ExecuteLimitFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.DeprecatedFilter</code></li>
</ul>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
@@ -61,16 +61,16 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.rpc.Filter (plain text file with the content: xxx=com.xxx.XxxFilter)
+ |-org.apache.dubbo.rpc.Filter (plain text file with the content: xxx=com.xxx.XxxFilter)
</code></pre>
<p>XxxFilter.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Filter;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Invoker;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Invocation;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Result;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.RpcException;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Filter;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Invoker;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Invocation;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Result;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.RpcException;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxFilter</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Filter</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Result <span class="hljs-title">invoke</span><span class="hljs-params">(Invoker<?> invoker, Invocation invocation)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
@@ -81,7 +81,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.rpc.Filter:</p>
+<p>META-INF/dubbo/org.apache.dubbo.rpc.Filter:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxFilter</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/filter.json b/en-us/docs/dev/impls/filter.json
index b234cb6..b933e24 100644
--- a/en-us/docs/dev/impls/filter.json
+++ b/en-us/docs/dev/impls/filter.json
@@ -1,6 +1,6 @@
{
"filename": "filter.md",
- "__html": "<h1>Filter Extension</h1>\n<h2>Summary</h2>\n<p>Extension for intercepting the invocation for both service provider and consumer, furthermore, most of functions in dubbo are implemented base on the same mechanism. Since every time when remote method is invoked, the filter extensions will be executed too, the corresponding penalty should be considered before more filters are added.</p>\n<p>Contract:</p>\n<ul>\n<li>User defined filters are executed after built-in filters by de [...]
+ "__html": "<h1>Filter Extension</h1>\n<h2>Summary</h2>\n<p>Extension for intercepting the invocation for both service provider and consumer, furthermore, most of functions in dubbo are implemented base on the same mechanism. Since every time when remote method is invoked, the filter extensions will be executed too, the corresponding penalty should be considered before more filters are added.</p>\n<p>Contract:</p>\n<ul>\n<li>User defined filters are executed after built-in filters by de [...]
"link": "/en-us/docs/dev/impls/filter.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/invoker-listener.html b/en-us/docs/dev/impls/invoker-listener.html
index f22c3c0..5c841db 100644
--- a/en-us/docs/dev/impls/invoker-listener.html
+++ b/en-us/docs/dev/impls/invoker-listener.html
@@ -16,7 +16,7 @@
<h2>Summary</h2>
<p>Fire event when there's any service referenced.</p>
<h2>Extension Interface</h2>
-<p><code>com.alibaba.dubbo.rpc.InvokerListener</code></p>
+<p><code>org.apache.dubbo.rpc.InvokerListener</code></p>
<h2>Extension Configuration</h2>
<pre><code class="language-xml"><span class="hljs-comment"><!-- 引用服务监听 --></span>
<span class="hljs-comment"><!-- service reference listener --></span>
@@ -25,7 +25,7 @@
<span class="hljs-tag"><<span class="hljs-name">dubbo:consumer</span> <span class="hljs-attr">listener</span>=<span class="hljs-string">"xxx,yyy"</span> /></span>
</code></pre>
<h2>Existing Extension</h2>
-<p><code>com.alibaba.dubbo.rpc.listener.DeprecatedInvokerListener</code></p>
+<p><code>org.apache.dubbo.rpc.listener.DeprecatedInvokerListener</code></p>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
<pre><code>src
@@ -37,14 +37,14 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.rpc.InvokerListener (plain text file with the content: xxx=com.xxx.XxxInvokerListener)
+ |-org.apache.dubbo.rpc.InvokerListener (plain text file with the content: xxx=com.xxx.XxxInvokerListener)
</code></pre>
<p>XxxInvokerListener.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.InvokerListener;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Invoker;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.RpcException;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.InvokerListener;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Invoker;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.RpcException;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxInvokerListener</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">InvokerListener</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">referred</span><span class="hljs-params">(Invoker<?> invoker)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
@@ -55,7 +55,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.rpc.InvokerListener:</p>
+<p>META-INF/dubbo/org.apache.dubbo.rpc.InvokerListener:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxInvokerListener</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/invoker-listener.json b/en-us/docs/dev/impls/invoker-listener.json
index d2927c2..4787e92 100644
--- a/en-us/docs/dev/impls/invoker-listener.json
+++ b/en-us/docs/dev/impls/invoker-listener.json
@@ -1,6 +1,6 @@
{
"filename": "invoker-listener.md",
- "__html": "<h1>InvokerListener Extension</h1>\n<h2>Summary</h2>\n<p>Fire event when there's any service referenced.</p>\n<h2>Extension Interface</h2>\n<p><code>com.alibaba.dubbo.rpc.InvokerListener</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-comment\"><!-- 引用服务监听 --></span>\n<span class=\"hljs-comment\"><!-- service reference listener --></span>\n<span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:reference</sp [...]
+ "__html": "<h1>InvokerListener Extension</h1>\n<h2>Summary</h2>\n<p>Fire event when there's any service referenced.</p>\n<h2>Extension Interface</h2>\n<p><code>org.apache.dubbo.rpc.InvokerListener</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-comment\"><!-- 引用服务监听 --></span>\n<span class=\"hljs-comment\"><!-- service reference listener --></span>\n<span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:reference</spa [...]
"link": "/en-us/docs/dev/impls/invoker-listener.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/load-balance.html b/en-us/docs/dev/impls/load-balance.html
index 3626d07..ac82b83 100644
--- a/en-us/docs/dev/impls/load-balance.html
+++ b/en-us/docs/dev/impls/load-balance.html
@@ -16,7 +16,7 @@
<h2>Summary</h2>
<p>Pick one from service providers and fire the invocation.</p>
<h2>Extension Interface</h2>
-<p><code>com.alibaba.dubbo.rpc.cluster.LoadBalance</code></p>
+<p><code>org.apache.dubbo.rpc.cluster.LoadBalance</code></p>
<h2>Extension Configuration</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">loadbalance</span>=<span class="hljs-string">"xxx"</span> /></span>
<span class="hljs-comment"><!-- default configuration, will take effect when loadbalance is not configured in <dubbo:protocol> --></span>
@@ -24,9 +24,9 @@
</code></pre>
<h2>Existing Extension</h2>
<ul>
-<li><code>com.alibaba.dubbo.rpc.cluster.loadbalance.RandomLoadBalance</code></li>
-<li><code>com.alibaba.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance</code></li>
-<li><code>com.alibaba.dubbo.rpc.cluster.loadbalance.LeastActiveLoadBalance</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.loadbalance.RandomLoadBalance</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.loadbalance.LeastActiveLoadBalance</code></li>
</ul>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
@@ -39,15 +39,15 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.rpc.cluster.LoadBalance (plain text file with the content: xxx=com.xxx.XxxLoadBalance)
+ |-org.apache.dubbo.rpc.cluster.LoadBalance (plain text file with the content: xxx=com.xxx.XxxLoadBalance)
</code></pre>
<p>XxxLoadBalance.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.cluster.LoadBalance;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Invoker;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Invocation;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.RpcException;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.cluster.LoadBalance;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Invoker;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Invocation;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.RpcException;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxLoadBalance</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">LoadBalance</span> </span>{
<span class="hljs-keyword">public</span> <T> <span class="hljs-function">Invoker<T> <span class="hljs-title">select</span><span class="hljs-params">(List<Invoker<T>> invokers, Invocation invocation)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
@@ -55,7 +55,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.rpc.cluster.LoadBalance:</p>
+<p>META-INF/dubbo/org.apache.dubbo.rpc.cluster.LoadBalance:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxLoadBalance</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/load-balance.json b/en-us/docs/dev/impls/load-balance.json
index 9b10504..b4a3816 100644
--- a/en-us/docs/dev/impls/load-balance.json
+++ b/en-us/docs/dev/impls/load-balance.json
@@ -1,6 +1,6 @@
{
"filename": "load-balance.md",
- "__html": "<h1>LoadBalance Extension</h1>\n<h2>Summary</h2>\n<p>Pick one from service providers and fire the invocation.</p>\n<h2>Extension Interface</h2>\n<p><code>com.alibaba.dubbo.rpc.cluster.LoadBalance</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">loadbalance</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n<span class=\"hljs-comme [...]
+ "__html": "<h1>LoadBalance Extension</h1>\n<h2>Summary</h2>\n<p>Pick one from service providers and fire the invocation.</p>\n<h2>Extension Interface</h2>\n<p><code>org.apache.dubbo.rpc.cluster.LoadBalance</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">loadbalance</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n<span class=\"hljs-commen [...]
"link": "/en-us/docs/dev/impls/load-balance.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/logger-adapter.html b/en-us/docs/dev/impls/logger-adapter.html
index edd3536..5052eae 100644
--- a/en-us/docs/dev/impls/logger-adapter.html
+++ b/en-us/docs/dev/impls/logger-adapter.html
@@ -16,7 +16,7 @@
<h2>Summary</h2>
<p>Extension for adapting logger output</p>
<h2>Extension Interface</h2>
-<p><code>com.alibaba.dubbo.common.logger.LoggerAdapter</code></p>
+<p><code>org.apache.dubbo.common.logger.LoggerAdapter</code></p>
<h2>Extension Configuration</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:application</span> <span class="hljs-attr">logger</span>=<span class="hljs-string">"xxx"</span> /></span>
</code></pre>
@@ -25,11 +25,11 @@
</code></pre>
<h2>Existing Extension</h2>
<ul>
-<li><code>com.alibaba.dubbo.common.logger.slf4j.Slf4jLoggerAdapter</code></li>
-<li><code>com.alibaba.dubbo.common.logger.jcl.JclLoggerAdapter</code></li>
-<li><code>com.alibaba.dubbo.common.logger.log4j.Log4jLoggerAdapter</code></li>
-<li><code>com.alibaba.dubbo.common.logger.log4j2.Log4j2LoggerAdapter</code></li>
-<li><code>com.alibaba.dubbo.common.logger.jdk.JdkLoggerAdapter</code></li>
+<li><code>org.apache.dubbo.common.logger.slf4j.Slf4jLoggerAdapter</code></li>
+<li><code>org.apache.dubbo.common.logger.jcl.JclLoggerAdapter</code></li>
+<li><code>org.apache.dubbo.common.logger.log4j.Log4jLoggerAdapter</code></li>
+<li><code>org.apache.dubbo.common.logger.log4j2.Log4j2LoggerAdapter</code></li>
+<li><code>org.apache.dubbo.common.logger.jdk.JdkLoggerAdapter</code></li>
</ul>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
@@ -42,12 +42,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.common.logger.LoggerAdapter (plain text file with the content: xxx=com.xxx.XxxLoggerAdapter)
+ |-org.apache.dubbo.common.logger.LoggerAdapter (plain text file with the content: xxx=com.xxx.XxxLoggerAdapter)
</code></pre>
<p>XxxLoggerAdapter.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.logger.LoggerAdapter;
+<span class="hljs-keyword">import</span> org.apache.dubbo.common.logger.LoggerAdapter;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxLoggerAdapter</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">LoggerAdapter</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Logger <span class="hljs-title">getLogger</span><span class="hljs-params">(URL url)</span> </span>{
@@ -58,7 +58,7 @@
<p>XxxLogger.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.logger.Logger;
+<span class="hljs-keyword">import</span> org.apache.dubbo.common.logger.Logger;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxLogger</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Logger</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">XxxLogger</span><span class="hljs-params">(URL url)</span> </span>{
@@ -70,7 +70,7 @@
<span class="hljs-comment">// ...</span>
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.common.logger.LoggerAdapter:</p>
+<p>META-INF/dubbo/org.apache.dubbo.common.logger.LoggerAdapter:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxLoggerAdapter</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/logger-adapter.json b/en-us/docs/dev/impls/logger-adapter.json
index 68f8f85..4cf18b0 100644
--- a/en-us/docs/dev/impls/logger-adapter.json
+++ b/en-us/docs/dev/impls/logger-adapter.json
@@ -1,6 +1,6 @@
{
"filename": "logger-adapter.md",
- "__html": "<h1>LoggerAdapter Extension</h1>\n<h2>Summary</h2>\n<p>Extension for adapting logger output</p>\n<h2>Extension Interface</h2>\n<p><code>com.alibaba.dubbo.common.logger.LoggerAdapter</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:application</span> <span class=\"hljs-attr\">logger</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n</code></pre>\n<p>Or:</p>\n<pre><code cl [...]
+ "__html": "<h1>LoggerAdapter Extension</h1>\n<h2>Summary</h2>\n<p>Extension for adapting logger output</p>\n<h2>Extension Interface</h2>\n<p><code>org.apache.dubbo.common.logger.LoggerAdapter</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:application</span> <span class=\"hljs-attr\">logger</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n</code></pre>\n<p>Or:</p>\n<pre><code cla [...]
"link": "/en-us/docs/dev/impls/logger-adapter.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/merger.html b/en-us/docs/dev/impls/merger.html
index d11b87d..916ecd9 100644
--- a/en-us/docs/dev/impls/merger.html
+++ b/en-us/docs/dev/impls/merger.html
@@ -16,16 +16,16 @@
<h2>Summary</h2>
<p>Merge strategy for return result aggregation in group.</p>
<h2>Extension Interface</h2>
-<p><code>com.alibaba.dubbo.rpc.cluster.Merger</code></p>
+<p><code>org.apache.dubbo.rpc.cluster.Merger</code></p>
<h2>Extension Configuration</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:method</span> <span class="hljs-attr">merger</span>=<span class="hljs-string">"xxx"</span> /></span>
</code></pre>
<h2>Existing Extension</h2>
<ul>
-<li><code>com.alibaba.dubbo.rpc.cluster.merger.ArrayMerger</code></li>
-<li><code>com.alibaba.dubbo.rpc.cluster.merger.ListMerger</code></li>
-<li><code>com.alibaba.dubbo.rpc.cluster.merger.SetMerger</code></li>
-<li><code>com.alibaba.dubbo.rpc.cluster.merger.MapMerger</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.merger.ArrayMerger</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.merger.ListMerger</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.merger.SetMerger</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.merger.MapMerger</code></li>
</ul>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
@@ -38,12 +38,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.rpc.cluster.Merger (plain text file with the content: xxx=com.xxx.XxxMerger)
+ |-org.apache.dubbo.rpc.cluster.Merger (plain text file with the content: xxx=com.xxx.XxxMerger)
</code></pre>
<p>XxxMerger.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.cluster.Merger;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.cluster.Merger;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxMerger</span><<span class="hljs-title">T</span>> <span class="hljs-keyword">implements</span> <span class="hljs-title">Merger</span><<span class="hljs-title">T</span>> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> T <span class="hljs-title">merge</span><span class="hljs-params">(T... results)</span> </span>{
@@ -51,7 +51,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.rpc.cluster.Merger:</p>
+<p>META-INF/dubbo/org.apache.dubbo.rpc.cluster.Merger:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxMerger</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/merger.json b/en-us/docs/dev/impls/merger.json
index 9c36e50..bb59d44 100644
--- a/en-us/docs/dev/impls/merger.json
+++ b/en-us/docs/dev/impls/merger.json
@@ -1,6 +1,6 @@
{
"filename": "merger.md",
- "__html": "<h1>Merger Extension</h1>\n<h2>Summary</h2>\n<p>Merge strategy for return result aggregation in group.</p>\n<h2>Extension Interface</h2>\n<p><code>com.alibaba.dubbo.rpc.cluster.Merger</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:method</span> <span class=\"hljs-attr\">merger</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n</code></pre>\n<h2>Existing Extension</h2>\ [...]
+ "__html": "<h1>Merger Extension</h1>\n<h2>Summary</h2>\n<p>Merge strategy for return result aggregation in group.</p>\n<h2>Extension Interface</h2>\n<p><code>org.apache.dubbo.rpc.cluster.Merger</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:method</span> <span class=\"hljs-attr\">merger</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n</code></pre>\n<h2>Existing Extension</h2>\n [...]
"link": "/en-us/docs/dev/impls/merger.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/monitor.html b/en-us/docs/dev/impls/monitor.html
index 4383290..dc1da7e 100644
--- a/en-us/docs/dev/impls/monitor.html
+++ b/en-us/docs/dev/impls/monitor.html
@@ -17,15 +17,15 @@
<p>Extension to monitor service invocation times and time taken for each service invocation.</p>
<h2>Extension Interface</h2>
<ul>
-<li><code>com.alibaba.dubbo.monitor.MonitorFactory</code></li>
-<li><code>com.alibaba.dubbo.monitor.Monitor</code></li>
+<li><code>org.apache.dubbo.monitor.MonitorFactory</code></li>
+<li><code>org.apache.dubbo.monitor.Monitor</code></li>
</ul>
<h2>Extension Configuration</h2>
<pre><code class="language-xml"><span class="hljs-comment"><!-- configure monitor center --></span>
<span class="hljs-tag"><<span class="hljs-name">dubbo:monitor</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"xxx://ip:port"</span> /></span>
</code></pre>
<h2>Existing Extension</h2>
-<p>com.alibaba.dubbo.monitor.support.dubbo.DubboMonitorFactory</p>
+<p>org.apache.dubbo.monitor.support.dubbo.DubboMonitorFactory</p>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
<pre><code>src
@@ -38,14 +38,14 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.monitor.MonitorFactory (plain text file with the format: xxx=com.xxx.XxxMonitorFactory)
+ |-org.apache.dubbo.monitor.MonitorFactory (plain text file with the format: xxx=com.xxx.XxxMonitorFactory)
</code></pre>
<p>XxxMonitorFactory.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.monitor.MonitorFactory;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.monitor.Monitor;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.URL;
+<span class="hljs-keyword">import</span> org.apache.dubbo.monitor.MonitorFactory;
+<span class="hljs-keyword">import</span> org.apache.dubbo.monitor.Monitor;
+<span class="hljs-keyword">import</span> org.apache.dubbo.common.URL;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxMonitorFactory</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">MonitorFactory</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Monitor <span class="hljs-title">getMonitor</span><span class="hljs-params">(URL url)</span> </span>{
@@ -56,7 +56,7 @@
<p>XxxMonitor.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.monitor.Monitor;
+<span class="hljs-keyword">import</span> org.apache.dubbo.monitor.Monitor;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxMonitor</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Monitor</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">count</span><span class="hljs-params">(URL statistics)</span> </span>{
@@ -64,7 +64,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.monitor.MonitorFactory:</p>
+<p>META-INF/dubbo/org.apache.dubbo.monitor.MonitorFactory:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxMonitorFactory</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/monitor.json b/en-us/docs/dev/impls/monitor.json
index 9df72f1..19e8629 100644
--- a/en-us/docs/dev/impls/monitor.json
+++ b/en-us/docs/dev/impls/monitor.json
@@ -1,6 +1,6 @@
{
"filename": "monitor.md",
- "__html": "<h1>Monitor Extension</h1>\n<h2>Summary</h2>\n<p>Extension to monitor service invocation times and time taken for each service invocation.</p>\n<h2>Extension Interface</h2>\n<ul>\n<li><code>com.alibaba.dubbo.monitor.MonitorFactory</code></li>\n<li><code>com.alibaba.dubbo.monitor.Monitor</code></li>\n</ul>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-comment\"><!-- configure monitor center --></span>\n<span class=\"hljs-tag\">& [...]
+ "__html": "<h1>Monitor Extension</h1>\n<h2>Summary</h2>\n<p>Extension to monitor service invocation times and time taken for each service invocation.</p>\n<h2>Extension Interface</h2>\n<ul>\n<li><code>org.apache.dubbo.monitor.MonitorFactory</code></li>\n<li><code>org.apache.dubbo.monitor.Monitor</code></li>\n</ul>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-comment\"><!-- configure monitor center --></span>\n<span class=\"hljs-tag\">< [...]
"link": "/en-us/docs/dev/impls/monitor.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/networker.html b/en-us/docs/dev/impls/networker.html
index f1a2715..247a6c4 100644
--- a/en-us/docs/dev/impls/networker.html
+++ b/en-us/docs/dev/impls/networker.html
@@ -16,7 +16,7 @@
<h2>Summary</h2>
<p>Extension for peer to peer network grouping.</p>
<h2>Extension Interface</h2>
-<p><code>com.alibaba.dubbo.remoting.p2p.Networker</code></p>
+<p><code>org.apache.dubbo.remoting.p2p.Networker</code></p>
<h2>Extension Configuration</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">networker</span>=<span class="hljs-string">"xxx"</span> /></span>
<span class="hljs-comment"><!-- default configuration, it takes effect if networker attribute is not set in <dubbo:protocol> --></span>
@@ -24,8 +24,8 @@
</code></pre>
<h2>Existing Extension</h2>
<ul>
-<li><code>com.alibaba.dubbo.remoting.p2p.support.MulticastNetworker</code></li>
-<li><code>com.alibaba.dubbo.remoting.p2p.support.FileNetworker</code></li>
+<li><code>org.apache.dubbo.remoting.p2p.support.MulticastNetworker</code></li>
+<li><code>org.apache.dubbo.remoting.p2p.support.FileNetworker</code></li>
</ul>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
@@ -38,12 +38,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.remoting.p2p.Networker (plain text file with the content: xxx=com.xxx.XxxNetworker)
+ |-org.apache.dubbo.remoting.p2p.Networker (plain text file with the content: xxx=com.xxx.XxxNetworker)
</code></pre>
<p>XxxNetworker.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.remoting.p2p.Networker;
+<span class="hljs-keyword">import</span> org.apache.dubbo.remoting.p2p.Networker;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxNetworker</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Networker</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Group <span class="hljs-title">lookup</span><span class="hljs-params">(URL url)</span> </span>{
@@ -51,7 +51,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.remoting.p2p.Networker:</p>
+<p>META-INF/dubbo/org.apache.dubbo.remoting.p2p.Networker:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxNetworker</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/networker.json b/en-us/docs/dev/impls/networker.json
index c65c15c..ae9adf9 100644
--- a/en-us/docs/dev/impls/networker.json
+++ b/en-us/docs/dev/impls/networker.json
@@ -1,6 +1,6 @@
{
"filename": "networker.md",
- "__html": "<h1>Networker Extension</h1>\n<h2>Summary</h2>\n<p>Extension for peer to peer network grouping.</p>\n<h2>Extension Interface</h2>\n<p><code>com.alibaba.dubbo.remoting.p2p.Networker</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">networker</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n<span class=\"hljs-comment\"><!-- defa [...]
+ "__html": "<h1>Networker Extension</h1>\n<h2>Summary</h2>\n<p>Extension for peer to peer network grouping.</p>\n<h2>Extension Interface</h2>\n<p><code>org.apache.dubbo.remoting.p2p.Networker</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">networker</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n<span class=\"hljs-comment\"><!-- defau [...]
"link": "/en-us/docs/dev/impls/networker.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/page.html b/en-us/docs/dev/impls/page.html
index 0e96a72..4a93146 100644
--- a/en-us/docs/dev/impls/page.html
+++ b/en-us/docs/dev/impls/page.html
@@ -16,7 +16,7 @@
<h2>Summary</h2>
<p>Extension for page handler</p>
<h2>Extension Interface</h2>
-<p><code>com.alibaba.dubbo.container.page.PageHandler</code></p>
+<p><code>org.apache.dubbo.container.page.PageHandler</code></p>
<h2>Extension Configuration</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">page</span>=<span class="hljs-string">"xxx,yyy"</span> /></span>
<span class="hljs-comment"><!-- default configuration, will take effect if page attribute is not set in <dubbo:protocol> --></span>
@@ -24,10 +24,10 @@
</code></pre>
<h2>Existing Extension</h2>
<ul>
-<li><code>com.alibaba.dubbo.container.page.pages.HomePageHandler</code></li>
-<li><code>com.alibaba.dubbo.container.page.pages.StatusPageHandler</code></li>
-<li><code>com.alibaba.dubbo.container.page.pages.LogPageHandler</code></li>
-<li><code>com.alibaba.dubbo.container.page.pages.SystemPageHandler</code></li>
+<li><code>org.apache.dubbo.container.page.pages.HomePageHandler</code></li>
+<li><code>org.apache.dubbo.container.page.pages.StatusPageHandler</code></li>
+<li><code>org.apache.dubbo.container.page.pages.LogPageHandler</code></li>
+<li><code>org.apache.dubbo.container.page.pages.SystemPageHandler</code></li>
</ul>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
@@ -40,12 +40,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.container.page.PageHandler (plain text file with the content: xxx=com.xxx.XxxPageHandler)
+ |-org.apache.dubbo.container.page.PageHandler (plain text file with the content: xxx=com.xxx.XxxPageHandler)
</code></pre>
<p>XxxPageHandler.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.container.page.PageHandler;
+<span class="hljs-keyword">import</span> org.apache.dubbo.container.page.PageHandler;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxPageHandler</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">PageHandler</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Group <span class="hljs-title">lookup</span><span class="hljs-params">(URL url)</span> </span>{
@@ -53,7 +53,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.container.page.PageHandler:</p>
+<p>META-INF/dubbo/org.apache.dubbo.container.page.PageHandler:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxPageHandler</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/page.json b/en-us/docs/dev/impls/page.json
index b1dfe03..2722a34 100644
--- a/en-us/docs/dev/impls/page.json
+++ b/en-us/docs/dev/impls/page.json
@@ -1,6 +1,6 @@
{
"filename": "page.md",
- "__html": "<h1>Page Extension</h1>\n<h2>Summary</h2>\n<p>Extension for page handler</p>\n<h2>Extension Interface</h2>\n<p><code>com.alibaba.dubbo.container.page.PageHandler</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">page</span>=<span class=\"hljs-string\">\"xxx,yyy\"</span> /></span>\n<span class=\"hljs-comment\"><!-- default configuration, w [...]
+ "__html": "<h1>Page Extension</h1>\n<h2>Summary</h2>\n<p>Extension for page handler</p>\n<h2>Extension Interface</h2>\n<p><code>org.apache.dubbo.container.page.PageHandler</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">page</span>=<span class=\"hljs-string\">\"xxx,yyy\"</span> /></span>\n<span class=\"hljs-comment\"><!-- default configuration, wi [...]
"link": "/en-us/docs/dev/impls/page.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/protocol.html b/en-us/docs/dev/impls/protocol.html
index 521edaf..f17d8e6 100644
--- a/en-us/docs/dev/impls/protocol.html
+++ b/en-us/docs/dev/impls/protocol.html
@@ -27,9 +27,9 @@
</ul>
<h2>Extension Interface</h2>
<ul>
-<li><code>com.alibaba.dubbo.rpc.Protocol</code></li>
-<li><code>com.alibaba.dubbo.rpc.Exporter</code></li>
-<li><code>com.alibaba.dubbo.rpc.Invoker</code></li>
+<li><code>org.apache.dubbo.rpc.Protocol</code></li>
+<li><code>org.apache.dubbo.rpc.Exporter</code></li>
+<li><code>org.apache.dubbo.rpc.Invoker</code></li>
</ul>
<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Protocol</span> </span>{
<span class="hljs-comment">/**
@@ -71,11 +71,11 @@
</code></pre>
<h2>Existing Protocol</h2>
<ul>
-<li><code>com.alibaba.dubbo.rpc.injvm.InjvmProtocol</code></li>
-<li><code>com.alibaba.dubbo.rpc.dubbo.DubboProtocol</code></li>
-<li><code>com.alibaba.dubbo.rpc.rmi.RmiProtocol</code></li>
-<li><code>com.alibaba.dubbo.rpc.http.HttpProtocol</code></li>
-<li><code>com.alibaba.dubbo.rpc.http.hessian.HessianProtocol</code></li>
+<li><code>org.apache.dubbo.rpc.injvm.InjvmProtocol</code></li>
+<li><code>org.apache.dubbo.rpc.dubbo.DubboProtocol</code></li>
+<li><code>org.apache.dubbo.rpc.rmi.RmiProtocol</code></li>
+<li><code>org.apache.dubbo.rpc.http.HttpProtocol</code></li>
+<li><code>org.apache.dubbo.rpc.http.hessian.HessianProtocol</code></li>
</ul>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
@@ -90,12 +90,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.rpc.Protocol (plain text file with the content: xxx=com.xxx.XxxProtocol)
+ |-org.apache.dubbo.rpc.Protocol (plain text file with the content: xxx=com.xxx.XxxProtocol)
</code></pre>
<p>XxxProtocol.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Protocol;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Protocol;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxProtocol</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Protocol</span> </span>{
<span class="hljs-keyword">public</span> <T> <span class="hljs-function">Exporter<T> <span class="hljs-title">export</span><span class="hljs-params">(Invoker<T> invoker)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
@@ -109,7 +109,7 @@
<p>XxxExporter.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.support.AbstractExporter;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.support.AbstractExporter;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxExporter</span><<span class="hljs-title">T</span>> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractExporter</span><<span class="hljs-title">T</span>> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">XxxExporter</span><span class="hljs-params">(Invoker<T> invoker)</span> <span class="hljs-keyword">throws</span> RemotingException</span>{
@@ -125,7 +125,7 @@
<p>XxxInvoker.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.support.AbstractInvoker;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.support.AbstractInvoker;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxInvoker</span><<span class="hljs-title">T</span>> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractInvoker</span><<span class="hljs-title">T</span>> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">XxxInvoker</span><span class="hljs-params">(Class<T> type, URL url)</span> <span class="hljs-keyword">throws</span> RemotingException</span>{
@@ -136,7 +136,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.rpc.Protocol:</p>
+<p>META-INF/dubbo/org.apache.dubbo.rpc.Protocol:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxProtocol</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/protocol.json b/en-us/docs/dev/impls/protocol.json
index 0394b66..ddd1407 100644
--- a/en-us/docs/dev/impls/protocol.json
+++ b/en-us/docs/dev/impls/protocol.json
@@ -1,6 +1,6 @@
{
"filename": "protocol.md",
- "__html": "<h1>Protocol Extension</h1>\n<h2>Summary</h2>\n<p>Extension to RPC protocol, hide details of remote call.</p>\n<p>Contract:</p>\n<ul>\n<li>When user calls <code>invoke()</code> method of <code>Invoker</code> object which's returned from <code>refer()</code> call, the protocol needs to correspondingly execute <code>invoke()</code> method of <code>Invoker</code> object passed from remote <code>export()</code> method associated with the same URL.</li>\n<li>Moreover, it's protoc [...]
+ "__html": "<h1>Protocol Extension</h1>\n<h2>Summary</h2>\n<p>Extension to RPC protocol, hide details of remote call.</p>\n<p>Contract:</p>\n<ul>\n<li>When user calls <code>invoke()</code> method of <code>Invoker</code> object which's returned from <code>refer()</code> call, the protocol needs to correspondingly execute <code>invoke()</code> method of <code>Invoker</code> object passed from remote <code>export()</code> method associated with the same URL.</li>\n<li>Moreover, it's protoc [...]
"link": "/en-us/docs/dev/impls/protocol.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/proxy-factory.html b/en-us/docs/dev/impls/proxy-factory.html
index 9f07e2e..1573e22 100644
--- a/en-us/docs/dev/impls/proxy-factory.html
+++ b/en-us/docs/dev/impls/proxy-factory.html
@@ -16,7 +16,7 @@
<h2>Summary</h2>
<p>Convert <code>Invoker</code> into business interface.</p>
<h2>Extension Interface</h2>
-<p><code>com.alibaba.dubbo.rpc.ProxyFactory</code></p>
+<p><code>org.apache.dubbo.rpc.ProxyFactory</code></p>
<h2>Extension Configuration</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">proxy</span>=<span class="hljs-string">"xxx"</span> /></span>
<span class="hljs-comment"><!-- default configuration, it will take effect when proxy attribute is not configured in <dubbo:protocol> --></span>
@@ -24,8 +24,8 @@
</code></pre>
<h2>Existing Extension</h2>
<ul>
-<li><code>com.alibaba.dubbo.rpc.proxy.JdkProxyFactory</code></li>
-<li><code>com.alibaba.dubbo.rpc.proxy.JavassistProxyFactory</code></li>
+<li><code>org.apache.dubbo.rpc.proxy.JdkProxyFactory</code></li>
+<li><code>org.apache.dubbo.rpc.proxy.JavassistProxyFactory</code></li>
</ul>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
@@ -38,14 +38,14 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.rpc.ProxyFactory (plain text file with the content: xxx=com.xxx.XxxProxyFactory)
+ |-org.apache.dubbo.rpc.ProxyFactory (plain text file with the content: xxx=com.xxx.XxxProxyFactory)
</code></pre>
<p>XxxProxyFactory.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.ProxyFactory;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Invoker;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.RpcException;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.ProxyFactory;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Invoker;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.RpcException;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxProxyFactory</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">ProxyFactory</span> </span>{
@@ -57,7 +57,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.rpc.ProxyFactory:</p>
+<p>META-INF/dubbo/org.apache.dubbo.rpc.ProxyFactory:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxProxyFactory</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/proxy-factory.json b/en-us/docs/dev/impls/proxy-factory.json
index 8f3f646..a11b91a 100644
--- a/en-us/docs/dev/impls/proxy-factory.json
+++ b/en-us/docs/dev/impls/proxy-factory.json
@@ -1,6 +1,6 @@
{
"filename": "proxy-factory.md",
- "__html": "<h1>ProxyFactory Extension</h1>\n<h2>Summary</h2>\n<p>Convert <code>Invoker</code> into business interface.</p>\n<h2>Extension Interface</h2>\n<p><code>com.alibaba.dubbo.rpc.ProxyFactory</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">proxy</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n<span class=\"hljs-comment\"><!-- de [...]
+ "__html": "<h1>ProxyFactory Extension</h1>\n<h2>Summary</h2>\n<p>Convert <code>Invoker</code> into business interface.</p>\n<h2>Extension Interface</h2>\n<p><code>org.apache.dubbo.rpc.ProxyFactory</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">proxy</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n<span class=\"hljs-comment\"><!-- def [...]
"link": "/en-us/docs/dev/impls/proxy-factory.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/registry.html b/en-us/docs/dev/impls/registry.html
index ab1e0c3..92202a9 100644
--- a/en-us/docs/dev/impls/registry.html
+++ b/en-us/docs/dev/impls/registry.html
@@ -17,8 +17,8 @@
<p>Registry extension is used for service registration and discovery.</p>
<h2>Extension Interface</h2>
<ul>
-<li><code>com.alibaba.dubbo.registry.RegistryFactory</code></li>
-<li><code>com.alibaba.dubbo.registry.Registry</code></li>
+<li><code>org.apache.dubbo.registry.RegistryFactory</code></li>
+<li><code>org.apache.dubbo.registry.Registry</code></li>
</ul>
<h2>Extension Configuration</h2>
<pre><code class="language-xml"><span class="hljs-comment"><!-- config registry server --></span>
@@ -109,9 +109,9 @@
* 查询注册列表,与订阅的推模式相对应,这里为拉模式,只返回一次结果。
* Lookup subscription list. Compared to push mode for subscription, this is pull mode and returns result only once.
*
- * <span class="hljs-doctag">@see</span> com.alibaba.dubbo.registry.NotifyListener#notify(List)
+ * <span class="hljs-doctag">@see</span> org.apache.dubbo.registry.NotifyListener#notify(List)
* <span class="hljs-doctag">@param</span> url URL for query, null is not allowed, e.g.: consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
- * <span class="hljs-doctag">@return</span> subscription list, could be null, has the same meaning as the parameters in {<span class="hljs-doctag">@link</span> com.alibaba.dubbo.registry.NotifyListener#notify(List<URL>)}.
+ * <span class="hljs-doctag">@return</span> subscription list, could be null, has the same meaning as the parameters in {<span class="hljs-doctag">@link</span> org.apache.dubbo.registry.NotifyListener#notify(List<URL>)}.
*/</span>
<span class="hljs-function">List<URL> <span class="hljs-title">lookup</span><span class="hljs-params">(URL url)</span></span>;
@@ -129,14 +129,14 @@
* 4. If the data for one particular type is empty, need to notify with a special URL which has empty as its protocol and has category parameter for this particluar type.
* 5. Notifier (usually it is monitor center) needs to guarantee the notification sequence by, for say: single thread push, queuing in order, versioning, etc. <br>
*
- * <span class="hljs-doctag">@param</span> urls subscription list, always not empty, equivalent to the return result of {<span class="hljs-doctag">@link</span> com.alibaba.dubbo.registry.RegistryService#lookup(URL)}.
+ * <span class="hljs-doctag">@param</span> urls subscription list, always not empty, equivalent to the return result of {<span class="hljs-doctag">@link</span> org.apache.dubbo.registry.RegistryService#lookup(URL)}.
*/</span>
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">notify</span><span class="hljs-params">(List<URL> urls)</span></span>;
}
</code></pre>
<h2>Existing Extension</h2>
-<p><code>com.alibaba.dubbo.registry.support.dubbo.DubboRegistryFactory</code></p>
+<p><code>org.apache.dubbo.registry.support.dubbo.DubboRegistryFactory</code></p>
<h2>Extension Guide</h2>
<p>Directory structure:</p>
<pre><code>src
@@ -149,14 +149,14 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.registry.RegistryFactory (plain text file with the content: xxx=com.xxx.XxxRegistryFactory)
+ |-org.apache.dubbo.registry.RegistryFactory (plain text file with the content: xxx=com.xxx.XxxRegistryFactory)
</code></pre>
<p>XxxRegistryFactory.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.registry.RegistryFactory;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.registry.Registry;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.URL;
+<span class="hljs-keyword">import</span> org.apache.dubbo.registry.RegistryFactory;
+<span class="hljs-keyword">import</span> org.apache.dubbo.registry.Registry;
+<span class="hljs-keyword">import</span> org.apache.dubbo.common.URL;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxRegistryFactory</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">RegistryFactory</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Registry <span class="hljs-title">getRegistry</span><span class="hljs-params">(URL url)</span> </span>{
@@ -167,9 +167,9 @@
<p>XxxRegistry.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.registry.Registry;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.registry.NotifyListener;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.URL;
+<span class="hljs-keyword">import</span> org.apache.dubbo.registry.Registry;
+<span class="hljs-keyword">import</span> org.apache.dubbo.registry.NotifyListener;
+<span class="hljs-keyword">import</span> org.apache.dubbo.common.URL;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxRegistry</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Registry</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">register</span><span class="hljs-params">(URL url)</span> </span>{
@@ -186,7 +186,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.registry.RegistryFactory:</p>
+<p>META-INF/dubbo/org.apache.dubbo.registry.RegistryFactory:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxRegistryFactory</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/registry.json b/en-us/docs/dev/impls/registry.json
index e7b9c95..961f448 100644
--- a/en-us/docs/dev/impls/registry.json
+++ b/en-us/docs/dev/impls/registry.json
@@ -1,6 +1,6 @@
{
"filename": "registry.md",
- "__html": "<h1>Registry Extension</h1>\n<h2>Summary</h2>\n<p>Registry extension is used for service registration and discovery.</p>\n<h2>Extension Interface</h2>\n<ul>\n<li><code>com.alibaba.dubbo.registry.RegistryFactory</code></li>\n<li><code>com.alibaba.dubbo.registry.Registry</code></li>\n</ul>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-comment\"><!-- config registry server --></span>\n<span class=\"hljs-tag\"><<span class=\"hlj [...]
+ "__html": "<h1>Registry Extension</h1>\n<h2>Summary</h2>\n<p>Registry extension is used for service registration and discovery.</p>\n<h2>Extension Interface</h2>\n<ul>\n<li><code>org.apache.dubbo.registry.RegistryFactory</code></li>\n<li><code>org.apache.dubbo.registry.Registry</code></li>\n</ul>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-comment\"><!-- config registry server --></span>\n<span class=\"hljs-tag\"><<span class=\"hljs- [...]
"link": "/en-us/docs/dev/impls/registry.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/remoting.html b/en-us/docs/dev/impls/remoting.html
index 0d17346..a4c01cc 100644
--- a/en-us/docs/dev/impls/remoting.html
+++ b/en-us/docs/dev/impls/remoting.html
@@ -17,9 +17,9 @@
<p>Transportation extension for communication between server and client.</p>
<h2>Extension Interface</h2>
<ul>
-<li><code>com.alibaba.dubbo.remoting.Transporter</code></li>
-<li><code>com.alibaba.dubbo.remoting.Server</code></li>
-<li><code>com.alibaba.dubbo.remoting.Client</code></li>
+<li><code>org.apache.dubbo.remoting.Transporter</code></li>
+<li><code>org.apache.dubbo.remoting.Server</code></li>
+<li><code>org.apache.dubbo.remoting.Client</code></li>
</ul>
<h2>Extension Configuration</h2>
<pre><code class="language-xml"><span class="hljs-comment"><!-- server and client use the same transporter --></span>
@@ -31,9 +31,9 @@
</code></pre>
<h2>Existing Extension</h2>
<ul>
-<li><code>com.alibaba.dubbo.remoting.transport.transporter.netty.NettyTransporter</code></li>
-<li><code>com.alibaba.dubbo.remoting.transport.transporter.mina.MinaTransporter</code></li>
-<li><code>com.alibaba.dubbo.remoting.transport.transporter.grizzly.GrizzlyTransporter</code></li>
+<li><code>org.apache.dubbo.remoting.transport.transporter.netty.NettyTransporter</code></li>
+<li><code>org.apache.dubbo.remoting.transport.transporter.mina.MinaTransporter</code></li>
+<li><code>org.apache.dubbo.remoting.transport.transporter.grizzly.GrizzlyTransporter</code></li>
</ul>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
@@ -48,12 +48,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.remoting.Transporter (plain text file with the content: xxx=com.xxx.XxxTransporter)
+ |-org.apache.dubbo.remoting.Transporter (plain text file with the content: xxx=com.xxx.XxxTransporter)
</code></pre>
<p>XxxTransporter.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.remoting.Transporter;
+<span class="hljs-keyword">import</span> org.apache.dubbo.remoting.Transporter;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxTransporter</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Transporter</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Server <span class="hljs-title">bind</span><span class="hljs-params">(URL url, ChannelHandler handler)</span> <span class="hljs-keyword">throws</span> RemotingException </span>{
@@ -67,7 +67,7 @@
<p>XxxServer.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.remoting.transport.transporter.AbstractServer;
+<span class="hljs-keyword">import</span> org.apache.dubbo.remoting.transport.transporter.AbstractServer;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxServer</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractServer</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">XxxServer</span><span class="hljs-params">(URL url, ChannelHandler handler)</span> <span class="hljs-keyword">throws</span> RemotingException</span>{
@@ -90,7 +90,7 @@
<p>XxxClient.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.remoting.transport.transporter.AbstractClient;
+<span class="hljs-keyword">import</span> org.apache.dubbo.remoting.transport.transporter.AbstractClient;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxClient</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractClient</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">XxxServer</span><span class="hljs-params">(URL url, ChannelHandler handler)</span> <span class="hljs-keyword">throws</span> RemotingException</span>{
@@ -110,7 +110,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.remoting.Transporter:</p>
+<p>META-INF/dubbo/org.apache.dubbo.remoting.Transporter:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxTransporter</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/remoting.json b/en-us/docs/dev/impls/remoting.json
index 4c1ceac..7c6ec61 100644
--- a/en-us/docs/dev/impls/remoting.json
+++ b/en-us/docs/dev/impls/remoting.json
@@ -1,6 +1,6 @@
{
"filename": "remoting.md",
- "__html": "<h1>Transporter Extension</h1>\n<h2>Summary</h2>\n<p>Transportation extension for communication between server and client.</p>\n<h2>Extension Interface</h2>\n<ul>\n<li><code>com.alibaba.dubbo.remoting.Transporter</code></li>\n<li><code>com.alibaba.dubbo.remoting.Server</code></li>\n<li><code>com.alibaba.dubbo.remoting.Client</code></li>\n</ul>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-comment\"><!-- server and client use the s [...]
+ "__html": "<h1>Transporter Extension</h1>\n<h2>Summary</h2>\n<p>Transportation extension for communication between server and client.</p>\n<h2>Extension Interface</h2>\n<ul>\n<li><code>org.apache.dubbo.remoting.Transporter</code></li>\n<li><code>org.apache.dubbo.remoting.Server</code></li>\n<li><code>org.apache.dubbo.remoting.Client</code></li>\n</ul>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-comment\"><!-- server and client use the same [...]
"link": "/en-us/docs/dev/impls/remoting.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/router.html b/en-us/docs/dev/impls/router.html
index 61a644d..813bc0c 100644
--- a/en-us/docs/dev/impls/router.html
+++ b/en-us/docs/dev/impls/router.html
@@ -17,13 +17,13 @@
<p>Pick one from service providers and fire the invocation.</p>
<h2>Extension Interface</h2>
<ul>
-<li><code>com.alibaba.dubbo.rpc.cluster.RouterFactory</code></li>
-<li><code>com.alibaba.dubbo.rpc.cluster.Router</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.RouterFactory</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.Router</code></li>
</ul>
<h2>Existing Extension</h2>
<ul>
-<li><code>com.alibaba.dubbo.rpc.cluster.router.ScriptRouterFactory</code></li>
-<li><code>com.alibaba.dubbo.rpc.cluster.router.FileRouterFactory</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.router.ScriptRouterFactory</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.router.FileRouterFactory</code></li>
</ul>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
@@ -36,16 +36,16 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.rpc.cluster.RouterFactory (plain text file with the content: xxx=com.xxx.XxxRouterFactory)
+ |-org.apache.dubbo.rpc.cluster.RouterFactory (plain text file with the content: xxx=com.xxx.XxxRouterFactory)
</code></pre>
<p>XxxRouterFactory.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.cluster.RouterFactory;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Invoker;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Invocation;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.RpcException;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.cluster.RouterFactory;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Invoker;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Invocation;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.RpcException;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxRouterFactory</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">RouterFactory</span> </span>{
<span class="hljs-keyword">public</span> <T> List<Invoker<T>> select(List<Invoker<T>> invokers, Invocation invocation) <span class="hljs-keyword">throws</span> RpcException {
@@ -53,7 +53,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.rpc.cluster.RouterFactory:</p>
+<p>META-INF/dubbo/org.apache.dubbo.rpc.cluster.RouterFactory:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxRouterFactory</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/router.json b/en-us/docs/dev/impls/router.json
index 73300f5..0ff404c 100644
--- a/en-us/docs/dev/impls/router.json
+++ b/en-us/docs/dev/impls/router.json
@@ -1,6 +1,6 @@
{
"filename": "router.md",
- "__html": "<h1>Router Extension</h1>\n<h2>Summary</h2>\n<p>Pick one from service providers and fire the invocation.</p>\n<h2>Extension Interface</h2>\n<ul>\n<li><code>com.alibaba.dubbo.rpc.cluster.RouterFactory</code></li>\n<li><code>com.alibaba.dubbo.rpc.cluster.Router</code></li>\n</ul>\n<h2>Existing Extension</h2>\n<ul>\n<li><code>com.alibaba.dubbo.rpc.cluster.router.ScriptRouterFactory</code></li>\n<li><code>com.alibaba.dubbo.rpc.cluster.router.FileRouterFactory</code></li>\n</ul>\ [...]
+ "__html": "<h1>Router Extension</h1>\n<h2>Summary</h2>\n<p>Pick one from service providers and fire the invocation.</p>\n<h2>Extension Interface</h2>\n<ul>\n<li><code>org.apache.dubbo.rpc.cluster.RouterFactory</code></li>\n<li><code>org.apache.dubbo.rpc.cluster.Router</code></li>\n</ul>\n<h2>Existing Extension</h2>\n<ul>\n<li><code>org.apache.dubbo.rpc.cluster.router.ScriptRouterFactory</code></li>\n<li><code>org.apache.dubbo.rpc.cluster.router.FileRouterFactory</code></li>\n</ul>\n<h2 [...]
"link": "/en-us/docs/dev/impls/router.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/serialize.html b/en-us/docs/dev/impls/serialize.html
index 4960724..dba1953 100644
--- a/en-us/docs/dev/impls/serialize.html
+++ b/en-us/docs/dev/impls/serialize.html
@@ -17,9 +17,9 @@
<p>Extension to serializing java object into byte code stream for transporting on the network, and vise versa.</p>
<h2>Extension Interface</h2>
<ul>
-<li><code>com.alibaba.dubbo.common.serialize.Serialization</code></li>
-<li><code>com.alibaba.dubbo.common.serialize.ObjectInput</code></li>
-<li><code>com.alibaba.dubbo.common.serialize.ObjectOutput</code></li>
+<li><code>org.apache.dubbo.common.serialize.Serialization</code></li>
+<li><code>org.apache.dubbo.common.serialize.ObjectInput</code></li>
+<li><code>org.apache.dubbo.common.serialize.ObjectOutput</code></li>
</ul>
<h2>Extension Configuration</h2>
<pre><code class="language-xml"><span class="hljs-comment"><!-- protocol serialization style --></span>
@@ -29,10 +29,10 @@
</code></pre>
<h2>Existing Extension</h2>
<ul>
-<li><code>com.alibaba.dubbo.common.serialize.dubbo.DubboSerialization</code></li>
-<li><code>com.alibaba.dubbo.common.serialize.hessian.Hessian2Serialization</code></li>
-<li><code>com.alibaba.dubbo.common.serialize.java.JavaSerialization</code></li>
-<li><code>com.alibaba.dubbo.common.serialize.java.CompactedJavaSerialization</code></li>
+<li><code>org.apache.dubbo.common.serialize.dubbo.DubboSerialization</code></li>
+<li><code>org.apache.dubbo.common.serialize.hessian.Hessian2Serialization</code></li>
+<li><code>org.apache.dubbo.common.serialize.java.JavaSerialization</code></li>
+<li><code>org.apache.dubbo.common.serialize.java.CompactedJavaSerialization</code></li>
</ul>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
@@ -47,14 +47,14 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.common.serialize.Serialization (plain text file with the content: xxx=com.xxx.XxxSerialization)
+ |-org.apache.dubbo.common.serialize.Serialization (plain text file with the content: xxx=com.xxx.XxxSerialization)
</code></pre>
<p>XxxSerialization.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.serialize.Serialization;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.serialize.ObjectInput;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.serialize.ObjectOutput;
+<span class="hljs-keyword">import</span> org.apache.dubbo.common.serialize.Serialization;
+<span class="hljs-keyword">import</span> org.apache.dubbo.common.serialize.ObjectInput;
+<span class="hljs-keyword">import</span> org.apache.dubbo.common.serialize.ObjectOutput;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxSerialization</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Serialization</span> </span>{
@@ -66,7 +66,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.common.serialize.Serialization:</p>
+<p>META-INF/dubbo/org.apache.dubbo.common.serialize.Serialization:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxSerialization</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/serialize.json b/en-us/docs/dev/impls/serialize.json
index bba59d7..d9f875e 100644
--- a/en-us/docs/dev/impls/serialize.json
+++ b/en-us/docs/dev/impls/serialize.json
@@ -1,6 +1,6 @@
{
"filename": "serialize.md",
- "__html": "<h1>Serialization Extension</h1>\n<h2>Summary</h2>\n<p>Extension to serializing java object into byte code stream for transporting on the network, and vise versa.</p>\n<h2>Extension Interface</h2>\n<ul>\n<li><code>com.alibaba.dubbo.common.serialize.Serialization</code></li>\n<li><code>com.alibaba.dubbo.common.serialize.ObjectInput</code></li>\n<li><code>com.alibaba.dubbo.common.serialize.ObjectOutput</code></li>\n</ul>\n<h2>Extension Configuration</h2>\n<pre><code class=\"la [...]
+ "__html": "<h1>Serialization Extension</h1>\n<h2>Summary</h2>\n<p>Extension to serializing java object into byte code stream for transporting on the network, and vise versa.</p>\n<h2>Extension Interface</h2>\n<ul>\n<li><code>org.apache.dubbo.common.serialize.Serialization</code></li>\n<li><code>org.apache.dubbo.common.serialize.ObjectInput</code></li>\n<li><code>org.apache.dubbo.common.serialize.ObjectOutput</code></li>\n</ul>\n<h2>Extension Configuration</h2>\n<pre><code class=\"langu [...]
"link": "/en-us/docs/dev/impls/serialize.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/status-checker.html b/en-us/docs/dev/impls/status-checker.html
index c8456df..9595919 100644
--- a/en-us/docs/dev/impls/status-checker.html
+++ b/en-us/docs/dev/impls/status-checker.html
@@ -16,7 +16,7 @@
<h2>Summary</h2>
<p>Extension to check status of resources service depends on. This status checker can be used in both telnet status command and status page.</p>
<h2>Extension Interface</h2>
-<p><code>com.alibaba.dubbo.common.status.StatusChecker</code></p>
+<p><code>org.apache.dubbo.common.status.StatusChecker</code></p>
<h2>Extension Configuration</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">status</span>=<span class="hljs-string">"xxx,yyy"</span> /></span>
<span class="hljs-comment"><!-- default configuration, will take effect if no status attribute is configured in <dubbo:protocol> --></span>
@@ -24,13 +24,13 @@
</code></pre>
<h2>Existing Extension</h2>
<ul>
-<li><code>com.alibaba.dubbo.common.status.support.MemoryStatusChecker</code></li>
-<li><code>com.alibaba.dubbo.common.status.support.LoadStatusChecker</code></li>
-<li><code>com.alibaba.dubbo.rpc.dubbo.status.ServerStatusChecker</code></li>
-<li><code>com.alibaba.dubbo.rpc.dubbo.status.ThreadPoolStatusChecker</code></li>
-<li><code>com.alibaba.dubbo.registry.directory.RegistryStatusChecker</code></li>
-<li><code>com.alibaba.dubbo.rpc.config.spring.status.SpringStatusChecker</code></li>
-<li><code>com.alibaba.dubbo.rpc.config.spring.status.DataSourceStatusChecker</code></li>
+<li><code>org.apache.dubbo.common.status.support.MemoryStatusChecker</code></li>
+<li><code>org.apache.dubbo.common.status.support.LoadStatusChecker</code></li>
+<li><code>org.apache.dubbo.rpc.dubbo.status.ServerStatusChecker</code></li>
+<li><code>org.apache.dubbo.rpc.dubbo.status.ThreadPoolStatusChecker</code></li>
+<li><code>org.apache.dubbo.registry.directory.RegistryStatusChecker</code></li>
+<li><code>org.apache.dubbo.rpc.config.spring.status.SpringStatusChecker</code></li>
+<li><code>org.apache.dubbo.rpc.config.spring.status.DataSourceStatusChecker</code></li>
</ul>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
@@ -43,12 +43,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.common.status.StatusChecker (plain text file with the content: xxx=com.xxx.XxxStatusChecker)
+ |-org.apache.dubbo.common.status.StatusChecker (plain text file with the content: xxx=com.xxx.XxxStatusChecker)
</code></pre>
<p>XxxStatusChecker.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.status.StatusChecker;
+<span class="hljs-keyword">import</span> org.apache.dubbo.common.status.StatusChecker;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxStatusChecker</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">StatusChecker</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Status <span class="hljs-title">check</span><span class="hljs-params">()</span> </span>{
@@ -56,7 +56,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.common.status.StatusChecker:</p>
+<p>META-INF/dubbo/org.apache.dubbo.common.status.StatusChecker:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxStatusChecker</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/status-checker.json b/en-us/docs/dev/impls/status-checker.json
index 4a1a618..8146564 100644
--- a/en-us/docs/dev/impls/status-checker.json
+++ b/en-us/docs/dev/impls/status-checker.json
@@ -1,6 +1,6 @@
{
"filename": "status-checker.md",
- "__html": "<h1>StatusChecker Extension</h1>\n<h2>Summary</h2>\n<p>Extension to check status of resources service depends on. This status checker can be used in both telnet status command and status page.</p>\n<h2>Extension Interface</h2>\n<p><code>com.alibaba.dubbo.common.status.StatusChecker</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">status</span> [...]
+ "__html": "<h1>StatusChecker Extension</h1>\n<h2>Summary</h2>\n<p>Extension to check status of resources service depends on. This status checker can be used in both telnet status command and status page.</p>\n<h2>Extension Interface</h2>\n<p><code>org.apache.dubbo.common.status.StatusChecker</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">status</span>= [...]
"link": "/en-us/docs/dev/impls/status-checker.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/telnet-handler.html b/en-us/docs/dev/impls/telnet-handler.html
index 1e3c216..45ecdf0 100644
--- a/en-us/docs/dev/impls/telnet-handler.html
+++ b/en-us/docs/dev/impls/telnet-handler.html
@@ -16,7 +16,7 @@
<h2>Summary</h2>
<p>Extension to telnet command. All server should support telnet access for operation convenience.</p>
<h2>Extension Interface</h2>
-<p><code>com.alibaba.dubbo.remoting.telnet.TelnetHandler</code></p>
+<p><code>org.apache.dubbo.remoting.telnet.TelnetHandler</code></p>
<h2>Extension Configuration</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">telnet</span>=<span class="hljs-string">"xxx,yyy"</span> /></span>
<span class="hljs-comment"><!-- default configuration, will take effect if telnet attribute is not specified in <dubbo:protocol> --></span>
@@ -24,17 +24,17 @@
</code></pre>
<h2>Existing Extension</h2>
<ul>
-<li><code>com.alibaba.dubbo.remoting.telnet.support.ClearTelnetHandler</code></li>
-<li><code>com.alibaba.dubbo.remoting.telnet.support.ExitTelnetHandler</code></li>
-<li><code>com.alibaba.dubbo.remoting.telnet.support.HelpTelnetHandler</code></li>
-<li><code>com.alibaba.dubbo.remoting.telnet.support.StatusTelnetHandler</code></li>
-<li><code>com.alibaba.dubbo.rpc.dubbo.telnet.ListTelnetHandler</code></li>
-<li><code>com.alibaba.dubbo.rpc.dubbo.telnet.ChangeTelnetHandler</code></li>
-<li><code>com.alibaba.dubbo.rpc.dubbo.telnet.CurrentTelnetHandler</code></li>
-<li><code>com.alibaba.dubbo.rpc.dubbo.telnet.InvokeTelnetHandler</code></li>
-<li><code>com.alibaba.dubbo.rpc.dubbo.telnet.TraceTelnetHandler</code></li>
-<li><code>com.alibaba.dubbo.rpc.dubbo.telnet.CountTelnetHandler</code></li>
-<li><code>com.alibaba.dubbo.rpc.dubbo.telnet.PortTelnetHandler</code></li>
+<li><code>org.apache.dubbo.remoting.telnet.support.ClearTelnetHandler</code></li>
+<li><code>org.apache.dubbo.remoting.telnet.support.ExitTelnetHandler</code></li>
+<li><code>org.apache.dubbo.remoting.telnet.support.HelpTelnetHandler</code></li>
+<li><code>org.apache.dubbo.remoting.telnet.support.StatusTelnetHandler</code></li>
+<li><code>org.apache.dubbo.rpc.dubbo.telnet.ListTelnetHandler</code></li>
+<li><code>org.apache.dubbo.rpc.dubbo.telnet.ChangeTelnetHandler</code></li>
+<li><code>org.apache.dubbo.rpc.dubbo.telnet.CurrentTelnetHandler</code></li>
+<li><code>org.apache.dubbo.rpc.dubbo.telnet.InvokeTelnetHandler</code></li>
+<li><code>org.apache.dubbo.rpc.dubbo.telnet.TraceTelnetHandler</code></li>
+<li><code>org.apache.dubbo.rpc.dubbo.telnet.CountTelnetHandler</code></li>
+<li><code>org.apache.dubbo.rpc.dubbo.telnet.PortTelnetHandler</code></li>
</ul>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
@@ -47,12 +47,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.remoting.telnet.TelnetHandler (plain text file with the content: xxx=com.xxx.XxxTelnetHandler)
+ |-org.apache.dubbo.remoting.telnet.TelnetHandler (plain text file with the content: xxx=com.xxx.XxxTelnetHandler)
</code></pre>
<p>XxxTelnetHandler.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.remoting.telnet.TelnetHandler;
+<span class="hljs-keyword">import</span> org.apache.dubbo.remoting.telnet.TelnetHandler;
<span class="hljs-meta">@Help</span>(parameter=<span class="hljs-string">"..."</span>, summary=<span class="hljs-string">"..."</span>, detail=<span class="hljs-string">"..."</span>)
@@ -62,7 +62,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.remoting.telnet.TelnetHandler:</p>
+<p>META-INF/dubbo/org.apache.dubbo.remoting.telnet.TelnetHandler:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxTelnetHandler</span>
</code></pre>
<h2>用法</h2>
diff --git a/en-us/docs/dev/impls/telnet-handler.json b/en-us/docs/dev/impls/telnet-handler.json
index fa7a17e..3b4a8b0 100644
--- a/en-us/docs/dev/impls/telnet-handler.json
+++ b/en-us/docs/dev/impls/telnet-handler.json
@@ -1,6 +1,6 @@
{
"filename": "telnet-handler.md",
- "__html": "<h1>TelnetHandler Extension</h1>\n<h2>Summary</h2>\n<p>Extension to telnet command. All server should support telnet access for operation convenience.</p>\n<h2>Extension Interface</h2>\n<p><code>com.alibaba.dubbo.remoting.telnet.TelnetHandler</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">telnet</span>=<span class=\"hljs-string\">\"xxx,yyy\" [...]
+ "__html": "<h1>TelnetHandler Extension</h1>\n<h2>Summary</h2>\n<p>Extension to telnet command. All server should support telnet access for operation convenience.</p>\n<h2>Extension Interface</h2>\n<p><code>org.apache.dubbo.remoting.telnet.TelnetHandler</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">telnet</span>=<span class=\"hljs-string\">\"xxx,yyy\"< [...]
"link": "/en-us/docs/dev/impls/telnet-handler.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/threadpool.html b/en-us/docs/dev/impls/threadpool.html
index 728f3d5..6bbe3a1 100644
--- a/en-us/docs/dev/impls/threadpool.html
+++ b/en-us/docs/dev/impls/threadpool.html
@@ -16,7 +16,7 @@
<h2>Summary</h2>
<p>Thread pool strategy extension for service provider. When server receives one request, it needs a thread from thread pool to execute business logic in service provider.</p>
<h2>Extension Interface</h2>
-<p><code>com.alibaba.dubbo.common.threadpool.ThreadPool</code></p>
+<p><code>org.apache.dubbo.common.threadpool.ThreadPool</code></p>
<h2>Extension Configuration</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">threadpool</span>=<span class="hljs-string">"xxx"</span> /></span>
<span class="hljs-comment"><!-- default configuration, it will take effect when threadpool attribute is not specified in <dubbo:protocol> --></span>
@@ -24,8 +24,8 @@
</code></pre>
<h2>Existing Extension</h2>
<ul>
-<li><code>com.alibaba.dubbo.common.threadpool.FixedThreadPool</code></li>
-<li><code>com.alibaba.dubbo.common.threadpool.CachedThreadPool</code></li>
+<li><code>org.apache.dubbo.common.threadpool.FixedThreadPool</code></li>
+<li><code>org.apache.dubbo.common.threadpool.CachedThreadPool</code></li>
</ul>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
@@ -38,12 +38,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.common.threadpool.ThreadPool (plain text file with the content: xxx=com.xxx.XxxThreadPool)
+ |-org.apache.dubbo.common.threadpool.ThreadPool (plain text file with the content: xxx=com.xxx.XxxThreadPool)
</code></pre>
<p>XxxThreadPool.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.threadpool.ThreadPool;
+<span class="hljs-keyword">import</span> org.apache.dubbo.common.threadpool.ThreadPool;
<span class="hljs-keyword">import</span> java.util.concurrent.Executor;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxThreadPool</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">ThreadPool</span> </span>{
@@ -52,7 +52,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.common.threadpool.ThreadPool:</p>
+<p>META-INF/dubbo/org.apache.dubbo.common.threadpool.ThreadPool:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxThreadPool</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/threadpool.json b/en-us/docs/dev/impls/threadpool.json
index 83c0b9c..df51ea4 100644
--- a/en-us/docs/dev/impls/threadpool.json
+++ b/en-us/docs/dev/impls/threadpool.json
@@ -1,6 +1,6 @@
{
"filename": "threadpool.md",
- "__html": "<h1>ThreadPool Extension</h1>\n<h2>Summary</h2>\n<p>Thread pool strategy extension for service provider. When server receives one request, it needs a thread from thread pool to execute business logic in service provider.</p>\n<h2>Extension Interface</h2>\n<p><code>com.alibaba.dubbo.common.threadpool.ThreadPool</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span clas [...]
+ "__html": "<h1>ThreadPool Extension</h1>\n<h2>Summary</h2>\n<p>Thread pool strategy extension for service provider. When server receives one request, it needs a thread from thread pool to execute business logic in service provider.</p>\n<h2>Extension Interface</h2>\n<p><code>org.apache.dubbo.common.threadpool.ThreadPool</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class [...]
"link": "/en-us/docs/dev/impls/threadpool.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/dev/impls/validation.html b/en-us/docs/dev/impls/validation.html
index a79ae1d..dd09530 100644
--- a/en-us/docs/dev/impls/validation.html
+++ b/en-us/docs/dev/impls/validation.html
@@ -16,14 +16,14 @@
<h2>Summary</h2>
<p>Extension for parameter validation.</p>
<h2>Extension Inteface</h2>
-<p><code>com.alibaba.dubbo.validation.Validation</code></p>
+<p><code>org.apache.dubbo.validation.Validation</code></p>
<h2>Extension Configuration</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">validation</span>=<span class="hljs-string">"xxx,yyy"</span> /></span>
<span class="hljs-comment"><!-- default configuration, it will take effect when there's no validation attribute specified in <dubbo:service> --></span>
<span class="hljs-tag"><<span class="hljs-name">dubbo:provider</span> <span class="hljs-attr">validation</span>=<span class="hljs-string">"xxx,yyy"</span> /></span>
</code></pre>
<h2>Existing Extension</h2>
-<p><code>com.alibaba.dubbo.validation.support.jvalidation.JValidation</code></p>
+<p><code>org.apache.dubbo.validation.support.jvalidation.JValidation</code></p>
<h2>Extension Guide</h2>
<p>Directory layout:</p>
<pre><code>src
@@ -35,12 +35,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.validation.Validation (plain text file with the content: xxx=com.xxx.XxxValidation)
+ |-org.apache.dubbo.validation.Validation (plain text file with the content: xxx=com.xxx.XxxValidation)
</code></pre>
<p>XxxValidation.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.validation.Validation;
+<span class="hljs-keyword">import</span> org.apache.dubbo.validation.Validation;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxValidation</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Validation</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Object <span class="hljs-title">getValidator</span><span class="hljs-params">(URL url)</span> </span>{
@@ -51,7 +51,7 @@
<p>XxxValidator.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.validation.Validator;
+<span class="hljs-keyword">import</span> org.apache.dubbo.validation.Validator;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxValidator</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Validator</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">XxxValidator</span><span class="hljs-params">(URL url)</span> </span>{
@@ -62,7 +62,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.validation.Validation:</p>
+<p>META-INF/dubbo/org.apache.dubbo.validation.Validation:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxValidation</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/en-us/docs/dev/impls/validation.json b/en-us/docs/dev/impls/validation.json
index 57102e2..ce78250 100644
--- a/en-us/docs/dev/impls/validation.json
+++ b/en-us/docs/dev/impls/validation.json
@@ -1,6 +1,6 @@
{
"filename": "validation.md",
- "__html": "<h1>Validation Extension</h1>\n<h2>Summary</h2>\n<p>Extension for parameter validation.</p>\n<h2>Extension Inteface</h2>\n<p><code>com.alibaba.dubbo.validation.Validation</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:service</span> <span class=\"hljs-attr\">validation</span>=<span class=\"hljs-string\">\"xxx,yyy\"</span> /></span>\n<span class=\"hljs-comment\"><!-- default co [...]
+ "__html": "<h1>Validation Extension</h1>\n<h2>Summary</h2>\n<p>Extension for parameter validation.</p>\n<h2>Extension Inteface</h2>\n<p><code>org.apache.dubbo.validation.Validation</code></p>\n<h2>Extension Configuration</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:service</span> <span class=\"hljs-attr\">validation</span>=<span class=\"hljs-string\">\"xxx,yyy\"</span> /></span>\n<span class=\"hljs-comment\"><!-- default con [...]
"link": "/en-us/docs/dev/impls/validation.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/configuration/annotation.html b/en-us/docs/user/configuration/annotation.html
index 37db6c7..eab58e4 100644
--- a/en-us/docs/user/configuration/annotation.html
+++ b/en-us/docs/user/configuration/annotation.html
@@ -16,7 +16,7 @@
<p>Requires<code>2.5.7</code> or higher</p>
<h2>Provider Side</h2>
<h3><code>Service</code> annotation for exporting</h3>
-<pre><code class="language-java"><span class="hljs-keyword">import</span> com.alibaba.dubbo.config.annotation.Service;
+<pre><code class="language-java"><span class="hljs-keyword">import</span> org.apache.dubbo.config.annotation.Service;
<span class="hljs-meta">@Service</span>(timeout = <span class="hljs-number">5000</span>)
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AnnotateServiceImpl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">AnnotateService</span> </span>{
@@ -45,7 +45,7 @@
</code></pre>
<h3>Path to scan</h3>
<pre><code class="language-java"><span class="hljs-meta">@SpringBootApplication</span>
-<span class="hljs-meta">@DubboComponentScan</span>(basePackages = <span class="hljs-string">"com.alibaba.dubbo.test.service.impl"</span>)
+<span class="hljs-meta">@DubboComponentScan</span>(basePackages = <span class="hljs-string">"org.apache.dubbo.test.service.impl"</span>)
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ProviderTestApp</span> </span>{
<span class="hljs-comment">// ...</span>
}
@@ -54,7 +54,7 @@
<h3><code>Reference</code> annotation for reference</h3>
<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AnnotationConsumeService</span> </span>{
- <span class="hljs-meta">@com</span>.alibaba.dubbo.config.annotation.Reference
+ <span class="hljs-meta">@org</span>.apache.dubbo.config.annotation.Reference
<span class="hljs-keyword">public</span> AnnotateService annotateService;
<span class="hljs-comment">// ...</span>
@@ -90,14 +90,14 @@
</code></pre>
<h3>Path to scan</h3>
<pre><code class="language-java"><span class="hljs-meta">@SpringBootApplication</span>
-<span class="hljs-meta">@DubboComponentScan</span>(basePackages = <span class="hljs-string">"com.alibaba.dubbo.test.service"</span>)
+<span class="hljs-meta">@DubboComponentScan</span>(basePackages = <span class="hljs-string">"org.apache.dubbo.test.service"</span>)
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ConsumerTestApp</span> </span>{
<span class="hljs-comment">// ...</span>
}
</code></pre>
<h2>NOTES</h2>
<p>All annotations in 2.5.7 will be removed later, if you have used these annotations in your project, please upgrade to the latest version.</p>
-<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:annotation</span> <span class="hljs-attr">package</span>=<span class="hljs-string">"com.alibaba.dubbo.test.service"</span> /></span>
+<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:annotation</span> <span class="hljs-attr">package</span>=<span class="hljs-string">"org.apache.dubbo.test.service"</span> /></span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
diff --git a/en-us/docs/user/configuration/annotation.json b/en-us/docs/user/configuration/annotation.json
index 7f71921..f56955b 100644
--- a/en-us/docs/user/configuration/annotation.json
+++ b/en-us/docs/user/configuration/annotation.json
@@ -1,6 +1,6 @@
{
"filename": "annotation.md",
- "__html": "<h1>Annotation Configuration</h1>\n<p>Requires<code>2.5.7</code> or higher</p>\n<h2>Provider Side</h2>\n<h3><code>Service</code> annotation for exporting</h3>\n<pre><code class=\"language-java\"><span class=\"hljs-keyword\">import</span> com.alibaba.dubbo.config.annotation.Service;\n \n<span class=\"hljs-meta\">@Service</span>(timeout = <span class=\"hljs-number\">5000</span>)\n<span class=\"hljs-keyword\">public</span> <span class=\"hljs-class\"><span class=\"hljs-keyword\" [...]
+ "__html": "<h1>Annotation Configuration</h1>\n<p>Requires<code>2.5.7</code> or higher</p>\n<h2>Provider Side</h2>\n<h3><code>Service</code> annotation for exporting</h3>\n<pre><code class=\"language-java\"><span class=\"hljs-keyword\">import</span> org.apache.dubbo.config.annotation.Service;\n \n<span class=\"hljs-meta\">@Service</span>(timeout = <span class=\"hljs-number\">5000</span>)\n<span class=\"hljs-keyword\">public</span> <span class=\"hljs-class\"><span class=\"hljs-keyword\"> [...]
"link": "/en-us/docs/user/configuration/annotation.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/configuration/api.html b/en-us/docs/user/configuration/api.html
index ca89ee0..4a3163a 100644
--- a/en-us/docs/user/configuration/api.html
+++ b/en-us/docs/user/configuration/api.html
@@ -15,10 +15,10 @@
<div id="root"><div class="documentation-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/en-us/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">中</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a [...]
<p>All API properties have counterparts in XML, see <a href="../references/xml/introduction.md">XML References</a> for details. For example <code>ApplicationConfig.setName("xxx")</code> equals to <code><dubbo:application name="xxx" /></code> <sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p>
<h2>Provider Side</h2>
-<pre><code class="language-java"><span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.config.ApplicationConfig;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.config.RegistryConfig;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.config.ProviderConfig;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.config.ServiceConfig;
+<pre><code class="language-java"><span class="hljs-keyword">import</span> org.apache.dubbo.rpc.config.ApplicationConfig;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.config.RegistryConfig;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.config.ProviderConfig;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.config.ServiceConfig;
<span class="hljs-keyword">import</span> com.xxx.XxxService;
<span class="hljs-keyword">import</span> com.xxx.XxxServiceImpl;
@@ -56,10 +56,10 @@ service.setVersion(<span class="hljs-string">"1.0.0"</span>);
service.export();
</code></pre>
<h2>Consumer Side</h2>
-<pre><code class="language-java"><span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.config.ApplicationConfig;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.config.RegistryConfig;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.config.ConsumerConfig;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.config.ReferenceConfig;
+<pre><code class="language-java"><span class="hljs-keyword">import</span> org.apache.dubbo.rpc.config.ApplicationConfig;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.config.RegistryConfig;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.config.ConsumerConfig;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.config.ReferenceConfig;
<span class="hljs-keyword">import</span> com.xxx.XxxService;
<span class="hljs-comment">// Application Info</span>
diff --git a/en-us/docs/user/configuration/api.json b/en-us/docs/user/configuration/api.json
index 6602b52..bb5868b 100644
--- a/en-us/docs/user/configuration/api.json
+++ b/en-us/docs/user/configuration/api.json
@@ -1,6 +1,6 @@
{
"filename": "api.md",
- "__html": "<h1>API Configuration</h1>\n<p>All API properties have counterparts in XML, see <a href=\"../references/xml/introduction.md\">XML References</a> for details. For example <code>ApplicationConfig.setName("xxx")</code> equals to <code><dubbo:application name="xxx" /></code> <sup class=\"footnote-ref\"><a href=\"#fn1\" id=\"fnref1\">[1]</a></sup></p>\n<h2>Provider Side</h2>\n<pre><code class=\"language-java\"><span class=\"hljs-keyword\">import</span> [...]
+ "__html": "<h1>API Configuration</h1>\n<p>All API properties have counterparts in XML, see <a href=\"../references/xml/introduction.md\">XML References</a> for details. For example <code>ApplicationConfig.setName("xxx")</code> equals to <code><dubbo:application name="xxx" /></code> <sup class=\"footnote-ref\"><a href=\"#fn1\" id=\"fnref1\">[1]</a></sup></p>\n<h2>Provider Side</h2>\n<pre><code class=\"language-java\"><span class=\"hljs-keyword\">import</span> [...]
"link": "/en-us/docs/user/configuration/api.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/configuration/xml.html b/en-us/docs/user/configuration/xml.html
index e5058c2..37e8a83 100644
--- a/en-us/docs/user/configuration/xml.html
+++ b/en-us/docs/user/configuration/xml.html
@@ -23,8 +23,8 @@
<span class="hljs-tag"><<span class="hljs-name">dubbo:application</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"hello-world-app"</span> /></span>
<span class="hljs-tag"><<span class="hljs-name">dubbo:registry</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"multicast://224.5.6.7:1234"</span> /></span>
<span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"dubbo"</span> <span class="hljs-attr">port</span>=<span class="hljs-string">"20880"</span> /></span>
- <span class="hljs-tag"><<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"com.alibaba.dubbo.demo.DemoService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"demoServiceLocal"</span> /></span>
- <span class="hljs-tag"><<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoServiceRemote"</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"com.alibaba.dubbo.demo.DemoService"</span> /></span>
+ <span class="hljs-tag"><<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"demoServiceLocal"</span> /></span>
+ <span class="hljs-tag"><<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoServiceRemote"</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.demo.DemoService"</span> /></span>
<span class="hljs-tag"></<span class="hljs-name">beans</span>></span>
</code></pre>
<p>All tags support custom parameters, so we can meet the special config requirements at different extension points, such as:</p>
diff --git a/en-us/docs/user/configuration/xml.json b/en-us/docs/user/configuration/xml.json
index 4e34b8d..ad0a9f0 100644
--- a/en-us/docs/user/configuration/xml.json
+++ b/en-us/docs/user/configuration/xml.json
@@ -1,6 +1,6 @@
{
"filename": "xml.md",
- "__html": "<h1>XML Configuration</h1>\n<p>About the XML configuration items, see:<a href=\"../references/xml/introduction.md\">XML References</a>. If you prefer use API directly instead of using Spring, see <a href=\"./api.md\">API Configuration</a>. Want a example of how to use configuration, see <a href=\"../quick-start.md\">Quick Start</a>。</p>\n<h2>provider.xml demo</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-meta\"><?xml version=\"1.0\" encoding=\"UTF-8\"?></s [...]
+ "__html": "<h1>XML Configuration</h1>\n<p>About the XML configuration items, see:<a href=\"../references/xml/introduction.md\">XML References</a>. If you prefer use API directly instead of using Spring, see <a href=\"./api.md\">API Configuration</a>. Want a example of how to use configuration, see <a href=\"../quick-start.md\">Quick Start</a>。</p>\n<h2>provider.xml demo</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-meta\"><?xml version=\"1.0\" encoding=\"UTF-8\"?></s [...]
"link": "/en-us/docs/user/configuration/xml.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/demos/events-notify.html b/en-us/docs/user/demos/events-notify.html
index 43b1c26..73a42f1 100644
--- a/en-us/docs/user/demos/events-notify.html
+++ b/en-us/docs/user/demos/events-notify.html
@@ -29,8 +29,8 @@
<h2>Service provider configure the service which it provided.</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:application</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"rpc-callback-demo"</span> /></span>
<span class="hljs-tag"><<span class="hljs-name">dubbo:registry</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"zookeeper://127.0.0.1:2181"</span>/></span>
-<span class="hljs-tag"><<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"com.alibaba.dubbo.callback.implicit.NormalDemoService"</span> /></span>
-<span class="hljs-tag"><<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"com.alibaba.dubbo.callback.implicit.IDemoService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">version</span>=<span class="hljs-string">"1.0.0"</span> <span class="hljs-attr">group</span>=<span class="hljs-string">"cn"</span>/></span>
+<span class="hljs-tag"><<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"org.apache.dubbo.callback.implicit.NormalDemoService"</span> /></span>
+<span class="hljs-tag"><<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.callback.implicit.IDemoService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">version</span>=<span class="hljs-string">"1.0.0"</span> <span class="hljs-attr">group</span>=<span class="hljs-string">"cn"</span>/></span>
</code></pre>
<h2>Declare the Callback interface at service consumer-side.</h2>
<pre><code class="language-java"><span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Notify</span> </span>{
@@ -54,8 +54,8 @@
}
</code></pre>
<h2>Configure the Callback at service consumer-side.</h2>
-<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">bean</span> <span class="hljs-attr">id</span> =<span class="hljs-string">"demoCallback"</span> <span class="hljs-attr">class</span> = <span class="hljs-string">"com.alibaba.dubbo.callback.implicit.NofifyImpl"</span> /></span>
-<span class="hljs-tag"><<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"com.alibaba.dubbo.callback.implicit.IDemoService"</span> <span class="hljs-attr">version</span>=<span class="hljs-string">"1.0.0"</span> <span class="hljs-attr">group</span>=<span class="hljs-string">"cn"</span> ></span>
+<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">bean</span> <span class="hljs-attr">id</span> =<span class="hljs-string">"demoCallback"</span> <span class="hljs-attr">class</span> = <span class="hljs-string">"org.apache.dubbo.callback.implicit.NofifyImpl"</span> /></span>
+<span class="hljs-tag"><<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"demoService"</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.callback.implicit.IDemoService"</span> <span class="hljs-attr">version</span>=<span class="hljs-string">"1.0.0"</span> <span class="hljs-attr">group</span>=<span class="hljs-string">"cn"</span> ></span>
<span class="hljs-tag"><<span class="hljs-name">dubbo:method</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"get"</span> <span class="hljs-attr">async</span>=<span class="hljs-string">"true"</span> <span class="hljs-attr">onreturn</span> = <span class="hljs-string">"demoCallback.onreturn"</span> <span class="hljs-attr">onthrow</span>=<span class="hljs-string">"demoCallback.onthrow"</span> /></span>
<span class="hljs-tag"></<span class="hljs-name">dubbo:reference</span>></span>
</code></pre>
diff --git a/en-us/docs/user/demos/events-notify.json b/en-us/docs/user/demos/events-notify.json
index df38083..612c8ee 100644
--- a/en-us/docs/user/demos/events-notify.json
+++ b/en-us/docs/user/demos/events-notify.json
@@ -1,6 +1,6 @@
{
"filename": "events-notify.md",
- "__html": "<h1>Event Notify</h1>\n<p>Before calling, after calling, when an exception occurs,will trigger <code>oninvoke</code>, <code>onreturn</code>, <code>onthrow</code> events.You can configure which method to notify when an event occurs.</p>\n<h2>Service Interface</h2>\n<pre><code class=\"language-java\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">interface</span> <span class=\"hljs-title\">IDemoService</span> </span>{\n <span class=\"hljs-function\"><span class=\"h [...]
+ "__html": "<h1>Event Notify</h1>\n<p>Before calling, after calling, when an exception occurs,will trigger <code>oninvoke</code>, <code>onreturn</code>, <code>onthrow</code> events.You can configure which method to notify when an event occurs.</p>\n<h2>Service Interface</h2>\n<pre><code class=\"language-java\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">interface</span> <span class=\"hljs-title\">IDemoService</span> </span>{\n <span class=\"hljs-function\"><span class=\"h [...]
"link": "/en-us/docs/user/demos/events-notify.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/demos/generic-reference.html b/en-us/docs/user/demos/generic-reference.html
index 9460270..3d2d604 100644
--- a/en-us/docs/user/demos/generic-reference.html
+++ b/en-us/docs/user/demos/generic-reference.html
@@ -23,7 +23,7 @@
Object result = barService.$invoke(<span class="hljs-string">"sayHello"</span>, <span class="hljs-keyword">new</span> String[] { <span class="hljs-string">"java.lang.String"</span> }, <span class="hljs-keyword">new</span> Object[] { <span class="hljs-string">"World"</span> });
</code></pre>
<h2>Use generic invocation via API</h2>
-<pre><code class="language-java"><span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.service.GenericService;
+<pre><code class="language-java"><span class="hljs-keyword">import</span> org.apache.dubbo.rpc.service.GenericService;
...
<span class="hljs-comment">// reference remote service</span>
@@ -35,7 +35,7 @@ reference.setVersion(<span class="hljs-string">"1.0.0"</span>);
<span class="hljs-comment">// declared as generic service</span>
reference.setGeneric(<span class="hljs-keyword">true</span>);
-<span class="hljs-comment">// service stub type is also the com.alibaba.dubbo.rpc.service.GenericService</span>
+<span class="hljs-comment">// service stub type is also the org.apache.dubbo.rpc.service.GenericService</span>
GenericService genericService = reference.get();
<span class="hljs-comment">// basic types and Date, List, Map, etc. do not need conversion, direct use them</span>
diff --git a/en-us/docs/user/demos/generic-reference.json b/en-us/docs/user/demos/generic-reference.json
index 4d73e9a..9bfb776 100644
--- a/en-us/docs/user/demos/generic-reference.json
+++ b/en-us/docs/user/demos/generic-reference.json
@@ -1,6 +1,6 @@
{
"filename": "generic-reference.md",
- "__html": "<h1>Generic Reference</h1>\n<p>Generic invocation is mainly used when the client does not have API interface or model class, all POJOs in parameters and return values are represented by <code>Map</code>.Commonly used for framework integration such as: implementing a common service testing framework, all service implementations can be invoked via <code>GenericService</code>.</p>\n<h2>Use generic invocation via Spring</h2>\n<p>Declared in the Spring configuration file <code>g [...]
+ "__html": "<h1>Generic Reference</h1>\n<p>Generic invocation is mainly used when the client does not have API interface or model class, all POJOs in parameters and return values are represented by <code>Map</code>.Commonly used for framework integration such as: implementing a common service testing framework, all service implementations can be invoked via <code>GenericService</code>.</p>\n<h2>Use generic invocation via Spring</h2>\n<p>Declared in the Spring configuration file <code>g [...]
"link": "/en-us/docs/user/demos/generic-reference.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/demos/generic-service.html b/en-us/docs/user/demos/generic-service.html
index 2cb5d9f..ddd3541 100644
--- a/en-us/docs/user/demos/generic-service.html
+++ b/en-us/docs/user/demos/generic-service.html
@@ -32,7 +32,7 @@
</code></pre>
<h2>Export generic implements via API</h2>
<pre><code class="language-java">...
-<span class="hljs-comment">// use com.alibaba.dubbo.rpc.service.GenericService can replace all implements</span>
+<span class="hljs-comment">// use org.apache.dubbo.rpc.service.GenericService can replace all implements</span>
GenericService xxxService = <span class="hljs-keyword">new</span> XxxGenericService();
<span class="hljs-comment">// The instance is very heavy, which encapsulates all the registration center and service provider connection, please cache</span>
diff --git a/en-us/docs/user/demos/generic-service.json b/en-us/docs/user/demos/generic-service.json
index bfbd1bb..1bd5f6a 100644
--- a/en-us/docs/user/demos/generic-service.json
+++ b/en-us/docs/user/demos/generic-service.json
@@ -1,6 +1,6 @@
{
"filename": "generic-service.md",
- "__html": "<h1>Generic Service</h1>\n<p>The implementation of the generic interface is mainly used when there is no API interface and model class on the server side. All POJOs in the parameters and return values are represented by the Map and are usually used for framework integration. For example, to implement a universal remote service Mock framework, handle all service requests by implementing the GenericService interface.</p>\n<p>In Java code, implement <code>GenericService</code> [...]
+ "__html": "<h1>Generic Service</h1>\n<p>The implementation of the generic interface is mainly used when there is no API interface and model class on the server side. All POJOs in the parameters and return values are represented by the Map and are usually used for framework integration. For example, to implement a universal remote service Mock framework, handle all service requests by implementing the GenericService interface.</p>\n<p>In Java code, implement <code>GenericService</code> [...]
"link": "/en-us/docs/user/demos/generic-service.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/demos/parameter-validation.html b/en-us/docs/user/demos/parameter-validation.html
index a0c7672..22cc56e 100644
--- a/en-us/docs/user/demos/parameter-validation.html
+++ b/en-us/docs/user/demos/parameter-validation.html
@@ -131,10 +131,10 @@
</code></pre>
<h2>Configuration</h2>
<h3>Validate Parameter on the client</h3>
-<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"validationService"</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"com.alibaba.dubbo.examples.validation.api.ValidationService"</span> <span class="hljs-attr">validation</span>=<span class="hljs-string">"true"</span> /></span>
+<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"validationService"</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.examples.validation.api.ValidationService"</span> <span class="hljs-attr">validation</span>=<span class="hljs-string">"true"</span> /></span>
</code></pre>
<h3>Validate Parameter on the server</h3>
-<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"com.alibaba.dubbo.examples.validation.api.ValidationService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"validationService"</span> <span class="hljs-attr">validation</span>=<span class="hljs-string">"true"</span> /></span>
+<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.examples.validation.api.ValidationService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"validationService"</span> <span class="hljs-attr">validation</span>=<span class="hljs-string">"true"</span> /></span>
</code></pre>
<h2>Validate Exception</h2>
<pre><code class="language-java"><span class="hljs-keyword">import</span> javax.validation.ConstraintViolationException;
@@ -142,9 +142,9 @@
<span class="hljs-keyword">import</span> org.springframework.context.support.ClassPathXmlApplicationContext;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.examples.validation.api.ValidationParameter;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.examples.validation.api.ValidationService;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.RpcException;
+<span class="hljs-keyword">import</span> org.apache.dubbo.examples.validation.api.ValidationParameter;
+<span class="hljs-keyword">import</span> org.apache.dubbo.examples.validation.api.ValidationService;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.RpcException;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ValidationConsumer</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception </span>{
diff --git a/en-us/docs/user/demos/parameter-validation.json b/en-us/docs/user/demos/parameter-validation.json
index f95dff4..0f705b0 100644
--- a/en-us/docs/user/demos/parameter-validation.json
+++ b/en-us/docs/user/demos/parameter-validation.json
@@ -1,6 +1,6 @@
{
"filename": "parameter-validation.md",
- "__html": "<h1>Parameter Validation</h1>\n<p>The parameter validation <sup class=\"footnote-ref\"><a href=\"#fn1\" id=\"fnref1\">[1]</a></sup> is based on [JSR303] (<a href=\"https://jcp.org/en/jsr/detail?id=303\">https://jcp.org/en/jsr/detail?id=303</a>). The user simply add the validation annotation of the JSR303 and declares the filter for validation <sup class=\"footnote-ref\"><a href=\"#fn2\" id=\"fnref2\">[2]</a></sup>.</p>\n<h2>Maven Dependency</h2>\n<pre><code class=\"language- [...]
+ "__html": "<h1>Parameter Validation</h1>\n<p>The parameter validation <sup class=\"footnote-ref\"><a href=\"#fn1\" id=\"fnref1\">[1]</a></sup> is based on [JSR303] (<a href=\"https://jcp.org/en/jsr/detail?id=303\">https://jcp.org/en/jsr/detail?id=303</a>). The user simply add the validation annotation of the JSR303 and declares the filter for validation <sup class=\"footnote-ref\"><a href=\"#fn2\" id=\"fnref2\">[2]</a></sup>.</p>\n<h2>Maven Dependency</h2>\n<pre><code class=\"language- [...]
"link": "/en-us/docs/user/demos/parameter-validation.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/demos/serialization.html b/en-us/docs/user/demos/serialization.html
index 8490169..1ead0be 100644
--- a/en-us/docs/user/demos/serialization.html
+++ b/en-us/docs/user/demos/serialization.html
@@ -36,7 +36,7 @@
}
</code></pre>
<p><font size=3>Then add in the XML configuration:</font></p>
-<pre><code><dubbo:protocol name="dubbo" serialization="kryo" optimizer="com.alibaba.dubbo.demo.SerializationOptimizerImpl"/>
+<pre><code><dubbo:protocol name="dubbo" serialization="kryo" optimizer="org.apache.dubbo.demo.SerializationOptimizerImpl"/>
</code></pre>
<p><font size=3>After registering these classes, serialization performance can be greatly improved, especially for small numbers of nested objects.</p>
<p>Of course, when serializing a class, you might also cascade references to many classes, such as Java collection classes. In this case, we've automatically registered common classes in the JDK, so you don't need to register them repeatedly (and of course, it doesn't matter if you register them again), including:</font></p>
diff --git a/en-us/docs/user/demos/serialization.json b/en-us/docs/user/demos/serialization.json
index cb1f95c..5a5ae98 100644
--- a/en-us/docs/user/demos/serialization.json
+++ b/en-us/docs/user/demos/serialization.json
@@ -1,6 +1,6 @@
{
"filename": "serialization.md",
- "__html": "<h2><font size=6>Using Efficient Java Serialization in Dubbo (Kryo and FST)</font></h2>\n<h2>Start Kryo and FST</h2>\n<p><font size=3>Using Kryo and FST is very simple, just add an attribute to the dubbo RPC XML configurition:</font></p>\n<pre><code><dubbo:protocol name="dubbo" serialization="kryo"/>\n</code></pre>\n<pre><code><dubbo:protocol name="dubbo" serialization="fst"/>\n</code></pre>\n<h2>Register serialized class</ [...]
+ "__html": "<h2><font size=6>Using Efficient Java Serialization in Dubbo (Kryo and FST)</font></h2>\n<h2>Start Kryo and FST</h2>\n<p><font size=3>Using Kryo and FST is very simple, just add an attribute to the dubbo RPC XML configurition:</font></p>\n<pre><code><dubbo:protocol name="dubbo" serialization="kryo"/>\n</code></pre>\n<pre><code><dubbo:protocol name="dubbo" serialization="fst"/>\n</code></pre>\n<h2>Register serialized class</ [...]
"link": "/en-us/docs/user/demos/serialization.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/demos/service-container.html b/en-us/docs/user/demos/service-container.html
index 46123f6..0db1467 100644
--- a/en-us/docs/user/demos/service-container.html
+++ b/en-us/docs/user/demos/service-container.html
@@ -49,13 +49,13 @@
</ul>
<h2>Container startup</h2>
<p>load spring by default.</p>
-<pre><code class="language-sh">java com.alibaba.dubbo.container.Main
+<pre><code class="language-sh">java org.apache.dubbo.container.Main
</code></pre>
<p>Load the container that passed in by the main method</p>
-<pre><code class="language-sh">java com.alibaba.dubbo.container.Main spring jetty log4j
+<pre><code class="language-sh">java org.apache.dubbo.container.Main spring jetty log4j
</code></pre>
<p>Load the container that passed in by the JVM option.</p>
-<pre><code class="language-sh">java com.alibaba.dubbo.container.Main -Ddubbo.container=spring,jetty,log4j
+<pre><code class="language-sh">java org.apache.dubbo.container.Main -Ddubbo.container=spring,jetty,log4j
</code></pre>
<p>Load the container that passed in by <code>dubbo.properties</code> in the classpath.</p>
<pre><code>dubbo.container=spring,jetty,log4j
diff --git a/en-us/docs/user/demos/service-container.json b/en-us/docs/user/demos/service-container.json
index b3e6c24..cdea864 100644
--- a/en-us/docs/user/demos/service-container.json
+++ b/en-us/docs/user/demos/service-container.json
@@ -1,6 +1,6 @@
{
"filename": "service-container.md",
- "__html": "<h1>Service container</h1>\n<p>The service container is a standalone launcher because the backend service does not require the functionality of a Web container ,such as Tomcat or JBoss. If you insist on using web containers to load service providers, that increase complexity and is waste of resources.</p>\n<p>The service container is just a simple Main method and loads a simple Spring container to expose the service.</p>\n<p>The content of Service container can be extended, [...]
+ "__html": "<h1>Service container</h1>\n<p>The service container is a standalone launcher because the backend service does not require the functionality of a Web container ,such as Tomcat or JBoss. If you insist on using web containers to load service providers, that increase complexity and is waste of resources.</p>\n<p>The service container is just a simple Main method and loads a simple Spring container to expose the service.</p>\n<p>The content of Service container can be extended, [...]
"link": "/en-us/docs/user/demos/service-container.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/references/api.html b/en-us/docs/user/references/api.html
index 1674687..5b7d568 100644
--- a/en-us/docs/user/references/api.html
+++ b/en-us/docs/user/references/api.html
@@ -16,38 +16,38 @@
<p>Generally speaking, dubbo keeps its functionality no intrusive as much as possible, but for some particular features, there's no other way not only API can achieve. <sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p>
<p>These APIs are summarized here below:</p>
<h2>Configuration API</h2>
-<pre><code>com.alibaba.dubbo.config.ServiceConfig
-com.alibaba.dubbo.config.ReferenceConfig
-com.alibaba.dubbo.config.ProtocolConfig
-com.alibaba.dubbo.config.RegistryConfig
-com.alibaba.dubbo.config.MonitorConfig
-com.alibaba.dubbo.config.ApplicationConfig
-com.alibaba.dubbo.config.ModuleConfig
-com.alibaba.dubbo.config.ProviderConfig
-com.alibaba.dubbo.config.ConsumerConfig
-com.alibaba.dubbo.config.MethodConfig
-com.alibaba.dubbo.config.ArgumentConfig
+<pre><code>org.apache.dubbo.config.ServiceConfig
+org.apache.dubbo.config.ReferenceConfig
+org.apache.dubbo.config.ProtocolConfig
+org.apache.dubbo.config.RegistryConfig
+org.apache.dubbo.config.MonitorConfig
+org.apache.dubbo.config.ApplicationConfig
+org.apache.dubbo.config.ModuleConfig
+org.apache.dubbo.config.ProviderConfig
+org.apache.dubbo.config.ConsumerConfig
+org.apache.dubbo.config.MethodConfig
+org.apache.dubbo.config.ArgumentConfig
</code></pre>
<p>Pls. refer to <a href="../configuration/api.md">API Configuration</a> for further information.</p>
<h2>Annotation API</h2>
-<pre><code>com.alibaba.dubbo.config.annotation.Service
-com.alibaba.dubbo.config.annotation.Reference
+<pre><code>org.apache.dubbo.config.annotation.Service
+org.apache.dubbo.config.annotation.Reference
</code></pre>
<p>Pls. refer to <a href="../configuration/annotation.md">Annotation Configuration</a> for further information.</p>
<h2>Model API</h2>
-<pre><code>com.alibaba.dubbo.common.URL
-com.alibaba.dubbo.rpc.RpcException
+<pre><code>org.apache.dubbo.common.URL
+org.apache.dubbo.rpc.RpcException
</code></pre>
<h2>Context API</h2>
-<pre><code>com.alibaba.dubbo.rpc.RpcContext
+<pre><code>org.apache.dubbo.rpc.RpcContext
</code></pre>
<p>Pls. refer to <a href="../demos/context.md">context</a> & <a href="../demos/attachment.md">pass parameter in attachment</a> & <a href="../demos/async-call.md">asynchronous call</a> for further information.</p>
<h2>Service API</h2>
-<pre><code>com.alibaba.dubbo.rpc.service.GenericService
-com.alibaba.dubbo.rpc.service.GenericException
+<pre><code>org.apache.dubbo.rpc.service.GenericService
+org.apache.dubbo.rpc.service.GenericException
</code></pre>
<p>Pls. refer to <a href="../demos/generic-reference.md">generic reference</a> & <a href="../demos/generic-service.md">generic service</a> for further information.</p>
-<pre><code>com.alibaba.dubbo.rpc.service.EchoService
+<pre><code>org.apache.dubbo.rpc.service.EchoService
</code></pre>
<p>Pls. refer to <a href="../demos/echo-service.md">test via echo service</a> for further details.</p>
<hr class="footnotes-sep">
diff --git a/en-us/docs/user/references/api.json b/en-us/docs/user/references/api.json
index 7c26f9d..e331f5f 100644
--- a/en-us/docs/user/references/api.json
+++ b/en-us/docs/user/references/api.json
@@ -1,6 +1,6 @@
{
"filename": "api.md",
- "__html": "<h1>API Reference</h1>\n<p>Generally speaking, dubbo keeps its functionality no intrusive as much as possible, but for some particular features, there's no other way not only API can achieve. <sup class=\"footnote-ref\"><a href=\"#fn1\" id=\"fnref1\">[1]</a></sup></p>\n<p>These APIs are summarized here below:</p>\n<h2>Configuration API</h2>\n<pre><code>com.alibaba.dubbo.config.ServiceConfig\ncom.alibaba.dubbo.config.ReferenceConfig\ncom.alibaba.dubbo.config.ProtocolConfig\nc [...]
+ "__html": "<h1>API Reference</h1>\n<p>Generally speaking, dubbo keeps its functionality no intrusive as much as possible, but for some particular features, there's no other way not only API can achieve. <sup class=\"footnote-ref\"><a href=\"#fn1\" id=\"fnref1\">[1]</a></sup></p>\n<p>These APIs are summarized here below:</p>\n<h2>Configuration API</h2>\n<pre><code>org.apache.dubbo.config.ServiceConfig\norg.apache.dubbo.config.ReferenceConfig\norg.apache.dubbo.config.ProtocolConfig\norg. [...]
"link": "/en-us/docs/user/references/api.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/references/protocol/http.html b/en-us/docs/user/references/protocol/http.html
index f99d4bb..57f7fbb 100644
--- a/en-us/docs/user/references/protocol/http.html
+++ b/en-us/docs/user/references/protocol/http.html
@@ -41,7 +41,7 @@
<p>configure DispatcherServlet:</p>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">servlet</span>></span>
<span class="hljs-tag"><<span class="hljs-name">servlet-name</span>></span>dubbo<span class="hljs-tag"></<span class="hljs-name">servlet-name</span>></span>
- <span class="hljs-tag"><<span class="hljs-name">servlet-class</span>></span>com.alibaba.dubbo.remoting.http.servlet.DispatcherServlet<span class="hljs-tag"></<span class="hljs-name">servlet-class</span>></span>
+ <span class="hljs-tag"><<span class="hljs-name">servlet-class</span>></span>org.apache.dubbo.remoting.http.servlet.DispatcherServlet<span class="hljs-tag"></<span class="hljs-name">servlet-class</span>></span>
<span class="hljs-tag"><<span class="hljs-name">load-on-startup</span>></span>1<span class="hljs-tag"></<span class="hljs-name">load-on-startup</span>></span>
<span class="hljs-tag"></<span class="hljs-name">servlet</span>></span>
<span class="hljs-tag"><<span class="hljs-name">servlet-mapping</span>></span>
diff --git a/en-us/docs/user/references/protocol/http.json b/en-us/docs/user/references/protocol/http.json
index d117358..4ba8ca3 100644
--- a/en-us/docs/user/references/protocol/http.json
+++ b/en-us/docs/user/references/protocol/http.json
@@ -1,6 +1,6 @@
{
"filename": "http.md",
- "__html": "<h1>http://</h1>\n<p>Dubbo http protocol is base on HTTP form and Spring's HttpInvoker</p>\n<h2>Features</h2>\n<ul>\n<li>Number of connections: multiple connections</li>\n<li>Connection: short connection</li>\n<li>Transmission protocol: HTTP</li>\n<li>Transmission: synchronous transmission</li>\n<li>Serialization: form serialization</li>\n<li>Scope of application: Available browser view, the form or URL can be passed parameters, Temporary files are not supported.</li>\n<li>A [...]
+ "__html": "<h1>http://</h1>\n<p>Dubbo http protocol is base on HTTP form and Spring's HttpInvoker</p>\n<h2>Features</h2>\n<ul>\n<li>Number of connections: multiple connections</li>\n<li>Connection: short connection</li>\n<li>Transmission protocol: HTTP</li>\n<li>Transmission: synchronous transmission</li>\n<li>Serialization: form serialization</li>\n<li>Scope of application: Available browser view, the form or URL can be passed parameters, Temporary files are not supported.</li>\n<li>A [...]
"link": "/en-us/docs/user/references/protocol/http.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/references/protocol/webservice.html b/en-us/docs/user/references/protocol/webservice.html
index bbe5e52..ada2c13 100644
--- a/en-us/docs/user/references/protocol/webservice.html
+++ b/en-us/docs/user/references/protocol/webservice.html
@@ -74,7 +74,7 @@
<p>configure DispatcherServlet:</p>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">servlet</span>></span>
<span class="hljs-tag"><<span class="hljs-name">servlet-name</span>></span>dubbo<span class="hljs-tag"></<span class="hljs-name">servlet-name</span>></span>
- <span class="hljs-tag"><<span class="hljs-name">servlet-class</span>></span>com.alibaba.dubbo.remoting.http.servlet.DispatcherServlet<span class="hljs-tag"></<span class="hljs-name">servlet-class</span>></span>
+ <span class="hljs-tag"><<span class="hljs-name">servlet-class</span>></span>org.apache.dubbo.remoting.http.servlet.DispatcherServlet<span class="hljs-tag"></<span class="hljs-name">servlet-class</span>></span>
<span class="hljs-tag"><<span class="hljs-name">load-on-startup</span>></span>1<span class="hljs-tag"></<span class="hljs-name">load-on-startup</span>></span>
<span class="hljs-tag"></<span class="hljs-name">servlet</span>></span>
<span class="hljs-tag"><<span class="hljs-name">servlet-mapping</span>></span>
diff --git a/en-us/docs/user/references/protocol/webservice.json b/en-us/docs/user/references/protocol/webservice.json
index 58b1400..4b460d1 100644
--- a/en-us/docs/user/references/protocol/webservice.json
+++ b/en-us/docs/user/references/protocol/webservice.json
@@ -1,6 +1,6 @@
{
"filename": "webservice.md",
- "__html": "<h1>webservice://</h1>\n<p>WebService-based remote calling protocol,base on <a href=\"http://cxf.apache.org\">Apache CXF</a> <code>frontend-simple</code> and <code>transports-http</code> implements。</p>\n<p>Interoperable with native WebService services:</p>\n<ul>\n<li>Providers expose services using Dubbo's WebService protocol, which consumers invoke directly using the standard WebService interface,</li>\n<li>Or the provider exposes the service using the standard WebServic [...]
+ "__html": "<h1>webservice://</h1>\n<p>WebService-based remote calling protocol,base on <a href=\"http://cxf.apache.org\">Apache CXF</a> <code>frontend-simple</code> and <code>transports-http</code> implements。</p>\n<p>Interoperable with native WebService services:</p>\n<ul>\n<li>Providers expose services using Dubbo's WebService protocol, which consumers invoke directly using the standard WebService interface,</li>\n<li>Or the provider exposes the service using the standard WebServic [...]
"link": "/en-us/docs/user/references/protocol/webservice.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/references/qos.html b/en-us/docs/user/references/qos.html
index cebcbd6..cd225e6 100644
--- a/en-us/docs/user/references/qos.html
+++ b/en-us/docs/user/references/qos.html
@@ -53,7 +53,7 @@ As Provider side:
+----------------------------------+---+
| Provider Service Name |PUB|
+----------------------------------+---+
-|com.alibaba.dubbo.demo.DemoService| N |
+|org.apache.dubbo.demo.DemoService| N |
+----------------------------------+---+
As Consumer side:
+---------------------+---+
@@ -67,7 +67,7 @@ As Provider side:
+----------------------------------+---+
| Provider Service Name |PUB|
+----------------------------------+---+
-|com.alibaba.dubbo.demo.DemoService| N |
+|org.apache.dubbo.demo.DemoService| N |
+----------------------------------+---+
As Consumer side:
+---------------------+---+
@@ -81,7 +81,7 @@ As Provider side:
+----------------------------------+---+
| Provider Service Name |PUB|
+----------------------------------+---+
-|com.alibaba.dubbo.demo.DemoService| Y |
+|org.apache.dubbo.demo.DemoService| Y |
+----------------------------------+---+
As Consumer side:
+---------------------+---+
@@ -90,7 +90,7 @@ As Consumer side:
</code></pre>
<p>List the services of the provides and the consumers that dubbo provide</p>
<h3>Online service command</h3>
-<p>When using delay publishing function(com.alibaba.dubbo.config.AbstractServiceConfig#register set as false), you can use “online” command to online the service</p>
+<p>When using delay publishing function(org.apache.dubbo.config.AbstractServiceConfig#register set as false), you can use “online” command to online the service</p>
<pre><code>//online all services
dubbo>online
OK
diff --git a/en-us/docs/user/references/qos.json b/en-us/docs/user/references/qos.json
index d099d3d..111c1fa 100644
--- a/en-us/docs/user/references/qos.json
+++ b/en-us/docs/user/references/qos.json
@@ -1,6 +1,6 @@
{
"filename": "qos.md",
- "__html": "<h1>Telnet (new version) Command Usage</h1>\n<p>In dubbo <code>2.5.8</code> a new QOS module is introduced, to provide new telnet command support.</p>\n<h2>Port</h2>\n<p>the port of new version telnet is different from the port of dubbo protocol. The default port is <code>22222</code>, which can be changed by modifying configuration file <code>dubbo.properties</code></p>\n<pre><code>dubbo.application.qos.port=33333\n</code></pre>\n<p>or by modifying the JVM parameter</p>\n<p [...]
+ "__html": "<h1>Telnet (new version) Command Usage</h1>\n<p>In dubbo <code>2.5.8</code> a new QOS module is introduced, to provide new telnet command support.</p>\n<h2>Port</h2>\n<p>the port of new version telnet is different from the port of dubbo protocol. The default port is <code>22222</code>, which can be changed by modifying configuration file <code>dubbo.properties</code></p>\n<pre><code>dubbo.application.qos.port=33333\n</code></pre>\n<p>or by modifying the JVM parameter</p>\n<p [...]
"link": "/en-us/docs/user/references/qos.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/references/registry/simple.html b/en-us/docs/user/references/registry/simple.html
index e5a3531..164cc58 100644
--- a/en-us/docs/user/references/registry/simple.html
+++ b/en-us/docs/user/references/registry/simple.html
@@ -26,19 +26,19 @@
<span class="hljs-comment"><!-- service protocol configuration --></span>
<span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">port</span>=<span class="hljs-string">"9090"</span> /></span>
<span class="hljs-comment"><!-- service configuration --></span>
- <span class="hljs-tag"><<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"com.alibaba.dubbo.registry.RegistryService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"registryService"</span> <span class="hljs-attr">registry</span>=<span class="hljs-string">"N/A"</span> <span class="hljs-attr">ondisconnect</span>=<span class="hljs-string">"disconnect"</span> <span class="hljs-attr">callbacks</span>=< [...]
+ <span class="hljs-tag"><<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.registry.RegistryService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"registryService"</span> <span class="hljs-attr">registry</span>=<span class="hljs-string">"N/A"</span> <span class="hljs-attr">ondisconnect</span>=<span class="hljs-string">"disconnect"</span> <span class="hljs-attr">callbacks</span>=<s [...]
<span class="hljs-tag"><<span class="hljs-name">dubbo:method</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"subscribe"</span>></span><span class="hljs-tag"><<span class="hljs-name">dubbo:argument</span> <span class="hljs-attr">index</span>=<span class="hljs-string">"1"</span> <span class="hljs-attr">callback</span>=<span class="hljs-string">"true"</span> /></span><span class="hljs-tag"></<span class="hljs-name">dubbo:method</span>></span>
<span class="hljs-tag"><<span class="hljs-name">dubbo:method</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"unsubscribe"</span>></span><span class="hljs-tag"><<span class="hljs-name">dubbo:argument</span> <span class="hljs-attr">index</span>=<span class="hljs-string">"1"</span> <span class="hljs-attr">callback</span>=<span class="hljs-string">"false"</span> /></span><span class="hljs-tag"></<span class="hljs-name">dubbo:method</span>></span>
<span class="hljs-tag"></<span class="hljs-name">dubbo:service</span>></span>
<span class="hljs-comment"><!-- simple registry server implementation, register other implementation if cluster ability is a requirement--></span>
- <span class="hljs-tag"><<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"registryService"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"com.alibaba.dubbo.registry.simple.SimpleRegistryService"</span> /></span>
+ <span class="hljs-tag"><<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"registryService"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"org.apache.dubbo.registry.simple.SimpleRegistryService"</span> /></span>
<span class="hljs-tag"></<span class="hljs-name">beans</span>></span>
</code></pre>
<p>Reference simple registry server service:</p>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:registry</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"127.0.0.1:9090"</span> /></span>
</code></pre>
<p>Or:</p>
-<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"com.alibaba.dubbo.registry.RegistryService"</span> <span class="hljs-attr">group</span>=<span class="hljs-string">"simple"</span> <span class="hljs-attr">version</span>=<span class="hljs-string">"1.0.0"</span> <span class="hljs-attr">...</span> ></span>
+<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.registry.RegistryService"</span> <span class="hljs-attr">group</span>=<span class="hljs-string">"simple"</span> <span class="hljs-attr">version</span>=<span class="hljs-string">"1.0.0"</span> <span class="hljs-attr">...</span> ></span>
</code></pre>
<p>Or:</p>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:registry</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"127.0.0.1:9090"</span> <span class="hljs-attr">group</span>=<span class="hljs-string">"simple"</span> <span class="hljs-attr">version</span>=<span class="hljs-string">"1.0.0"</span> /></span>
diff --git a/en-us/docs/user/references/registry/simple.json b/en-us/docs/user/references/registry/simple.json
index f1b2528..82ea6ac 100644
--- a/en-us/docs/user/references/registry/simple.json
+++ b/en-us/docs/user/references/registry/simple.json
@@ -1,6 +1,6 @@
{
"filename": "simple.md",
- "__html": "<h1>Simple Registry Server</h1>\n<p>Simple registry server itself is a regular dubbo service. In this way, third-party dependency is unnecessary, and communication keeps consistent at the same moment.</p>\n<h2>Configuration</h2>\n<p>Register simple registry server as dubbo service:</p>\n<pre><code class=\"language-xml\"><span class=\"hljs-meta\"><?xml version=\"1.0\" encoding=\"UTF-8\"?></span>\n<span class=\"hljs-tag\"><<span class=\"hljs-name\">beans</span> <span [...]
+ "__html": "<h1>Simple Registry Server</h1>\n<p>Simple registry server itself is a regular dubbo service. In this way, third-party dependency is unnecessary, and communication keeps consistent at the same moment.</p>\n<h2>Configuration</h2>\n<p>Register simple registry server as dubbo service:</p>\n<pre><code class=\"language-xml\"><span class=\"hljs-meta\"><?xml version=\"1.0\" encoding=\"UTF-8\"?></span>\n<span class=\"hljs-tag\"><<span class=\"hljs-name\">beans</span> <span [...]
"link": "/en-us/docs/user/references/registry/simple.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/references/xml/dubbo-application.html b/en-us/docs/user/references/xml/dubbo-application.html
index 99de8f2..522909f 100644
--- a/en-us/docs/user/references/xml/dubbo-application.html
+++ b/en-us/docs/user/references/xml/dubbo-application.html
@@ -56,7 +56,7 @@ table tr:hover {
})
</script>
<h1>dubbo:application</h1>
-<p>Application configuration. The corresponding class: <code>com.alibaba.dubbo.config.ApplicationConfig</code></p>
+<p>Application configuration. The corresponding class: <code>org.apache.dubbo.config.ApplicationConfig</code></p>
<table>
<thead>
<tr>
diff --git a/en-us/docs/user/references/xml/dubbo-application.json b/en-us/docs/user/references/xml/dubbo-application.json
index 515ae1e..62a022a 100644
--- a/en-us/docs/user/references/xml/dubbo-application.json
+++ b/en-us/docs/user/references/xml/dubbo-application.json
@@ -1,6 +1,6 @@
{
"filename": "dubbo-application.md",
- "__html": "<style>\ntable {\n width: 100%;\n max-width: 65em;\n border: 1px solid #dedede;\n margin: 15px auto;\n border-collapse: collapse;\n empty-cells: show;\n}\ntable th,\ntable td {\n height: 35px;\n border: 1px solid #dedede;\n padding: 0 10px;\n}\ntable th {\n font-weight: bold;\n text-align: center !important;\n background: rgba(158,188,226,0.2);\n white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n background: rgba(158,188,226,0.12);\n}\ntable td:nth-child [...]
+ "__html": "<style>\ntable {\n width: 100%;\n max-width: 65em;\n border: 1px solid #dedede;\n margin: 15px auto;\n border-collapse: collapse;\n empty-cells: show;\n}\ntable th,\ntable td {\n height: 35px;\n border: 1px solid #dedede;\n padding: 0 10px;\n}\ntable th {\n font-weight: bold;\n text-align: center !important;\n background: rgba(158,188,226,0.2);\n white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n background: rgba(158,188,226,0.12);\n}\ntable td:nth-child [...]
"link": "/en-us/docs/user/references/xml/dubbo-application.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/references/xml/dubbo-argument.html b/en-us/docs/user/references/xml/dubbo-argument.html
index 36509f0..9a0ef13 100644
--- a/en-us/docs/user/references/xml/dubbo-argument.html
+++ b/en-us/docs/user/references/xml/dubbo-argument.html
@@ -56,7 +56,7 @@ table tr:hover {
})
</script>
<h1>dubbo:argument</h1>
-<p>Method argument configuration. The corresponding class:<code>com.alibaba.dubbo.config.ArgumentConfig</code>. This tag is child of <code><dubbo:method></code>, which is for feature description of method argument, such as:</p>
+<p>Method argument configuration. The corresponding class:<code>org.apache.dubbo.config.ArgumentConfig</code>. This tag is child of <code><dubbo:method></code>, which is for feature description of method argument, such as:</p>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:method</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"findXxx"</span> <span class="hljs-attr">timeout</span>=<span class="hljs-string">"3000"</span> <span class="hljs-attr">retries</span>=<span class="hljs-string">"2"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">dubbo:argument</span> <span class="hljs-attr">index</span>=<span class="hljs-string">"0"</span> <span class="hljs-attr">callback</span>=<span class="hljs-string">"true"</span> /></span>
<span class="hljs-tag"></<span class="hljs-name">dubbo:method</span>></span>
diff --git a/en-us/docs/user/references/xml/dubbo-argument.json b/en-us/docs/user/references/xml/dubbo-argument.json
index 3c9f936..5bd6ad6 100644
--- a/en-us/docs/user/references/xml/dubbo-argument.json
+++ b/en-us/docs/user/references/xml/dubbo-argument.json
@@ -1,6 +1,6 @@
{
"filename": "dubbo-argument.md",
- "__html": "<style>\ntable {\n width: 100%;\n max-width: 65em;\n border: 1px solid #dedede;\n margin: 15px auto;\n border-collapse: collapse;\n empty-cells: show;\n}\ntable th,\ntable td {\n height: 35px;\n border: 1px solid #dedede;\n padding: 0 10px;\n}\ntable th {\n font-weight: bold;\n text-align: center !important;\n background: rgba(158,188,226,0.2);\n white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n background: rgba(158,188,226,0.12);\n}\ntable td:nth-child [...]
+ "__html": "<style>\ntable {\n width: 100%;\n max-width: 65em;\n border: 1px solid #dedede;\n margin: 15px auto;\n border-collapse: collapse;\n empty-cells: show;\n}\ntable th,\ntable td {\n height: 35px;\n border: 1px solid #dedede;\n padding: 0 10px;\n}\ntable th {\n font-weight: bold;\n text-align: center !important;\n background: rgba(158,188,226,0.2);\n white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n background: rgba(158,188,226,0.12);\n}\ntable td:nth-child [...]
"link": "/en-us/docs/user/references/xml/dubbo-argument.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/references/xml/dubbo-consumer.html b/en-us/docs/user/references/xml/dubbo-consumer.html
index 512e4ee..6410ac4 100644
--- a/en-us/docs/user/references/xml/dubbo-consumer.html
+++ b/en-us/docs/user/references/xml/dubbo-consumer.html
@@ -56,7 +56,7 @@ table tr:hover {
})
</script>
<h1>dubbo:consumer</h1>
-<p>Consumer default configuration. The corresponding clas: <code>com.alibaba.dubbo.config.ConsumerConfig</code>. It is also default configuration of <code><dubbo:reference></code>.</p>
+<p>Consumer default configuration. The corresponding clas: <code>org.apache.dubbo.config.ConsumerConfig</code>. It is also default configuration of <code><dubbo:reference></code>.</p>
<table>
<thead>
<tr>
diff --git a/en-us/docs/user/references/xml/dubbo-consumer.json b/en-us/docs/user/references/xml/dubbo-consumer.json
index 41a16a5..a058bc2 100644
--- a/en-us/docs/user/references/xml/dubbo-consumer.json
+++ b/en-us/docs/user/references/xml/dubbo-consumer.json
@@ -1,6 +1,6 @@
{
"filename": "dubbo-consumer.md",
- "__html": "<style>\ntable {\n width: 100%;\n max-width: 65em;\n border: 1px solid #dedede;\n margin: 15px auto;\n border-collapse: collapse;\n empty-cells: show;\n}\ntable th,\ntable td {\n height: 35px;\n border: 1px solid #dedede;\n padding: 0 10px;\n}\ntable th {\n font-weight: bold;\n text-align: center !important;\n background: rgba(158,188,226,0.2);\n white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n background: rgba(158,188,226,0.12);\n}\ntable td:nth-child [...]
+ "__html": "<style>\ntable {\n width: 100%;\n max-width: 65em;\n border: 1px solid #dedede;\n margin: 15px auto;\n border-collapse: collapse;\n empty-cells: show;\n}\ntable th,\ntable td {\n height: 35px;\n border: 1px solid #dedede;\n padding: 0 10px;\n}\ntable th {\n font-weight: bold;\n text-align: center !important;\n background: rgba(158,188,226,0.2);\n white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n background: rgba(158,188,226,0.12);\n}\ntable td:nth-child [...]
"link": "/en-us/docs/user/references/xml/dubbo-consumer.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/references/xml/dubbo-method.html b/en-us/docs/user/references/xml/dubbo-method.html
index 1c5ab9c..18a69c2 100644
--- a/en-us/docs/user/references/xml/dubbo-method.html
+++ b/en-us/docs/user/references/xml/dubbo-method.html
@@ -56,7 +56,7 @@ table tr:hover {
})
</script>
<h1>dubbo:method</h1>
-<p>Method level configuration. The corresponding class: <code>com.alibaba.dubbo.config.MethodConfig</code>. This tag is a child tag of <code><dubbo:service></code> or <code><dubbo:reference></code>, for accuracy to method level.</p>
+<p>Method level configuration. The corresponding class: <code>org.apache.dubbo.config.MethodConfig</code>. This tag is a child tag of <code><dubbo:service></code> or <code><dubbo:reference></code>, for accuracy to method level.</p>
<table>
<thead>
<tr>
diff --git a/en-us/docs/user/references/xml/dubbo-method.json b/en-us/docs/user/references/xml/dubbo-method.json
index 30e47cb..d0446d8 100644
--- a/en-us/docs/user/references/xml/dubbo-method.json
+++ b/en-us/docs/user/references/xml/dubbo-method.json
@@ -1,6 +1,6 @@
{
"filename": "dubbo-method.md",
- "__html": "<style>\ntable {\n width: 100%;\n max-width: 65em;\n border: 1px solid #dedede;\n margin: 15px auto;\n border-collapse: collapse;\n empty-cells: show;\n}\ntable th,\ntable td {\n height: 35px;\n border: 1px solid #dedede;\n padding: 0 10px;\n}\ntable th {\n font-weight: bold;\n text-align: center !important;\n background: rgba(158,188,226,0.2);\n white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n background: rgba(158,188,226,0.12);\n}\ntable td:nth-child [...]
+ "__html": "<style>\ntable {\n width: 100%;\n max-width: 65em;\n border: 1px solid #dedede;\n margin: 15px auto;\n border-collapse: collapse;\n empty-cells: show;\n}\ntable th,\ntable td {\n height: 35px;\n border: 1px solid #dedede;\n padding: 0 10px;\n}\ntable th {\n font-weight: bold;\n text-align: center !important;\n background: rgba(158,188,226,0.2);\n white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n background: rgba(158,188,226,0.12);\n}\ntable td:nth-child [...]
"link": "/en-us/docs/user/references/xml/dubbo-method.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/references/xml/dubbo-module.html b/en-us/docs/user/references/xml/dubbo-module.html
index 588147a..228db72 100644
--- a/en-us/docs/user/references/xml/dubbo-module.html
+++ b/en-us/docs/user/references/xml/dubbo-module.html
@@ -56,7 +56,7 @@ table tr:hover {
})
</script>
<h1>dubbo:module</h1>
-<p>Module configuration. The corresponding class <code>com.alibaba.dubbo.config.ModuleConfig</code></p>
+<p>Module configuration. The corresponding class <code>org.apache.dubbo.config.ModuleConfig</code></p>
<table>
<thead>
<tr>
diff --git a/en-us/docs/user/references/xml/dubbo-module.json b/en-us/docs/user/references/xml/dubbo-module.json
index e7236c6..11fd684 100644
--- a/en-us/docs/user/references/xml/dubbo-module.json
+++ b/en-us/docs/user/references/xml/dubbo-module.json
@@ -1,6 +1,6 @@
{
"filename": "dubbo-module.md",
- "__html": "<style>\ntable {\n width: 100%;\n max-width: 65em;\n border: 1px solid #dedede;\n margin: 15px auto;\n border-collapse: collapse;\n empty-cells: show;\n}\ntable th,\ntable td {\n height: 35px;\n border: 1px solid #dedede;\n padding: 0 10px;\n}\ntable th {\n font-weight: bold;\n text-align: center !important;\n background: rgba(158,188,226,0.2);\n white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n background: rgba(158,188,226,0.12);\n}\ntable td:nth-child [...]
+ "__html": "<style>\ntable {\n width: 100%;\n max-width: 65em;\n border: 1px solid #dedede;\n margin: 15px auto;\n border-collapse: collapse;\n empty-cells: show;\n}\ntable th,\ntable td {\n height: 35px;\n border: 1px solid #dedede;\n padding: 0 10px;\n}\ntable th {\n font-weight: bold;\n text-align: center !important;\n background: rgba(158,188,226,0.2);\n white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n background: rgba(158,188,226,0.12);\n}\ntable td:nth-child [...]
"link": "/en-us/docs/user/references/xml/dubbo-module.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/references/xml/dubbo-monitor.html b/en-us/docs/user/references/xml/dubbo-monitor.html
index 7e30630..e01fb00 100644
--- a/en-us/docs/user/references/xml/dubbo-monitor.html
+++ b/en-us/docs/user/references/xml/dubbo-monitor.html
@@ -56,7 +56,7 @@ table tr:hover {
})
</script>
<h1>dubbo:monitor</h1>
-<p>Monitor center configuration. The corresponding class: <code>com.alibaba.dubbo.config.MonitorConfig</code></p>
+<p>Monitor center configuration. The corresponding class: <code>org.apache.dubbo.config.MonitorConfig</code></p>
<table>
<thead>
<tr>
diff --git a/en-us/docs/user/references/xml/dubbo-monitor.json b/en-us/docs/user/references/xml/dubbo-monitor.json
index dc12d5a..296ccf7 100644
--- a/en-us/docs/user/references/xml/dubbo-monitor.json
+++ b/en-us/docs/user/references/xml/dubbo-monitor.json
@@ -1,6 +1,6 @@
{
"filename": "dubbo-monitor.md",
- "__html": "<style>\ntable {\n width: 100%;\n max-width: 65em;\n border: 1px solid #dedede;\n margin: 15px auto;\n border-collapse: collapse;\n empty-cells: show;\n}\ntable th,\ntable td {\n height: 35px;\n border: 1px solid #dedede;\n padding: 0 10px;\n}\ntable th {\n font-weight: bold;\n text-align: center !important;\n background: rgba(158,188,226,0.2);\n white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n background: rgba(158,188,226,0.12);\n}\ntable td:nth-child [...]
+ "__html": "<style>\ntable {\n width: 100%;\n max-width: 65em;\n border: 1px solid #dedede;\n margin: 15px auto;\n border-collapse: collapse;\n empty-cells: show;\n}\ntable th,\ntable td {\n height: 35px;\n border: 1px solid #dedede;\n padding: 0 10px;\n}\ntable th {\n font-weight: bold;\n text-align: center !important;\n background: rgba(158,188,226,0.2);\n white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n background: rgba(158,188,226,0.12);\n}\ntable td:nth-child [...]
"link": "/en-us/docs/user/references/xml/dubbo-monitor.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/references/xml/dubbo-protocol.html b/en-us/docs/user/references/xml/dubbo-protocol.html
index 2161a62..5885150 100644
--- a/en-us/docs/user/references/xml/dubbo-protocol.html
+++ b/en-us/docs/user/references/xml/dubbo-protocol.html
@@ -56,7 +56,7 @@ table tr:hover {
})
</script>
<h1>dubbo:protocol</h1>
-<p>Service provider protocol configuration. The corresponding class is <code>com.alibaba.dubbo.config.ProtocolConfig</code>. If you need to support multiple protocols, you could declare multiple <code><dubbo:protocol></code> tags, and specify the protocol via <code>protocol</code> property.</p>
+<p>Service provider protocol configuration. The corresponding class is <code>org.apache.dubbo.config.ProtocolConfig</code>. If you need to support multiple protocols, you could declare multiple <code><dubbo:protocol></code> tags, and specify the protocol via <code>protocol</code> property.</p>
<table>
<thead>
<tr>
diff --git a/en-us/docs/user/references/xml/dubbo-protocol.json b/en-us/docs/user/references/xml/dubbo-protocol.json
index 550ff7b..34d2147 100644
--- a/en-us/docs/user/references/xml/dubbo-protocol.json
+++ b/en-us/docs/user/references/xml/dubbo-protocol.json
@@ -1,6 +1,6 @@
{
"filename": "dubbo-protocol.md",
- "__html": "<style>\ntable {\n width: 100%;\n max-width: 65em;\n border: 1px solid #dedede;\n margin: 15px auto;\n border-collapse: collapse;\n empty-cells: show;\n}\ntable th,\ntable td {\n height: 35px;\n border: 1px solid #dedede;\n padding: 0 10px;\n}\ntable th {\n font-weight: bold;\n text-align: center !important;\n background: rgba(158,188,226,0.2);\n white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n background: rgba(158,188,226,0.12);\n}\ntable td:nth-child [...]
+ "__html": "<style>\ntable {\n width: 100%;\n max-width: 65em;\n border: 1px solid #dedede;\n margin: 15px auto;\n border-collapse: collapse;\n empty-cells: show;\n}\ntable th,\ntable td {\n height: 35px;\n border: 1px solid #dedede;\n padding: 0 10px;\n}\ntable th {\n font-weight: bold;\n text-align: center !important;\n background: rgba(158,188,226,0.2);\n white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n background: rgba(158,188,226,0.12);\n}\ntable td:nth-child [...]
"link": "/en-us/docs/user/references/xml/dubbo-protocol.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/references/xml/dubbo-provider.html b/en-us/docs/user/references/xml/dubbo-provider.html
index f8da9bd..6a4c710 100644
--- a/en-us/docs/user/references/xml/dubbo-provider.html
+++ b/en-us/docs/user/references/xml/dubbo-provider.html
@@ -56,7 +56,7 @@ table tr:hover {
})
</script>
<h1>dubbo:provider</h1>
-<p>The default configuration of service provider. The corresponding class is <code>com.alibaba.dubbo.config.ProviderConfig</code>. This tag provider default values for <code><dubbo:service></code> and <code><dubbo:protocol></code>.</p>
+<p>The default configuration of service provider. The corresponding class is <code>org.apache.dubbo.config.ProviderConfig</code>. This tag provider default values for <code><dubbo:service></code> and <code><dubbo:protocol></code>.</p>
<table>
<thead>
<tr>
diff --git a/en-us/docs/user/references/xml/dubbo-provider.json b/en-us/docs/user/references/xml/dubbo-provider.json
index 54a1904..7f65f25 100644
--- a/en-us/docs/user/references/xml/dubbo-provider.json
+++ b/en-us/docs/user/references/xml/dubbo-provider.json
@@ -1,6 +1,6 @@
{
"filename": "dubbo-provider.md",
- "__html": "<style>\ntable {\n width: 100%;\n max-width: 65em;\n border: 1px solid #dedede;\n margin: 15px auto;\n border-collapse: collapse;\n empty-cells: show;\n}\ntable th,\ntable td {\n height: 35px;\n border: 1px solid #dedede;\n padding: 0 10px;\n}\ntable th {\n font-weight: bold;\n text-align: center !important;\n background: rgba(158,188,226,0.2);\n white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n background: rgba(158,188,226,0.12);\n}\ntable td:nth-child [...]
+ "__html": "<style>\ntable {\n width: 100%;\n max-width: 65em;\n border: 1px solid #dedede;\n margin: 15px auto;\n border-collapse: collapse;\n empty-cells: show;\n}\ntable th,\ntable td {\n height: 35px;\n border: 1px solid #dedede;\n padding: 0 10px;\n}\ntable th {\n font-weight: bold;\n text-align: center !important;\n background: rgba(158,188,226,0.2);\n white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n background: rgba(158,188,226,0.12);\n}\ntable td:nth-child [...]
"link": "/en-us/docs/user/references/xml/dubbo-provider.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/references/xml/dubbo-reference.html b/en-us/docs/user/references/xml/dubbo-reference.html
index b0740aa..c253ef7 100644
--- a/en-us/docs/user/references/xml/dubbo-reference.html
+++ b/en-us/docs/user/references/xml/dubbo-reference.html
@@ -56,7 +56,7 @@ table tr:hover {
})
</script>
<h1>dubbo:reference</h1>
-<p>The configuration of service consumer. The corresponding class is<code>com.alibaba.dubbo.config.ReferenceConfig</code></p>
+<p>The configuration of service consumer. The corresponding class is<code>org.apache.dubbo.config.ReferenceConfig</code></p>
<table>
<thead>
<tr>
diff --git a/en-us/docs/user/references/xml/dubbo-reference.json b/en-us/docs/user/references/xml/dubbo-reference.json
index 5246d94..6e6f3b9 100644
--- a/en-us/docs/user/references/xml/dubbo-reference.json
+++ b/en-us/docs/user/references/xml/dubbo-reference.json
@@ -1,6 +1,6 @@
{
"filename": "dubbo-reference.md",
- "__html": "<style>\ntable {\n width: 100%;\n max-width: 65em;\n border: 1px solid #dedede;\n margin: 15px auto;\n border-collapse: collapse;\n empty-cells: show;\n}\ntable th,\ntable td {\n height: 35px;\n border: 1px solid #dedede;\n padding: 0 10px;\n}\ntable th {\n font-weight: bold;\n text-align: center !important;\n background: rgba(158,188,226,0.2);\n white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n background: rgba(158,188,226,0.12);\n}\ntable td:nth-child [...]
+ "__html": "<style>\ntable {\n width: 100%;\n max-width: 65em;\n border: 1px solid #dedede;\n margin: 15px auto;\n border-collapse: collapse;\n empty-cells: show;\n}\ntable th,\ntable td {\n height: 35px;\n border: 1px solid #dedede;\n padding: 0 10px;\n}\ntable th {\n font-weight: bold;\n text-align: center !important;\n background: rgba(158,188,226,0.2);\n white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n background: rgba(158,188,226,0.12);\n}\ntable td:nth-child [...]
"link": "/en-us/docs/user/references/xml/dubbo-reference.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/references/xml/dubbo-registry.html b/en-us/docs/user/references/xml/dubbo-registry.html
index b3f1195..62531db 100644
--- a/en-us/docs/user/references/xml/dubbo-registry.html
+++ b/en-us/docs/user/references/xml/dubbo-registry.html
@@ -56,7 +56,7 @@ table tr:hover {
})
</script>
<h1>dubbo:registry</h1>
-<p>The configuration of the registry center. The corresponding class is <code>com.alibaba.dubbo.config.RegistryConfig</code>. If you have multiple different registries, you can declare multiple <code><dubbo:registry></code> tags, and then reference specified registry with <code>registry</code> property in <code><dubbo:service></code> or <code><dubbo:reference></code> tag.</p>
+<p>The configuration of the registry center. The corresponding class is <code>org.apache.dubbo.config.RegistryConfig</code>. If you have multiple different registries, you can declare multiple <code><dubbo:registry></code> tags, and then reference specified registry with <code>registry</code> property in <code><dubbo:service></code> or <code><dubbo:reference></code> tag.</p>
<table>
<thead>
<tr>
diff --git a/en-us/docs/user/references/xml/dubbo-registry.json b/en-us/docs/user/references/xml/dubbo-registry.json
index d337332..9c6f39b 100644
--- a/en-us/docs/user/references/xml/dubbo-registry.json
+++ b/en-us/docs/user/references/xml/dubbo-registry.json
@@ -1,6 +1,6 @@
{
"filename": "dubbo-registry.md",
- "__html": "<style>\ntable {\n width: 100%;\n max-width: 65em;\n border: 1px solid #dedede;\n margin: 15px auto;\n border-collapse: collapse;\n empty-cells: show;\n}\ntable th,\ntable td {\n height: 35px;\n border: 1px solid #dedede;\n padding: 0 10px;\n}\ntable th {\n font-weight: bold;\n text-align: center !important;\n background: rgba(158,188,226,0.2);\n white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n background: rgba(158,188,226,0.12);\n}\ntable td:nth-child [...]
+ "__html": "<style>\ntable {\n width: 100%;\n max-width: 65em;\n border: 1px solid #dedede;\n margin: 15px auto;\n border-collapse: collapse;\n empty-cells: show;\n}\ntable th,\ntable td {\n height: 35px;\n border: 1px solid #dedede;\n padding: 0 10px;\n}\ntable th {\n font-weight: bold;\n text-align: center !important;\n background: rgba(158,188,226,0.2);\n white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n background: rgba(158,188,226,0.12);\n}\ntable td:nth-child [...]
"link": "/en-us/docs/user/references/xml/dubbo-registry.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/references/xml/dubbo-service.html b/en-us/docs/user/references/xml/dubbo-service.html
index bf18d32..b0973a4 100644
--- a/en-us/docs/user/references/xml/dubbo-service.html
+++ b/en-us/docs/user/references/xml/dubbo-service.html
@@ -56,7 +56,7 @@ table tr:hover {
})
</script>
<h1>dubbo:service</h1>
-<p>The configuration of the service provider. The corresponding class is <code>com.alibaba.dubbo.config.ServiceConfig</code>.</p>
+<p>The configuration of the service provider. The corresponding class is <code>org.apache.dubbo.config.ServiceConfig</code>.</p>
<table>
<thead>
<tr>
diff --git a/en-us/docs/user/references/xml/dubbo-service.json b/en-us/docs/user/references/xml/dubbo-service.json
index 1de2f30..f8b2e59 100644
--- a/en-us/docs/user/references/xml/dubbo-service.json
+++ b/en-us/docs/user/references/xml/dubbo-service.json
@@ -1,6 +1,6 @@
{
"filename": "dubbo-service.md",
- "__html": "<style>\ntable {\n width: 100%;\n max-width: 65em;\n border: 1px solid #dedede;\n margin: 15px auto;\n border-collapse: collapse;\n empty-cells: show;\n}\ntable th,\ntable td {\n height: 35px;\n border: 1px solid #dedede;\n padding: 0 10px;\n}\ntable th {\n font-weight: bold;\n text-align: center !important;\n background: rgba(158,188,226,0.2);\n white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n background: rgba(158,188,226,0.12);\n}\ntable td:nth-child [...]
+ "__html": "<style>\ntable {\n width: 100%;\n max-width: 65em;\n border: 1px solid #dedede;\n margin: 15px auto;\n border-collapse: collapse;\n empty-cells: show;\n}\ntable th,\ntable td {\n height: 35px;\n border: 1px solid #dedede;\n padding: 0 10px;\n}\ntable th {\n font-weight: bold;\n text-align: center !important;\n background: rgba(158,188,226,0.2);\n white-space: nowrap;\n}\ntable tbody tr:nth-child(2n) {\n background: rgba(158,188,226,0.12);\n}\ntable td:nth-child [...]
"link": "/en-us/docs/user/references/xml/dubbo-service.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/rest.html b/en-us/docs/user/rest.html
index fd8e6b1..c4cacd3 100644
--- a/en-us/docs/user/rest.html
+++ b/en-us/docs/user/rest.html
@@ -361,7 +361,7 @@ instead of deploying to a Java application server, we recommend the following co
<span class="hljs-tag"></<span class="hljs-name">context-param</span>></span>
<span class="hljs-tag"><<span class="hljs-name">listener</span>></span>
- <span class="hljs-tag"><<span class="hljs-name">listener-class</span>></span>com.alibaba.dubbo.remoting.http.servlet.BootstrapListener<span class="hljs-tag"></<span class="hljs-name">listener-class</span>></span>
+ <span class="hljs-tag"><<span class="hljs-name">listener-class</span>></span>org.apache.dubbo.remoting.http.servlet.BootstrapListener<span class="hljs-tag"></<span class="hljs-name">listener-class</span>></span>
<span class="hljs-tag"></<span class="hljs-name">listener</span>></span>
<span class="hljs-tag"><<span class="hljs-name">listener</span>></span>
@@ -370,7 +370,7 @@ instead of deploying to a Java application server, we recommend the following co
<span class="hljs-tag"><<span class="hljs-name">servlet</span>></span>
<span class="hljs-tag"><<span class="hljs-name">servlet-name</span>></span>dispatcher<span class="hljs-tag"></<span class="hljs-name">servlet-name</span>></span>
- <span class="hljs-tag"><<span class="hljs-name">servlet-class</span>></span>com.alibaba.dubbo.remoting.http.servlet.DispatcherServlet<span class="hljs-tag"></<span class="hljs-name">servlet-class</span>></span>
+ <span class="hljs-tag"><<span class="hljs-name">servlet-class</span>></span>org.apache.dubbo.remoting.http.servlet.DispatcherServlet<span class="hljs-tag"></<span class="hljs-name">servlet-class</span>></span>
<span class="hljs-tag"><<span class="hljs-name">load-on-startup</span>></span>1<span class="hljs-tag"></<span class="hljs-name">load-on-startup</span>></span>
<span class="hljs-tag"></<span class="hljs-name">servlet</span>></span>
@@ -594,10 +594,10 @@ However, dubbo/spring itself supports the use of annotation for configuration, s
<h3>Configuring HTTP log output</h3>
<p>Dubbo RESTful Remoting supports outputting the header and body in all HTTP requests/responses.</p>
<p>Add the following REST filter to the XML configuration:</p>
-<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"rest"</span> <span class="hljs-attr">port</span>=<span class="hljs-string">"8888"</span> <span class="hljs-attr">extension</span>=<span class="hljs-string">"com.alibaba.dubbo.rpc.protocol.rest.support.LoggingFilter"</span>/></span>
+<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"rest"</span> <span class="hljs-attr">port</span>=<span class="hljs-string">"8888"</span> <span class="hljs-attr">extension</span>=<span class="hljs-string">"org.apache.dubbo.rpc.protocol.rest.support.LoggingFilter"</span>/></span>
</code></pre>
-<p><strong>Then turn on at least INFO level log output for com.alibaba.dubbo.rpc.protocol.rest.support in the logging configuration</strong>,for example,in log4j.xml:</p>
-<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">logger</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"com.alibaba.dubbo.rpc.protocol.rest.support"</span>></span>
+<p><strong>Then turn on at least INFO level log output for org.apache.dubbo.rpc.protocol.rest.support in the logging configuration</strong>,for example,in log4j.xml:</p>
+<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">logger</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"org.apache.dubbo.rpc.protocol.rest.support"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">level</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"INFO"</span>/></span>
<span class="hljs-tag"><<span class="hljs-name">appender-ref</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"CONSOLE"</span>/></span>
<span class="hljs-tag"></<span class="hljs-name">logger</span>></span>
diff --git a/en-us/docs/user/rest.json b/en-us/docs/user/rest.json
index d6d7d33..b7dfd68 100644
--- a/en-us/docs/user/rest.json
+++ b/en-us/docs/user/rest.json
@@ -1,6 +1,6 @@
{
"filename": "rest.md",
- "__html": "<h1>Developing RESTful Remoting in Dubbo</h1>\n<p><strong>Original author: Li Shen</strong></p>\n<p><strong>Document copyright: <a href=\"HTTP://www.apache.org/licenses/LICENSE-2.0\">Apache 2.0license Signature - No interpretation</a></strong></p>\n<p>Working in progress ...</p>\n<blockquote>\n<p>This article is lengthy since REST involves many aspects. Besides, it refers to the document style of Spring and so on. Not only limited to usage of the framework but also strives t [...]
+ "__html": "<h1>Developing RESTful Remoting in Dubbo</h1>\n<p><strong>Original author: Li Shen</strong></p>\n<p><strong>Document copyright: <a href=\"HTTP://www.apache.org/licenses/LICENSE-2.0\">Apache 2.0license Signature - No interpretation</a></strong></p>\n<p>Working in progress ...</p>\n<blockquote>\n<p>This article is lengthy since REST involves many aspects. Besides, it refers to the document style of Spring and so on. Not only limited to usage of the framework but also strives t [...]
"link": "/en-us/docs/user/rest.html",
"meta": {}
}
\ No newline at end of file
diff --git a/en-us/docs/user/simple-monitor.html b/en-us/docs/user/simple-monitor.html
index 06a3919..5e8532d 100644
--- a/en-us/docs/user/simple-monitor.html
+++ b/en-us/docs/user/simple-monitor.html
@@ -36,9 +36,9 @@
<span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">port</span>=<span class="hljs-string">"7070"</span> /></span>
<span class="hljs-comment"><!-- configuration of certain exposed service --></span>
-<span class="hljs-tag"><<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"com.alibaba.dubbo.monitor.MonitorService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"monitorService"</span> /></span>
+<span class="hljs-tag"><<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.monitor.MonitorService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"monitorService"</span> /></span>
-<span class="hljs-tag"><<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"monitorService"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"com.alibaba.dubbo.monitor.simple.SimpleMonitorService"</span> /></span>
+<span class="hljs-tag"><<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"monitorService"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"org.apache.dubbo.monitor.simple.SimpleMonitorService"</span> /></span>
<span class="hljs-tag"></<span class="hljs-name">beans</span>></span>
</code></pre>
</li>
@@ -67,15 +67,15 @@
<span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">port</span>=<span class="hljs-string">"7070"</span> /></span>
<span class="hljs-comment"><!-- configuration of exposed service --></span>
-<span class="hljs-tag"><<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"com.alibaba.dubbo.monitor.MonitorService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"monitorService"</span> <span class="hljs-attr">registry</span>=<span class="hljs-string">"N/A"</span> /></span>
+<span class="hljs-tag"><<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">interface</span>=<span class="hljs-string">"org.apache.dubbo.monitor.MonitorService"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"monitorService"</span> <span class="hljs-attr">registry</span>=<span class="hljs-string">"N/A"</span> /></span>
-<span class="hljs-tag"><<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"monitorService"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"com.alibaba.dubbo.monitor.simple.SimpleMonitorService"</span> /></span>
+<span class="hljs-tag"><<span class="hljs-name">bean</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"monitorService"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"org.apache.dubbo.monitor.simple.SimpleMonitorService"</span> /></span>
<span class="hljs-tag"></<span class="hljs-name">beans</span>></span>
</code></pre>
</li>
<li>
<p>connected to the monitor service straightly</p>
-<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:monitor</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"dubbo://127.0.0.1:7070/com.alibaba.dubbo.monitor.MonitorService"</span> /></span>
+<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:monitor</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"dubbo://127.0.0.1:7070/org.apache.dubbo.monitor.MonitorService"</span> /></span>
</code></pre>
<p>or:</p>
<pre><code class="language-sh"><dubbo:monitor address=<span class="hljs-string">"127.0.0.1:7070"</span> />
diff --git a/en-us/docs/user/simple-monitor.json b/en-us/docs/user/simple-monitor.json
index 1727870..9d296a5 100644
--- a/en-us/docs/user/simple-monitor.json
+++ b/en-us/docs/user/simple-monitor.json
@@ -1,6 +1,6 @@
{
"filename": "simple-monitor.md",
- "__html": "<blockquote>\n<p><img src=\"sources/images/check.gif\" alt=\"warning\">Monitor service is a standard Dubbo service,can be exported to the registry,also can be connected straightly。</p>\n</blockquote>\n<blockquote>\n<p><img src=\"sources/images/check.gif\" alt=\"warning\">[Install the simple registry](admin-guide-install-manual#Install the simple registry)</p>\n</blockquote>\n<ol start=\"0\">\n<li>\n<p>export a simple monitor service to the registry: (If you use the installer [...]
+ "__html": "<blockquote>\n<p><img src=\"sources/images/check.gif\" alt=\"warning\">Monitor service is a standard Dubbo service,can be exported to the registry,also can be connected straightly。</p>\n</blockquote>\n<blockquote>\n<p><img src=\"sources/images/check.gif\" alt=\"warning\">[Install the simple registry](admin-guide-install-manual#Install the simple registry)</p>\n</blockquote>\n<ol start=\"0\">\n<li>\n<p>export a simple monitor service to the registry: (If you use the installer [...]
"link": "/en-us/docs/user/simple-monitor.html",
"meta": {}
}
\ No newline at end of file
diff --git a/md_json/docs.json b/md_json/docs.json
index ce952ea..ed7f67c 100644
--- a/md_json/docs.json
+++ b/md_json/docs.json
@@ -1218,6 +1218,78 @@
"meta": {}
},
{
+ "filename": "adaptive-extension.md",
+ "link": "/zh-cn/docs/source_code_guide/adaptive-extension.html",
+ "meta": {
+ "title": "SPI 自适应拓展",
+ "keywords": "Dubbo, SPI, Adaptive Extension",
+ "description": "本文介绍了自适应拓展的原理和实现细节"
+ }
+ },
+ {
+ "filename": "cluster.md",
+ "link": "/zh-cn/docs/source_code_guide/cluster.html",
+ "meta": {
+ "title": "集群",
+ "keywords": "Dubbo, Cluster",
+ "description": "本文介绍了集群的原理和实现细节"
+ }
+ },
+ {
+ "filename": "directory.md",
+ "link": "/zh-cn/docs/source_code_guide/directory.html",
+ "meta": {
+ "title": "服务目录",
+ "keywords": "Dubbo, Directory",
+ "description": "本文介绍了服务目录的原理和实现细节"
+ }
+ },
+ {
+ "filename": "dubbo-spi.md",
+ "link": "/zh-cn/docs/source_code_guide/dubbo-spi.html",
+ "meta": {
+ "title": "Dubbo SPI",
+ "keywords": "Dubbo, SPI",
+ "description": "本文介绍了 Dubbo SPI 的原理和实现细节"
+ }
+ },
+ {
+ "filename": "export-service.md",
+ "link": "/zh-cn/docs/source_code_guide/export-service.html",
+ "meta": {
+ "title": "服务导出",
+ "keywords": "Dubbo, service, export",
+ "description": "本文介绍了 Dubbo 服务导出的过程和实现细节"
+ }
+ },
+ {
+ "filename": "loadbalance.md",
+ "link": "/zh-cn/docs/source_code_guide/loadbalance.html",
+ "meta": {
+ "title": "负载均衡",
+ "keywords": "Dubbo, LoadBalance",
+ "description": "本文介绍了集群的原理和实现细节"
+ }
+ },
+ {
+ "filename": "refer-service.md",
+ "link": "/zh-cn/docs/source_code_guide/refer-service.html",
+ "meta": {
+ "title": "服务引用",
+ "keywords": "Dubbo, service, refer",
+ "description": "本文介绍了 Dubbo 服务引用的过程和实现细节"
+ }
+ },
+ {
+ "filename": "router.md",
+ "link": "/zh-cn/docs/source_code_guide/router.html",
+ "meta": {
+ "title": "服务路由",
+ "keywords": "Dubbo, Router",
+ "description": "本文介绍了服务\b路由的原理和实现细节"
+ }
+ },
+ {
"filename": "README.md",
"link": "/zh-cn/docs/user/README.html",
"meta": {}
diff --git a/zh-cn/docs/admin/install/consumer-demo.html b/zh-cn/docs/admin/install/consumer-demo.html
index 24ed3ab..500399b 100644
--- a/zh-cn/docs/admin/install/consumer-demo.html
+++ b/zh-cn/docs/admin/install/consumer-demo.html
@@ -16,7 +16,7 @@
<p>安装:</p>
<pre><code class="language-sh">git <span class="hljs-built_in">clone</span> https://github.com/apache/incubator-dubbo.git
<span class="hljs-built_in">cd</span> incubator-dubbo
-运行 dubbo-demo-consumer中的com.alibaba.dubbo.demo.consumer.Consumer
+运行 dubbo-demo-consumer中的org.apache.dubbo.demo.consumer.Consumer
请确保先启动Provider
如果使用Intellij Idea 请加上-Djava.net.preferIPv4Stack=<span class="hljs-literal">true</span>
</code></pre>
diff --git a/zh-cn/docs/admin/install/consumer-demo.json b/zh-cn/docs/admin/install/consumer-demo.json
index 7f5844f..a502a5f 100644
--- a/zh-cn/docs/admin/install/consumer-demo.json
+++ b/zh-cn/docs/admin/install/consumer-demo.json
@@ -1,6 +1,6 @@
{
"filename": "consumer-demo.md",
- "__html": "<h1>示例消费者安装</h1>\n<p>安装:</p>\n<pre><code class=\"language-sh\">git <span class=\"hljs-built_in\">clone</span> https://github.com/apache/incubator-dubbo.git\n<span class=\"hljs-built_in\">cd</span> incubator-dubbo\n运行 dubbo-demo-consumer中的com.alibaba.dubbo.demo.consumer.Consumer\n请确保先启动Provider\n如果使用Intellij Idea 请加上-Djava.net.preferIPv4Stack=<span class=\"hljs-literal\">true</span>\n</code></pre>\n<p>配置:</p>\n<pre><code class=\"language-sh\">resource/META-INFO.spring/dubbo-d [...]
+ "__html": "<h1>示例消费者安装</h1>\n<p>安装:</p>\n<pre><code class=\"language-sh\">git <span class=\"hljs-built_in\">clone</span> https://github.com/apache/incubator-dubbo.git\n<span class=\"hljs-built_in\">cd</span> incubator-dubbo\n运行 dubbo-demo-consumer中的org.apache.dubbo.demo.consumer.Consumer\n请确保先启动Provider\n如果使用Intellij Idea 请加上-Djava.net.preferIPv4Stack=<span class=\"hljs-literal\">true</span>\n</code></pre>\n<p>配置:</p>\n<pre><code class=\"language-sh\">resource/META-INFO.spring/dubbo-de [...]
"link": "/zh-cn/docs/admin/install/consumer-demo.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/admin/install/provider-demo.html b/zh-cn/docs/admin/install/provider-demo.html
index c8a434f..2ccfd55 100644
--- a/zh-cn/docs/admin/install/provider-demo.html
+++ b/zh-cn/docs/admin/install/provider-demo.html
@@ -16,7 +16,7 @@
<p>安装:</p>
<pre><code class="language-sh">git <span class="hljs-built_in">clone</span> https://github.com/apache/incubator-dubbo.git
<span class="hljs-built_in">cd</span> incubator-dubbo
-运行 dubbo-demo-provider中的com.alibaba.dubbo.demo.provider.Provider
+运行 dubbo-demo-provider中的org.apache.dubbo.demo.provider.Provider
如果使用Intellij Idea 请加上-Djava.net.preferIPv4Stack=<span class="hljs-literal">true</span>
</code></pre>
<p>配置:</p>
diff --git a/zh-cn/docs/admin/install/provider-demo.json b/zh-cn/docs/admin/install/provider-demo.json
index 7dc67d3..f469609 100644
--- a/zh-cn/docs/admin/install/provider-demo.json
+++ b/zh-cn/docs/admin/install/provider-demo.json
@@ -1,6 +1,6 @@
{
"filename": "provider-demo.md",
- "__html": "<h1>示例提供者安装</h1>\n<p>安装:</p>\n<pre><code class=\"language-sh\">git <span class=\"hljs-built_in\">clone</span> https://github.com/apache/incubator-dubbo.git\n<span class=\"hljs-built_in\">cd</span> incubator-dubbo\n运行 dubbo-demo-provider中的com.alibaba.dubbo.demo.provider.Provider\n如果使用Intellij Idea 请加上-Djava.net.preferIPv4Stack=<span class=\"hljs-literal\">true</span>\n</code></pre>\n<p>配置:</p>\n<pre><code class=\"language-sh\">resource/META-INFO.spring/dubbo-demo-provider.xml [...]
+ "__html": "<h1>示例提供者安装</h1>\n<p>安装:</p>\n<pre><code class=\"language-sh\">git <span class=\"hljs-built_in\">clone</span> https://github.com/apache/incubator-dubbo.git\n<span class=\"hljs-built_in\">cd</span> incubator-dubbo\n运行 dubbo-demo-provider中的org.apache.dubbo.demo.provider.Provider\n如果使用Intellij Idea 请加上-Djava.net.preferIPv4Stack=<span class=\"hljs-literal\">true</span>\n</code></pre>\n<p>配置:</p>\n<pre><code class=\"language-sh\">resource/META-INFO.spring/dubbo-demo-provider.xml\ [...]
"link": "/zh-cn/docs/admin/install/provider-demo.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/admin/ops/pinpoint.html b/zh-cn/docs/admin/ops/pinpoint.html
index 484d47d..91cee2b 100644
--- a/zh-cn/docs/admin/ops/pinpoint.html
+++ b/zh-cn/docs/admin/ops/pinpoint.html
@@ -154,7 +154,7 @@ public interface HelloService {
</ol>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.example.demoprovider.provider;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.config.annotation.Service;
+<span class="hljs-keyword">import</span> org.apache.dubbo.config.annotation.Service;
<span class="hljs-keyword">import</span> com.example.demoapi.HelloService;
<span class="hljs-meta">@Service</span>(version = <span class="hljs-string">"${demo.service.version}"</span>,
@@ -299,7 +299,7 @@ public interface HelloService {
</ol>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.example.democonsumer.controller;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.config.annotation.Reference;
+<span class="hljs-keyword">import</span> org.apache.dubbo.config.annotation.Reference;
<span class="hljs-keyword">import</span> com.example.demoapi.HelloService;
<span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.RequestMapping;
<span class="hljs-keyword">import</span> org.springframework.web.bind.annotation.RequestParam;
diff --git a/zh-cn/docs/admin/ops/pinpoint.json b/zh-cn/docs/admin/ops/pinpoint.json
index aa9cb94..f61976f 100644
--- a/zh-cn/docs/admin/ops/pinpoint.json
+++ b/zh-cn/docs/admin/ops/pinpoint.json
@@ -1,6 +1,6 @@
{
"filename": "pinpoint.md",
- "__html": "<h1>使用Pinpoint做分布式跟踪</h1>\n<p>在使用Dubbo进行服务化或者整合应用后,假设某个服务后台日志显示有异常,这个服务又被多个应用调用的情况下,我们通常很难判断是哪个应用调用的,问题的起因是什么,因此我们需要一套分布式跟踪系统来快速定位问题,Pinpoint可以帮助我们快速定位问题(当然,解决方案也不止这一种)。</p>\n<h2>什么是Pinpoint(摘自<a href=\"https://skyao.gitbooks.io/learning-pinpoint/\">Pinpoint学习笔记</a>)</h2>\n<p><a href=\"https://github.com/naver/pinpoint\">Pinpoint</a>是一个开源的 APM (Application Performance Management/应用性能管理)工具,用于基于java的大规模分布式系统。\n仿照Google Dapper,Pinpoint通过跟踪分布式应用之间的调用来提供解决方案,以帮助分析系统的总体结构和内部模块之间如何 [...]
+ "__html": "<h1>使用Pinpoint做分布式跟踪</h1>\n<p>在使用Dubbo进行服务化或者整合应用后,假设某个服务后台日志显示有异常,这个服务又被多个应用调用的情况下,我们通常很难判断是哪个应用调用的,问题的起因是什么,因此我们需要一套分布式跟踪系统来快速定位问题,Pinpoint可以帮助我们快速定位问题(当然,解决方案也不止这一种)。</p>\n<h2>什么是Pinpoint(摘自<a href=\"https://skyao.gitbooks.io/learning-pinpoint/\">Pinpoint学习笔记</a>)</h2>\n<p><a href=\"https://github.com/naver/pinpoint\">Pinpoint</a>是一个开源的 APM (Application Performance Management/应用性能管理)工具,用于基于java的大规模分布式系统。\n仿照Google Dapper,Pinpoint通过跟踪分布式应用之间的调用来提供解决方案,以帮助分析系统的总体结构和内部模块之间如何 [...]
"link": "/zh-cn/docs/admin/ops/pinpoint.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/SPI.html b/zh-cn/docs/dev/SPI.html
index 7fc63ab..3062be9 100644
--- a/zh-cn/docs/dev/SPI.html
+++ b/zh-cn/docs/dev/SPI.html
@@ -25,13 +25,13 @@
<h3>约定:</h3>
<p>在扩展类的 jar 包内 <sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>,放置扩展点配置文件 <code>META-INF/dubbo/接口全限定名</code>,内容为:<code>配置名=扩展实现类全限定名</code>,多个实现类用换行符分隔。</p>
<h3>示例:</h3>
-<p>以扩展 Dubbo 的协议为例,在协议的实现 jar 包内放置文本文件:<code>META-INF/dubbo/com.alibaba.dubbo.rpc.Protocol</code>,内容为:</p>
+<p>以扩展 Dubbo 的协议为例,在协议的实现 jar 包内放置文本文件:<code>META-INF/dubbo/org.apache.dubbo.rpc.Protocol</code>,内容为:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.alibaba.xxx.XxxProtocol</span>
</code></pre>
<p>实现类内容 <sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup>:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.alibaba.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Protocol;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Protocol;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxProtocol</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Protocol</span> </span>{
<span class="hljs-comment">// ...</span>
@@ -47,7 +47,7 @@
<p>Wrapper类内容:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.alibaba.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Protocol;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Protocol;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxProtocolWrapper</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Protocol</span> </span>{
Protocol impl;
@@ -148,8 +148,8 @@ Wheel wheel = wheelMaker.makeWheel(url);
<p>对于 bind() 方法,Adaptive 实现先查找 <code>server</code> key,如果该 Key 没有值则找 <code>transport</code> key 值,来决定代理到哪个实际扩展点。</p>
<h3>扩展点自动激活</h3>
<p>对于集合类扩展点,比如:<code>Filter</code>, <code>InvokerListener</code>, <code>ExportListener</code>, <code>TelnetHandler</code>, <code>StatusChecker</code> 等,可以同时加载多个实现,此时,可以用自动激活来简化配置,如:</p>
-<pre><code class="language-java"><span class="hljs-keyword">import</span> com.alibaba.dubbo.common.extension.Activate;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Filter;
+<pre><code class="language-java"><span class="hljs-keyword">import</span> org.apache.dubbo.common.extension.Activate;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Filter;
<span class="hljs-meta">@Activate</span> <span class="hljs-comment">// 无条件自动激活</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxFilter</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Filter</span> </span>{
@@ -157,8 +157,8 @@ Wheel wheel = wheelMaker.makeWheel(url);
}
</code></pre>
<p>或:</p>
-<pre><code class="language-java"><span class="hljs-keyword">import</span> com.alibaba.dubbo.common.extension.Activate;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Filter;
+<pre><code class="language-java"><span class="hljs-keyword">import</span> org.apache.dubbo.common.extension.Activate;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Filter;
<span class="hljs-meta">@Activate</span>(<span class="hljs-string">"xxx"</span>) <span class="hljs-comment">// 当配置了xxx参数,并且参数为有效值时激活,比如配了cache="lru",自动激活CacheFilter。</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxFilter</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Filter</span> </span>{
@@ -166,8 +166,8 @@ Wheel wheel = wheelMaker.makeWheel(url);
}
</code></pre>
<p>或:</p>
-<pre><code class="language-java"><span class="hljs-keyword">import</span> com.alibaba.dubbo.common.extension.Activate;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Filter;
+<pre><code class="language-java"><span class="hljs-keyword">import</span> org.apache.dubbo.common.extension.Activate;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Filter;
<span class="hljs-meta">@Activate</span>(group = <span class="hljs-string">"provider"</span>, value = <span class="hljs-string">"xxx"</span>) <span class="hljs-comment">// 只对提供方激活,group可选"provider"或"consumer"</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxFilter</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Filter</span> </span>{
diff --git a/zh-cn/docs/dev/SPI.json b/zh-cn/docs/dev/SPI.json
index b514694..c032038 100644
--- a/zh-cn/docs/dev/SPI.json
+++ b/zh-cn/docs/dev/SPI.json
@@ -1,6 +1,6 @@
{
"filename": "SPI.md",
- "__html": "<h1>扩展点加载</h1>\n<h2>扩展点配置</h2>\n<h3>来源:</h3>\n<p>Dubbo 的扩展点加载从 JDK 标准的 SPI (Service Provider Interface) 扩展点发现机制加强而来。</p>\n<p>Dubbo 改进了 JDK 标准的 SPI 的以下问题:</p>\n<ul>\n<li>JDK 标准的 SPI 会一次性实例化扩展点所有实现,如果有扩展实现初始化很耗时,但如果没用上也加载,会很浪费资源。</li>\n<li>如果扩展点加载失败,连扩展点的名称都拿不到了。比如:JDK 标准的 ScriptEngine,通过 <code>getName()</code> 获取脚本类型的名称,但如果 RubyScriptEngine 因为所依赖的 jruby.jar 不存在,导致 RubyScriptEngine 类加载失败,这个失败原因被吃掉了,和 ruby 对应不起来,当用户执行 ruby 脚本时,会报不支持 ruby,而不是真正失败的原因。</li>\n<li>增加了对扩展点 IoC 和 AOP [...]
+ "__html": "<h1>扩展点加载</h1>\n<h2>扩展点配置</h2>\n<h3>来源:</h3>\n<p>Dubbo 的扩展点加载从 JDK 标准的 SPI (Service Provider Interface) 扩展点发现机制加强而来。</p>\n<p>Dubbo 改进了 JDK 标准的 SPI 的以下问题:</p>\n<ul>\n<li>JDK 标准的 SPI 会一次性实例化扩展点所有实现,如果有扩展实现初始化很耗时,但如果没用上也加载,会很浪费资源。</li>\n<li>如果扩展点加载失败,连扩展点的名称都拿不到了。比如:JDK 标准的 ScriptEngine,通过 <code>getName()</code> 获取脚本类型的名称,但如果 RubyScriptEngine 因为所依赖的 jruby.jar 不存在,导致 RubyScriptEngine 类加载失败,这个失败原因被吃掉了,和 ruby 对应不起来,当用户执行 ruby 脚本时,会报不支持 ruby,而不是真正失败的原因。</li>\n<li>增加了对扩展点 IoC 和 AOP [...]
"link": "/zh-cn/docs/dev/SPI.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/code-smell.html b/zh-cn/docs/dev/code-smell.html
index 550b5b0..ca57d7d 100644
--- a/zh-cn/docs/dev/code-smell.html
+++ b/zh-cn/docs/dev/code-smell.html
@@ -24,11 +24,11 @@
</code></pre>
<h3>2. 通过注册中心暴露服务</h3>
<p>向注册中心暴露服务:</p>
-<pre><code>EXPORT(registry://registry-address/com.alibaba.dubbo.registry.RegistrySerevice?registry=dubbo&export=ENCODE(dubbo://provider-address/com.xxx.XxxService?version=1.0.0))
+<pre><code>EXPORT(registry://registry-address/org.apache.dubbo.registry.RegistrySerevice?registry=dubbo&export=ENCODE(dubbo://provider-address/com.xxx.XxxService?version=1.0.0))
</code></pre>
<p>获取注册中心:</p>
<pre><code>url.setProtocol(url.getParameter("registry", "dubbo"))
-GETREGISTRY(dubbo://registry-address/com.alibaba.dubbo.registry.RegistrySerevice)
+GETREGISTRY(dubbo://registry-address/org.apache.dubbo.registry.RegistrySerevice)
</code></pre>
<p>注册服务地址:</p>
<pre><code>url.getParameterAndDecoded("export"))
@@ -36,11 +36,11 @@ REGISTER(dubbo://provider-address/com.xxx.XxxService?version=1.0.0)
</code></pre>
<h3>3. 通过注册中心引用服务</h3>
<p>从注册中心订阅服务:</p>
-<pre><code>REFER(registry://registry-address/com.alibaba.dubbo.registry.RegistrySerevice?registry=dubbo&refer=ENCODE(version=1.0.0))
+<pre><code>REFER(registry://registry-address/org.apache.dubbo.registry.RegistrySerevice?registry=dubbo&refer=ENCODE(version=1.0.0))
</code></pre>
<p>获取注册中心:</p>
<pre><code>url.setProtocol(url.getParameter("registry", "dubbo"))
-GETREGISTRY(dubbo://registry-address/com.alibaba.dubbo.registry.RegistrySerevice)
+GETREGISTRY(dubbo://registry-address/org.apache.dubbo.registry.RegistrySerevice)
</code></pre>
<p>订阅服务地址:</p>
<pre><code>url.addParameters(url.getParameterAndDecoded("refer"))
@@ -111,7 +111,7 @@ public class <扩展点接口名>$Adpative implements <扩展点接口&
}
</code></pre>
<p><code>@Adaptive</code> 注解使用如下:</p>
-<p>如果 URL 这些 Key 都没有 Value,使用缺省的扩展(在接口的 Default 中设定的值)。比如,String[] {"key1", "key2"},表示先在 URL 上找 key1 的 Value 作为要 Adapt 成的 Extension 名;key1 没有 Value,则使用 key2 的 Value 作为要 Adapt 成的 Extension 名。 key2 没有 Value,使用缺省的扩展。如果没有设定缺省扩展,则方法调用会抛出 IllegalStateException。如果不设置则缺省使用 Extension 接口类名的点分隔小写字串。即对于 Extension 接口 <code>com.alibaba.dubbo.xxx.YyyInvokerWrapper</code> 的缺省值为 <code>new String[] {"yyy.invoker.wrapper"}</code></p>
+<p>如果 URL 这些 Key 都没有 Value,使用缺省的扩展(在接口的 Default 中设定的值)。比如,String[] {"key1", "key2"},表示先在 URL 上找 key1 的 Value 作为要 Adapt 成的 Extension 名;key1 没有 Value,则使用 key2 的 Value 作为要 Adapt 成的 Extension 名。 key2 没有 Value,使用缺省的扩展。如果没有设定缺省扩展,则方法调用会抛出 IllegalStateException。如果不设置则缺省使用 Extension 接口类名的点分隔小写字串。即对于 Extension 接口 <code>org.apache.dubbo.xxx.YyyInvokerWrapper</code> 的缺省值为 <code>new String[] {"yyy.invoker.wrapper"}</code></p>
<h2>Callback 功能</h2>
<h3>1. 参数回调</h3>
<p>主要原理: 在一个 consumer->provider 的长连接上,自动在 Consumer 端暴露一个服务(实现方法参数上声明的接口A),provider 端便可反向调用到 consumer 端的接口实例。</p>
diff --git a/zh-cn/docs/dev/code-smell.json b/zh-cn/docs/dev/code-smell.json
index f1654b1..6ef3a87 100644
--- a/zh-cn/docs/dev/code-smell.json
+++ b/zh-cn/docs/dev/code-smell.json
@@ -1,6 +1,6 @@
{
"filename": "code-smell.md",
- "__html": "<h1>坏味道</h1>\n<p>这里记录的是 Dubbo 设计或实现不优雅的地方。</p>\n<h2>URL 转换</h2>\n<h3>1. 点对点暴露和引用服务</h3>\n<p>直接暴露服务:</p>\n<pre><code>EXPORT(dubbo://provider-address/com.xxx.XxxService?version=1.0.0")\n</code></pre>\n<p>点对点直连服务:</p>\n<pre><code>REFER(dubbo://provider-address/com.xxx.XxxService?version=1.0.0)\n</code></pre>\n<h3>2. 通过注册中心暴露服务</h3>\n<p>向注册中心暴露服务:</p>\n<pre><code>EXPORT(registry://registry-address/com.alibaba.dubbo.registry.RegistrySerevice?registry=dubbo&export=ENCODE( [...]
+ "__html": "<h1>坏味道</h1>\n<p>这里记录的是 Dubbo 设计或实现不优雅的地方。</p>\n<h2>URL 转换</h2>\n<h3>1. 点对点暴露和引用服务</h3>\n<p>直接暴露服务:</p>\n<pre><code>EXPORT(dubbo://provider-address/com.xxx.XxxService?version=1.0.0")\n</code></pre>\n<p>点对点直连服务:</p>\n<pre><code>REFER(dubbo://provider-address/com.xxx.XxxService?version=1.0.0)\n</code></pre>\n<h3>2. 通过注册中心暴露服务</h3>\n<p>向注册中心暴露服务:</p>\n<pre><code>EXPORT(registry://registry-address/org.apache.dubbo.registry.RegistrySerevice?registry=dubbo&export=ENCODE(d [...]
"link": "/zh-cn/docs/dev/code-smell.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/implementation.html b/zh-cn/docs/dev/implementation.html
index a7c14a1..143b201 100644
--- a/zh-cn/docs/dev/implementation.html
+++ b/zh-cn/docs/dev/implementation.html
@@ -25,7 +25,7 @@
<code>dubbo://service-host/com.foo.FooService?version=1.0.0</code>。</p>
<p>基于扩展点自适应机制,通过 URL 的 <code>dubbo://</code> 协议头识别,直接调用 <code>DubboProtocol</code>的 <code>export()</code> 方法,打开服务端口。</p>
<h4>2. 向注册中心暴露服务:</h4>
-<p>在有注册中心,需要注册提供者地址的情况下 <sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup>,<code>ServiceConfig</code> 解析出的 URL 的格式为: <code>registry://registry-host/com.alibaba.dubbo.registry.RegistryService?export=URL.encode("dubbo://service-host/com.foo.FooService?version=1.0.0")</code>,</p>
+<p>在有注册中心,需要注册提供者地址的情况下 <sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup>,<code>ServiceConfig</code> 解析出的 URL 的格式为: <code>registry://registry-host/org.apache.dubbo.registry.RegistryService?export=URL.encode("dubbo://service-host/com.foo.FooService?version=1.0.0")</code>,</p>
<p>基于扩展点自适应机制,通过 URL 的 <code>registry://</code> 协议头识别,就会调用 <code>RegistryProtocol</code> 的 <code>export()</code> 方法,将 <code>export</code> 参数中的提供者 URL,先注册到注册中心。</p>
<p>再重新传给 <code>Protocol</code> 扩展点进行暴露: <code>dubbo://service-host/com.foo.FooService?version=1.0.0</code>,然后基于扩展点自适应机制,通过提供者 URL 的 <code>dubbo://</code> 协议头识别,就会调用 <code>DubboProtocol</code> 的 <code>export()</code> 方法,打开服务端口。</p>
<h3>引用服务</h3>
@@ -34,7 +34,7 @@
<p>基于扩展点自适应机制,通过 URL 的 <code>dubbo://</code> 协议头识别,直接调用 <code>DubboProtocol</code> 的 <code>refer()</code> 方法,返回提供者引用。</p>
<h4>2. 从注册中心发现引用服务:</h4>
<p>在有注册中心,通过注册中心发现提供者地址的情况下 <sup class="footnote-ref"><a href="#fn4" id="fnref4">[4]</a></sup>,<code>ReferenceConfig</code> 解析出的 URL 的格式为:
-<code>registry://registry-host/com.alibaba.dubbo.registry.RegistryService?refer=URL.encode("consumer://consumer-host/com.foo.FooService?version=1.0.0")</code>。</p>
+<code>registry://registry-host/org.apache.dubbo.registry.RegistryService?refer=URL.encode("consumer://consumer-host/com.foo.FooService?version=1.0.0")</code>。</p>
<p>基于扩展点自适应机制,通过 URL 的 <code>registry://</code> 协议头识别,就会调用 <code>RegistryProtocol</code> 的 <code>refer()</code> 方法,基于 <code>refer</code> 参数中的条件,查询提供者 URL,如:
<code>dubbo://service-host/com.foo.FooService?version=1.0.0</code>。</p>
<p>基于扩展点自适应机制,通过提供者 URL 的 <code>dubbo://</code> 协议头识别,就会调用 <code>DubboProtocol</code> 的 <code>refer()</code> 方法,得到提供者引用。</p>
diff --git a/zh-cn/docs/dev/implementation.json b/zh-cn/docs/dev/implementation.json
index 959411d..76e4aab 100644
--- a/zh-cn/docs/dev/implementation.json
+++ b/zh-cn/docs/dev/implementation.json
@@ -1,6 +1,6 @@
{
"filename": "implementation.md",
- "__html": "<h1>实现细节</h1>\n<h2>初始化过程细节</h2>\n<h3>解析服务</h3>\n<p>基于 dubbo.jar 内的 <code>META-INF/spring.handlers</code> 配置,Spring 在遇到 dubbo 名称空间时,会回调 <code>DubboNamespaceHandler</code>。</p>\n<p>所有 dubbo 的标签,都统一用 <code>DubboBeanDefinitionParser</code> 进行解析,基于一对一属性映射,将 XML 标签解析为 Bean 对象。</p>\n<p>在 <code>ServiceConfig.export()</code> 或 <code>ReferenceConfig.get()</code> 初始化时,将 Bean 对象转换 URL 格式,所有 Bean 属性转成 URL 的参数。</p>\n<p>然后将 URL 传给 <a href=\"./impls/protocol.md\">协议扩展点</a>,基于扩展点的 <a href=\" [...]
+ "__html": "<h1>实现细节</h1>\n<h2>初始化过程细节</h2>\n<h3>解析服务</h3>\n<p>基于 dubbo.jar 内的 <code>META-INF/spring.handlers</code> 配置,Spring 在遇到 dubbo 名称空间时,会回调 <code>DubboNamespaceHandler</code>。</p>\n<p>所有 dubbo 的标签,都统一用 <code>DubboBeanDefinitionParser</code> 进行解析,基于一对一属性映射,将 XML 标签解析为 Bean 对象。</p>\n<p>在 <code>ServiceConfig.export()</code> 或 <code>ReferenceConfig.get()</code> 初始化时,将 Bean 对象转换 URL 格式,所有 Bean 属性转成 URL 的参数。</p>\n<p>然后将 URL 传给 <a href=\"./impls/protocol.md\">协议扩展点</a>,基于扩展点的 <a href=\" [...]
"link": "/zh-cn/docs/dev/implementation.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/cache.html b/zh-cn/docs/dev/impls/cache.html
index 4072d12..4bfb5ab 100644
--- a/zh-cn/docs/dev/impls/cache.html
+++ b/zh-cn/docs/dev/impls/cache.html
@@ -16,7 +16,7 @@
<h2>扩展说明</h2>
<p>用请求参数作为 key,缓存返回结果。</p>
<h2>扩展接口</h2>
-<p><code>com.alibaba.dubbo.cache.CacheFactory</code></p>
+<p><code>org.apache.dubbo.cache.CacheFactory</code></p>
<h2>扩展配置</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">cache</span>=<span class="hljs-string">"lru"</span> /></span>
<span class="hljs-comment"><!-- 方法级缓存 --></span>
@@ -26,9 +26,9 @@
</code></pre>
<h2>已知扩展</h2>
<ul>
-<li><code>com.alibaba.dubbo.cache.support.lru.LruCacheFactory</code></li>
-<li><code>com.alibaba.dubbo.cache.support.threadlocal.ThreadLocalCacheFactory</code></li>
-<li><code>com.alibaba.dubbo.cache.support.jcache.JCacheFactory</code></li>
+<li><code>org.apache.dubbo.cache.support.lru.LruCacheFactory</code></li>
+<li><code>org.apache.dubbo.cache.support.threadlocal.ThreadLocalCacheFactory</code></li>
+<li><code>org.apache.dubbo.cache.support.jcache.JCacheFactory</code></li>
</ul>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
@@ -41,12 +41,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.cache.CacheFactory (纯文本文件,内容为:xxx=com.xxx.XxxCacheFactory)
+ |-org.apache.dubbo.cache.CacheFactory (纯文本文件,内容为:xxx=com.xxx.XxxCacheFactory)
</code></pre>
<p>XxxCacheFactory.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.cache.CacheFactory;
+<span class="hljs-keyword">import</span> org.apache.dubbo.cache.CacheFactory;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxCacheFactory</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">CacheFactory</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Cache <span class="hljs-title">getCache</span><span class="hljs-params">(URL url, String name)</span> </span>{
@@ -57,7 +57,7 @@
<p>XxxCacheFactory.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.cache.Cache;
+<span class="hljs-keyword">import</span> org.apache.dubbo.cache.Cache;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxCache</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Cache</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Cache</span><span class="hljs-params">(URL url, String name)</span> </span>{
@@ -71,7 +71,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.cache.CacheFactory:</p>
+<p>META-INF/dubbo/org.apache.dubbo.cache.CacheFactory:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxCacheFactory</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/cache.json b/zh-cn/docs/dev/impls/cache.json
index ae5ce01..0026c99 100644
--- a/zh-cn/docs/dev/impls/cache.json
+++ b/zh-cn/docs/dev/impls/cache.json
@@ -1,6 +1,6 @@
{
"filename": "cache.md",
- "__html": "<h1>缓存扩展</h1>\n<h2>扩展说明</h2>\n<p>用请求参数作为 key,缓存返回结果。</p>\n<h2>扩展接口</h2>\n<p><code>com.alibaba.dubbo.cache.CacheFactory</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:service</span> <span class=\"hljs-attr\">cache</span>=<span class=\"hljs-string\">\"lru\"</span> /></span>\n<span class=\"hljs-comment\"><!-- 方法级缓存 --></span>\n<span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:service< [...]
+ "__html": "<h1>缓存扩展</h1>\n<h2>扩展说明</h2>\n<p>用请求参数作为 key,缓存返回结果。</p>\n<h2>扩展接口</h2>\n<p><code>org.apache.dubbo.cache.CacheFactory</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:service</span> <span class=\"hljs-attr\">cache</span>=<span class=\"hljs-string\">\"lru\"</span> /></span>\n<span class=\"hljs-comment\"><!-- 方法级缓存 --></span>\n<span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:service</ [...]
"link": "/zh-cn/docs/dev/impls/cache.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/cluster.html b/zh-cn/docs/dev/impls/cluster.html
index 6ddd70f..94f4418 100644
--- a/zh-cn/docs/dev/impls/cluster.html
+++ b/zh-cn/docs/dev/impls/cluster.html
@@ -16,7 +16,7 @@
<h2>扩展说明</h2>
<p>当有多个服务提供方时,将多个服务提供方组织成一个集群,并伪装成一个提供方。</p>
<h2>扩展接口</h2>
-<p><code>com.alibaba.dubbo.rpc.cluster.Cluster</code></p>
+<p><code>org.apache.dubbo.rpc.cluster.Cluster</code></p>
<h2>扩展配置</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">cluster</span>=<span class="hljs-string">"xxx"</span> /></span>
<span class="hljs-comment"><!-- 缺省值配置,如果<dubbo:protocol>没有配置cluster时,使用此配置 --></span>
@@ -24,12 +24,12 @@
</code></pre>
<h2>已知扩展</h2>
<ul>
-<li><code>com.alibaba.dubbo.rpc.cluster.support.FailoverCluster</code></li>
-<li><code>com.alibaba.dubbo.rpc.cluster.support.FailfastCluster</code></li>
-<li><code>com.alibaba.dubbo.rpc.cluster.support.FailsafeCluster</code></li>
-<li><code>com.alibaba.dubbo.rpc.cluster.support.FailbackCluster</code></li>
-<li><code>com.alibaba.dubbo.rpc.cluster.support.ForkingCluster</code></li>
-<li><code>com.alibaba.dubbo.rpc.cluster.support.AvailableCluster</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.support.FailoverCluster</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.support.FailfastCluster</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.support.FailsafeCluster</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.support.FailbackCluster</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.support.ForkingCluster</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.support.AvailableCluster</code></li>
</ul>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
@@ -42,19 +42,19 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.rpc.cluster.Cluster (纯文本文件,内容为:xxx=com.xxx.XxxCluster)
+ |-org.apache.dubbo.rpc.cluster.Cluster (纯文本文件,内容为:xxx=com.xxx.XxxCluster)
</code></pre>
<p>XxxCluster.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.cluster.Cluster;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.cluster.Directory;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.cluster.LoadBalance;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Invoker;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Invocation;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Result;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.RpcException;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.cluster.Cluster;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.cluster.Directory;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.cluster.LoadBalance;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Invoker;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Invocation;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Result;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.RpcException;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxCluster</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Cluster</span> </span>{
<span class="hljs-keyword">public</span> <T> <span class="hljs-function">Invoker<T> <span class="hljs-title">merge</span><span class="hljs-params">(Directory<T> directory)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
@@ -66,7 +66,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.rpc.cluster.Cluster:</p>
+<p>META-INF/dubbo/org.apache.dubbo.rpc.cluster.Cluster:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxCluster</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/cluster.json b/zh-cn/docs/dev/impls/cluster.json
index f17b55f..5829db0 100644
--- a/zh-cn/docs/dev/impls/cluster.json
+++ b/zh-cn/docs/dev/impls/cluster.json
@@ -1,6 +1,6 @@
{
"filename": "cluster.md",
- "__html": "<h1>集群扩展</h1>\n<h2>扩展说明</h2>\n<p>当有多个服务提供方时,将多个服务提供方组织成一个集群,并伪装成一个提供方。</p>\n<h2>扩展接口</h2>\n<p><code>com.alibaba.dubbo.rpc.cluster.Cluster</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">cluster</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n<span class=\"hljs-comment\"><!-- 缺省值配置,如果<dubbo:protocol>没有配置cluster时,使用此配置 --></span>\n<spa [...]
+ "__html": "<h1>集群扩展</h1>\n<h2>扩展说明</h2>\n<p>当有多个服务提供方时,将多个服务提供方组织成一个集群,并伪装成一个提供方。</p>\n<h2>扩展接口</h2>\n<p><code>org.apache.dubbo.rpc.cluster.Cluster</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">cluster</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n<span class=\"hljs-comment\"><!-- 缺省值配置,如果<dubbo:protocol>没有配置cluster时,使用此配置 --></span>\n<span [...]
"link": "/zh-cn/docs/dev/impls/cluster.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/compiler.html b/zh-cn/docs/dev/impls/compiler.html
index d8fd205..e682db1 100644
--- a/zh-cn/docs/dev/impls/compiler.html
+++ b/zh-cn/docs/dev/impls/compiler.html
@@ -16,13 +16,13 @@
<h2>扩展说明</h2>
<p>Java 代码编译器,用于动态生成字节码,加速调用。</p>
<h2>扩展接口</h2>
-<p><code>com.alibaba.dubbo.common.compiler.Compiler</code></p>
+<p><code>org.apache.dubbo.common.compiler.Compiler</code></p>
<h2>扩展配置</h2>
<p>自动加载</p>
<h2>已知扩展</h2>
<ul>
-<li><code>com.alibaba.dubbo.common.compiler.support.JdkCompiler</code></li>
-<li><code>com.alibaba.dubbo.common.compiler.support.JavassistCompiler</code></li>
+<li><code>org.apache.dubbo.common.compiler.support.JdkCompiler</code></li>
+<li><code>org.apache.dubbo.common.compiler.support.JavassistCompiler</code></li>
</ul>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
@@ -35,12 +35,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.common.compiler.Compiler (纯文本文件,内容为:xxx=com.xxx.XxxCompiler)
+ |-org.apache.dubbo.common.compiler.Compiler (纯文本文件,内容为:xxx=com.xxx.XxxCompiler)
</code></pre>
<p>XxxCompiler.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.compiler.Compiler;
+<span class="hljs-keyword">import</span> org.apache.dubbo.common.compiler.Compiler;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxCompiler</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Compiler</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Object <span class="hljs-title">getExtension</span><span class="hljs-params">(Class<?> type, String name)</span> </span>{
@@ -48,7 +48,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.common.compiler.Compiler:</p>
+<p>META-INF/dubbo/org.apache.dubbo.common.compiler.Compiler:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxCompiler</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/compiler.json b/zh-cn/docs/dev/impls/compiler.json
index 58179f3..4b7768d 100644
--- a/zh-cn/docs/dev/impls/compiler.json
+++ b/zh-cn/docs/dev/impls/compiler.json
@@ -1,6 +1,6 @@
{
"filename": "compiler.md",
- "__html": "<h1>编译器扩展</h1>\n<h2>扩展说明</h2>\n<p>Java 代码编译器,用于动态生成字节码,加速调用。</p>\n<h2>扩展接口</h2>\n<p><code>com.alibaba.dubbo.common.compiler.Compiler</code></p>\n<h2>扩展配置</h2>\n<p>自动加载</p>\n<h2>已知扩展</h2>\n<ul>\n<li><code>com.alibaba.dubbo.common.compiler.support.JdkCompiler</code></li>\n<li><code>com.alibaba.dubbo.common.compiler.support.JavassistCompiler</code></li>\n</ul>\n<h2>扩展示例</h2>\n<p>Maven 项目结构:</p>\n<pre><code>src\n |-main\n |-java\n |-com\n |-xxx\n [...]
+ "__html": "<h1>编译器扩展</h1>\n<h2>扩展说明</h2>\n<p>Java 代码编译器,用于动态生成字节码,加速调用。</p>\n<h2>扩展接口</h2>\n<p><code>org.apache.dubbo.common.compiler.Compiler</code></p>\n<h2>扩展配置</h2>\n<p>自动加载</p>\n<h2>已知扩展</h2>\n<ul>\n<li><code>org.apache.dubbo.common.compiler.support.JdkCompiler</code></li>\n<li><code>org.apache.dubbo.common.compiler.support.JavassistCompiler</code></li>\n</ul>\n<h2>扩展示例</h2>\n<p>Maven 项目结构:</p>\n<pre><code>src\n |-main\n |-java\n |-com\n |-xxx\n [...]
"link": "/zh-cn/docs/dev/impls/compiler.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/container.html b/zh-cn/docs/dev/impls/container.html
index 92adf9c..9bfb421 100644
--- a/zh-cn/docs/dev/impls/container.html
+++ b/zh-cn/docs/dev/impls/container.html
@@ -16,15 +16,15 @@
<h2>扩展说明</h2>
<p>服务容器扩展,用于自定义加载内容。</p>
<h2>扩展接口</h2>
-<p><code>com.alibaba.dubbo.container.Container</code></p>
+<p><code>org.apache.dubbo.container.Container</code></p>
<h2>扩展配置</h2>
-<pre><code class="language-sh">java com.alibaba.dubbo.container.Main spring jetty log4j
+<pre><code class="language-sh">java org.apache.dubbo.container.Main spring jetty log4j
</code></pre>
<h2>已知扩展</h2>
<ul>
-<li><code>com.alibaba.dubbo.container.spring.SpringContainer</code></li>
-<li><code>com.alibaba.dubbo.container.spring.JettyContainer</code></li>
-<li><code>com.alibaba.dubbo.container.spring.Log4jContainer</code></li>
+<li><code>org.apache.dubbo.container.spring.SpringContainer</code></li>
+<li><code>org.apache.dubbo.container.spring.JettyContainer</code></li>
+<li><code>org.apache.dubbo.container.spring.Log4jContainer</code></li>
</ul>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
@@ -37,12 +37,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.container.Container (纯文本文件,内容为:xxx=com.xxx.XxxContainer)
+ |-org.apache.dubbo.container.Container (纯文本文件,内容为:xxx=com.xxx.XxxContainer)
</code></pre>
<p>XxxContainer.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-com.alibaba.dubbo.container.Container;
+org.apache.dubbo.container.Container;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxContainer</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Container</span> </span>{
@@ -54,7 +54,7 @@ com.alibaba.dubbo.container.Container;
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.container.Container:</p>
+<p>META-INF/dubbo/org.apache.dubbo.container.Container:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxContainer</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/container.json b/zh-cn/docs/dev/impls/container.json
index fb2d702..f73769a 100644
--- a/zh-cn/docs/dev/impls/container.json
+++ b/zh-cn/docs/dev/impls/container.json
@@ -1,6 +1,6 @@
{
"filename": "container.md",
- "__html": "<h1>容器扩展</h1>\n<h2>扩展说明</h2>\n<p>服务容器扩展,用于自定义加载内容。</p>\n<h2>扩展接口</h2>\n<p><code>com.alibaba.dubbo.container.Container</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-sh\">java com.alibaba.dubbo.container.Main spring jetty log4j\n</code></pre>\n<h2>已知扩展</h2>\n<ul>\n<li><code>com.alibaba.dubbo.container.spring.SpringContainer</code></li>\n<li><code>com.alibaba.dubbo.container.spring.JettyContainer</code></li>\n<li><code>com.alibaba.dubbo.container.spring.Log4jContainer< [...]
+ "__html": "<h1>容器扩展</h1>\n<h2>扩展说明</h2>\n<p>服务容器扩展,用于自定义加载内容。</p>\n<h2>扩展接口</h2>\n<p><code>org.apache.dubbo.container.Container</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-sh\">java org.apache.dubbo.container.Main spring jetty log4j\n</code></pre>\n<h2>已知扩展</h2>\n<ul>\n<li><code>org.apache.dubbo.container.spring.SpringContainer</code></li>\n<li><code>org.apache.dubbo.container.spring.JettyContainer</code></li>\n<li><code>org.apache.dubbo.container.spring.Log4jContainer</code [...]
"link": "/zh-cn/docs/dev/impls/container.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/dispatcher.html b/zh-cn/docs/dev/impls/dispatcher.html
index 1921b7d..bcdd6b2 100644
--- a/zh-cn/docs/dev/impls/dispatcher.html
+++ b/zh-cn/docs/dev/impls/dispatcher.html
@@ -16,7 +16,7 @@
<h2>扩展说明</h2>
<p>通道信息派发器,用于指定线程池模型。</p>
<h2>扩展接口</h2>
-<p><code>com.alibaba.dubbo.remoting.Dispatcher</code></p>
+<p><code>org.apache.dubbo.remoting.Dispatcher</code></p>
<h2>扩展配置</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">dispatcher</span>=<span class="hljs-string">"xxx"</span> /></span>
<span class="hljs-comment"><!-- 缺省值设置,当<dubbo:protocol>没有配置dispatcher属性时,使用此配置 --></span>
@@ -24,11 +24,11 @@
</code></pre>
<h2>已知扩展</h2>
<ul>
-<li><code>com.alibaba.dubbo.remoting.transport.dispatcher.all.AllDispatcher</code></li>
-<li><code>com.alibaba.dubbo.remoting.transport.dispatcher.direct.DirectDispatcher</code></li>
-<li><code>com.alibaba.dubbo.remoting.transport.dispatcher.message.MessageOnlyDispatcher</code></li>
-<li><code>com.alibaba.dubbo.remoting.transport.dispatcher.execution.ExecutionDispatcher</code></li>
-<li><code>com.alibaba.dubbo.remoting.transport.dispatcher.connection.ConnectionOrderedDispatcher</code></li>
+<li><code>org.apache.dubbo.remoting.transport.dispatcher.all.AllDispatcher</code></li>
+<li><code>org.apache.dubbo.remoting.transport.dispatcher.direct.DirectDispatcher</code></li>
+<li><code>org.apache.dubbo.remoting.transport.dispatcher.message.MessageOnlyDispatcher</code></li>
+<li><code>org.apache.dubbo.remoting.transport.dispatcher.execution.ExecutionDispatcher</code></li>
+<li><code>org.apache.dubbo.remoting.transport.dispatcher.connection.ConnectionOrderedDispatcher</code></li>
</ul>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
@@ -41,12 +41,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.remoting.Dispatcher (纯文本文件,内容为:xxx=com.xxx.XxxDispatcher)
+ |-org.apache.dubbo.remoting.Dispatcher (纯文本文件,内容为:xxx=com.xxx.XxxDispatcher)
</code></pre>
<p>XxxDispatcher.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.remoting.Dispatcher;
+<span class="hljs-keyword">import</span> org.apache.dubbo.remoting.Dispatcher;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxDispatcher</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Dispatcher</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Group <span class="hljs-title">lookup</span><span class="hljs-params">(URL url)</span> </span>{
@@ -54,7 +54,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.remoting.Dispatcher:</p>
+<p>META-INF/dubbo/org.apache.dubbo.remoting.Dispatcher:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxDispatcher</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/dispatcher.json b/zh-cn/docs/dev/impls/dispatcher.json
index 6b0de02..8ce373f 100644
--- a/zh-cn/docs/dev/impls/dispatcher.json
+++ b/zh-cn/docs/dev/impls/dispatcher.json
@@ -1,6 +1,6 @@
{
"filename": "dispatcher.md",
- "__html": "<h1>消息派发扩展</h1>\n<h2>扩展说明</h2>\n<p>通道信息派发器,用于指定线程池模型。</p>\n<h2>扩展接口</h2>\n<p><code>com.alibaba.dubbo.remoting.Dispatcher</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">dispatcher</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n<span class=\"hljs-comment\"><!-- 缺省值设置,当<dubbo:protocol>没有配置dispatcher属性时,使用此配置 --></span>\n<span class=\" [...]
+ "__html": "<h1>消息派发扩展</h1>\n<h2>扩展说明</h2>\n<p>通道信息派发器,用于指定线程池模型。</p>\n<h2>扩展接口</h2>\n<p><code>org.apache.dubbo.remoting.Dispatcher</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">dispatcher</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n<span class=\"hljs-comment\"><!-- 缺省值设置,当<dubbo:protocol>没有配置dispatcher属性时,使用此配置 --></span>\n<span class=\"h [...]
"link": "/zh-cn/docs/dev/impls/dispatcher.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/exchanger.html b/zh-cn/docs/dev/impls/exchanger.html
index 8e7f08e..52025d9 100644
--- a/zh-cn/docs/dev/impls/exchanger.html
+++ b/zh-cn/docs/dev/impls/exchanger.html
@@ -17,9 +17,9 @@
<p>基于传输层之上,实现 Request-Response 信息交换语义。</p>
<h2>扩展接口</h2>
<ul>
-<li><code>com.alibaba.dubbo.remoting.exchange.Exchanger</code></li>
-<li><code>com.alibaba.dubbo.remoting.exchange.ExchangeServer</code></li>
-<li><code>com.alibaba.dubbo.remoting.exchange.ExchangeClient</code></li>
+<li><code>org.apache.dubbo.remoting.exchange.Exchanger</code></li>
+<li><code>org.apache.dubbo.remoting.exchange.ExchangeServer</code></li>
+<li><code>org.apache.dubbo.remoting.exchange.ExchangeClient</code></li>
</ul>
<h2>扩展配置</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">exchanger</span>=<span class="hljs-string">"xxx"</span> /></span>
@@ -27,7 +27,7 @@
<span class="hljs-tag"><<span class="hljs-name">dubbo:provider</span> <span class="hljs-attr">exchanger</span>=<span class="hljs-string">"xxx"</span> /></span>
</code></pre>
<h2>已知扩展</h2>
-<p><code>com.alibaba.dubbo.remoting.exchange.exchanger.HeaderExchanger</code></p>
+<p><code>org.apache.dubbo.remoting.exchange.exchanger.HeaderExchanger</code></p>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
<pre><code>src
@@ -41,12 +41,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.remoting.exchange.Exchanger (纯文本文件,内容为:xxx=com.xxx.XxxExchanger)
+ |-org.apache.dubbo.remoting.exchange.Exchanger (纯文本文件,内容为:xxx=com.xxx.XxxExchanger)
</code></pre>
<p>XxxExchanger.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.remoting.exchange.Exchanger;
+<span class="hljs-keyword">import</span> org.apache.dubbo.remoting.exchange.Exchanger;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxExchanger</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Exchanger</span> </span>{
@@ -62,7 +62,7 @@
<pre><code class="language-java">
<span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.remoting.exchange.ExchangeServer;
+<span class="hljs-keyword">import</span> org.apache.dubbo.remoting.exchange.ExchangeServer;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxExchangeServer</span> <span class="hljs-title">impelements</span> <span class="hljs-title">ExchangeServer</span> </span>{
<span class="hljs-comment">// ...</span>
@@ -71,13 +71,13 @@
<p>XxxExchangeClient.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.remoting.exchange.ExchangeClient;
+<span class="hljs-keyword">import</span> org.apache.dubbo.remoting.exchange.ExchangeClient;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxExchangeClient</span> <span class="hljs-title">impelments</span> <span class="hljs-title">ExchangeClient</span> </span>{
<span class="hljs-comment">// ...</span>
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.remoting.exchange.Exchanger:</p>
+<p>META-INF/dubbo/org.apache.dubbo.remoting.exchange.Exchanger:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxExchanger</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/exchanger.json b/zh-cn/docs/dev/impls/exchanger.json
index e369177..48bf619 100644
--- a/zh-cn/docs/dev/impls/exchanger.json
+++ b/zh-cn/docs/dev/impls/exchanger.json
@@ -1,6 +1,6 @@
{
"filename": "exchanger.md",
- "__html": "<h1>信息交换扩展</h1>\n<h2>扩展说明</h2>\n<p>基于传输层之上,实现 Request-Response 信息交换语义。</p>\n<h2>扩展接口</h2>\n<ul>\n<li><code>com.alibaba.dubbo.remoting.exchange.Exchanger</code></li>\n<li><code>com.alibaba.dubbo.remoting.exchange.ExchangeServer</code></li>\n<li><code>com.alibaba.dubbo.remoting.exchange.ExchangeClient</code></li>\n</ul>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">exchan [...]
+ "__html": "<h1>信息交换扩展</h1>\n<h2>扩展说明</h2>\n<p>基于传输层之上,实现 Request-Response 信息交换语义。</p>\n<h2>扩展接口</h2>\n<ul>\n<li><code>org.apache.dubbo.remoting.exchange.Exchanger</code></li>\n<li><code>org.apache.dubbo.remoting.exchange.ExchangeServer</code></li>\n<li><code>org.apache.dubbo.remoting.exchange.ExchangeClient</code></li>\n</ul>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">exchanger [...]
"link": "/zh-cn/docs/dev/impls/exchanger.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/exporter-listener.html b/zh-cn/docs/dev/impls/exporter-listener.html
index a561f7b..d82aaff 100644
--- a/zh-cn/docs/dev/impls/exporter-listener.html
+++ b/zh-cn/docs/dev/impls/exporter-listener.html
@@ -16,7 +16,7 @@
<h2>扩展说明</h2>
<p>当有服务暴露时,触发该事件。</p>
<h2>扩展接口</h2>
-<p><code>com.alibaba.dubbo.rpc.ExporterListener</code></p>
+<p><code>org.apache.dubbo.rpc.ExporterListener</code></p>
<h2>扩展配置</h2>
<pre><code class="language-xml"><span class="hljs-comment"><!-- 暴露服务监听 --></span>
<span class="hljs-tag"><<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">listener</span>=<span class="hljs-string">"xxx,yyy"</span> /></span>
@@ -24,7 +24,7 @@
<span class="hljs-tag"><<span class="hljs-name">dubbo:provider</span> <span class="hljs-attr">listener</span>=<span class="hljs-string">"xxx,yyy"</span> /></span>
</code></pre>
<h2>已知扩展</h2>
-<p><code>com.alibaba.dubbo.registry.directory.RegistryExporterListener</code></p>
+<p><code>org.apache.dubbo.registry.directory.RegistryExporterListener</code></p>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
<pre><code>src
@@ -36,14 +36,14 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.rpc.ExporterListener (纯文本文件,内容为:xxx=com.xxx.XxxExporterListener)
+ |-org.apache.dubbo.rpc.ExporterListener (纯文本文件,内容为:xxx=com.xxx.XxxExporterListener)
</code></pre>
<p>XxxExporterListener.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.ExporterListener;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Exporter;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.RpcException;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.ExporterListener;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Exporter;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.RpcException;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxExporterListener</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">ExporterListener</span> </span>{
@@ -55,7 +55,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.rpc.ExporterListener:</p>
+<p>META-INF/dubbo/org.apache.dubbo.rpc.ExporterListener:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxExporterListener</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/exporter-listener.json b/zh-cn/docs/dev/impls/exporter-listener.json
index badb301..4933fb5 100644
--- a/zh-cn/docs/dev/impls/exporter-listener.json
+++ b/zh-cn/docs/dev/impls/exporter-listener.json
@@ -1,6 +1,6 @@
{
"filename": "exporter-listener.md",
- "__html": "<h1>暴露监听扩展</h1>\n<h2>扩展说明</h2>\n<p>当有服务暴露时,触发该事件。</p>\n<h2>扩展接口</h2>\n<p><code>com.alibaba.dubbo.rpc.ExporterListener</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-comment\"><!-- 暴露服务监听 --></span>\n<span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:service</span> <span class=\"hljs-attr\">listener</span>=<span class=\"hljs-string\">\"xxx,yyy\"</span> /></span>\n<span class=\"hljs-comment\"><!-- 暴露服务缺省监听器 --></span>\n [...]
+ "__html": "<h1>暴露监听扩展</h1>\n<h2>扩展说明</h2>\n<p>当有服务暴露时,触发该事件。</p>\n<h2>扩展接口</h2>\n<p><code>org.apache.dubbo.rpc.ExporterListener</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-comment\"><!-- 暴露服务监听 --></span>\n<span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:service</span> <span class=\"hljs-attr\">listener</span>=<span class=\"hljs-string\">\"xxx,yyy\"</span> /></span>\n<span class=\"hljs-comment\"><!-- 暴露服务缺省监听器 --></span>\n< [...]
"link": "/zh-cn/docs/dev/impls/exporter-listener.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/extension-factory.html b/zh-cn/docs/dev/impls/extension-factory.html
index e0b5dca..5753b0c 100644
--- a/zh-cn/docs/dev/impls/extension-factory.html
+++ b/zh-cn/docs/dev/impls/extension-factory.html
@@ -16,14 +16,14 @@
<h2>扩展说明</h2>
<p>扩展点本身的加载容器,可从不同容器加载扩展点。</p>
<h2>扩展接口</h2>
-<p><code>com.alibaba.dubbo.common.extension.ExtensionFactory</code></p>
+<p><code>org.apache.dubbo.common.extension.ExtensionFactory</code></p>
<h2>扩展配置</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:application</span> <span class="hljs-attr">compiler</span>=<span class="hljs-string">"jdk"</span> /></span>
</code></pre>
<h2>已知扩展</h2>
<ul>
-<li><code>com.alibaba.dubbo.common.extension.factory.SpiExtensionFactory</code></li>
-<li><code>com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory</code></li>
+<li><code>org.apache.dubbo.common.extension.factory.SpiExtensionFactory</code></li>
+<li><code>org.apache.dubbo.config.spring.extension.SpringExtensionFactory</code></li>
</ul>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
@@ -36,12 +36,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.common.extension.ExtensionFactory (纯文本文件,内容为:xxx=com.xxx.XxxExtensionFactory)
+ |-org.apache.dubbo.common.extension.ExtensionFactory (纯文本文件,内容为:xxx=com.xxx.XxxExtensionFactory)
</code></pre>
<p>XxxExtensionFactory.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.extension.ExtensionFactory;
+<span class="hljs-keyword">import</span> org.apache.dubbo.common.extension.ExtensionFactory;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxExtensionFactory</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">ExtensionFactory</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Object <span class="hljs-title">getExtension</span><span class="hljs-params">(Class<?> type, String name)</span> </span>{
@@ -49,7 +49,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.common.extension.ExtensionFactory:</p>
+<p>META-INF/dubbo/org.apache.dubbo.common.extension.ExtensionFactory:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxExtensionFactory</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/extension-factory.json b/zh-cn/docs/dev/impls/extension-factory.json
index 8aeb6d2..5a74441 100644
--- a/zh-cn/docs/dev/impls/extension-factory.json
+++ b/zh-cn/docs/dev/impls/extension-factory.json
@@ -1,6 +1,6 @@
{
"filename": "extension-factory.md",
- "__html": "<h1>扩展点加载扩展</h1>\n<h2>扩展说明</h2>\n<p>扩展点本身的加载容器,可从不同容器加载扩展点。</p>\n<h2>扩展接口</h2>\n<p><code>com.alibaba.dubbo.common.extension.ExtensionFactory</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:application</span> <span class=\"hljs-attr\">compiler</span>=<span class=\"hljs-string\">\"jdk\"</span> /></span>\n</code></pre>\n<h2>已知扩展</h2>\n<ul>\n<li><code>com.alibaba.dubbo.common.extension.factory.SpiExtens [...]
+ "__html": "<h1>扩展点加载扩展</h1>\n<h2>扩展说明</h2>\n<p>扩展点本身的加载容器,可从不同容器加载扩展点。</p>\n<h2>扩展接口</h2>\n<p><code>org.apache.dubbo.common.extension.ExtensionFactory</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:application</span> <span class=\"hljs-attr\">compiler</span>=<span class=\"hljs-string\">\"jdk\"</span> /></span>\n</code></pre>\n<h2>已知扩展</h2>\n<ul>\n<li><code>org.apache.dubbo.common.extension.factory.SpiExtensio [...]
"link": "/zh-cn/docs/dev/impls/extension-factory.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/filter.html b/zh-cn/docs/dev/impls/filter.html
index c9b8295..b472c9c 100644
--- a/zh-cn/docs/dev/impls/filter.html
+++ b/zh-cn/docs/dev/impls/filter.html
@@ -23,7 +23,7 @@
<li>provider 和 service 同时配置的 filter 时,累加所有 filter,而不是覆盖。比如:<code><dubbo:provider filter="xxx,yyy"/></code> 和 <code><dubbo:service filter="aaa,bbb" /></code>,则 <code>xxx</code>,<code>yyy</code>,<code>aaa</code>,<code>bbb</code> 均会生效。如果要覆盖,需配置:<code><dubbo:service filter="-xxx,-yyy,aaa,bbb" /></code></li>
</ul>
<h2>扩展接口</h2>
-<p><code>com.alibaba.dubbo.rpc.Filter</code></p>
+<p><code>org.apache.dubbo.rpc.Filter</code></p>
<h2>扩展配置</h2>
<pre><code class="language-xml"><span class="hljs-comment"><!-- 消费方调用过程拦截 --></span>
<span class="hljs-tag"><<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">filter</span>=<span class="hljs-string">"xxx,yyy"</span> /></span>
@@ -36,19 +36,19 @@
</code></pre>
<h2>已知扩展</h2>
<ul>
-<li><code>com.alibaba.dubbo.rpc.filter.EchoFilter</code></li>
-<li><code>com.alibaba.dubbo.rpc.filter.GenericFilter</code></li>
-<li><code>com.alibaba.dubbo.rpc.filter.GenericImplFilter</code></li>
-<li><code>com.alibaba.dubbo.rpc.filter.TokenFilter</code></li>
-<li><code>com.alibaba.dubbo.rpc.filter.AccessLogFilter</code></li>
-<li><code>com.alibaba.dubbo.rpc.filter.CountFilter</code></li>
-<li><code>com.alibaba.dubbo.rpc.filter.ActiveLimitFilter</code></li>
-<li><code>com.alibaba.dubbo.rpc.filter.ClassLoaderFilter</code></li>
-<li><code>com.alibaba.dubbo.rpc.filter.ContextFilter</code></li>
-<li><code>com.alibaba.dubbo.rpc.filter.ConsumerContextFilter</code></li>
-<li><code>com.alibaba.dubbo.rpc.filter.ExceptionFilter</code></li>
-<li><code>com.alibaba.dubbo.rpc.filter.ExecuteLimitFilter</code></li>
-<li><code>com.alibaba.dubbo.rpc.filter.DeprecatedFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.EchoFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.GenericFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.GenericImplFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.TokenFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.AccessLogFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.CountFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.ActiveLimitFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.ClassLoaderFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.ContextFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.ConsumerContextFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.ExceptionFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.ExecuteLimitFilter</code></li>
+<li><code>org.apache.dubbo.rpc.filter.DeprecatedFilter</code></li>
</ul>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
@@ -61,16 +61,16 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.rpc.Filter (纯文本文件,内容为:xxx=com.xxx.XxxFilter)
+ |-org.apache.dubbo.rpc.Filter (纯文本文件,内容为:xxx=com.xxx.XxxFilter)
</code></pre>
<p>XxxFilter.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Filter;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Invoker;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Invocation;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Result;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.RpcException;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Filter;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Invoker;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Invocation;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Result;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.RpcException;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxFilter</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Filter</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Result <span class="hljs-title">invoke</span><span class="hljs-params">(Invoker<?> invoker, Invocation invocation)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
@@ -81,7 +81,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.rpc.Filter:</p>
+<p>META-INF/dubbo/org.apache.dubbo.rpc.Filter:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxFilter</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/filter.json b/zh-cn/docs/dev/impls/filter.json
index 5432f7e..83bc4d9 100644
--- a/zh-cn/docs/dev/impls/filter.json
+++ b/zh-cn/docs/dev/impls/filter.json
@@ -1,6 +1,6 @@
{
"filename": "filter.md",
- "__html": "<h1>调用拦截扩展</h1>\n<h2>扩展说明</h2>\n<p>服务提供方和服务消费方调用过程拦截,Dubbo 本身的大多功能均基于此扩展点实现,每次远程方法执行,该拦截都会被执行,请注意对性能的影响。</p>\n<p>约定:</p>\n<ul>\n<li>用户自定义 filter 默认在内置 filter 之后。</li>\n<li>特殊值 <code>default</code>,表示缺省扩展点插入的位置。比如:<code>filter="xxx,default,yyy"</code>,表示 <code>xxx</code> 在缺省 filter 之前,<code>yyy</code> 在缺省 filter 之后。</li>\n<li>特殊符号 <code>-</code>,表示剔除。比如:<code>filter="-foo1"</code>,剔除添加缺省扩展点 <code>foo1</code>。比如:<code>filter="-default"</code>,剔除添加 [...]
+ "__html": "<h1>调用拦截扩展</h1>\n<h2>扩展说明</h2>\n<p>服务提供方和服务消费方调用过程拦截,Dubbo 本身的大多功能均基于此扩展点实现,每次远程方法执行,该拦截都会被执行,请注意对性能的影响。</p>\n<p>约定:</p>\n<ul>\n<li>用户自定义 filter 默认在内置 filter 之后。</li>\n<li>特殊值 <code>default</code>,表示缺省扩展点插入的位置。比如:<code>filter="xxx,default,yyy"</code>,表示 <code>xxx</code> 在缺省 filter 之前,<code>yyy</code> 在缺省 filter 之后。</li>\n<li>特殊符号 <code>-</code>,表示剔除。比如:<code>filter="-foo1"</code>,剔除添加缺省扩展点 <code>foo1</code>。比如:<code>filter="-default"</code>,剔除添加 [...]
"link": "/zh-cn/docs/dev/impls/filter.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/invoker-listener.html b/zh-cn/docs/dev/impls/invoker-listener.html
index 110d786..d7ebb80 100644
--- a/zh-cn/docs/dev/impls/invoker-listener.html
+++ b/zh-cn/docs/dev/impls/invoker-listener.html
@@ -16,7 +16,7 @@
<h2>扩展说明</h2>
<p>当有服务引用时,触发该事件。</p>
<h2>扩展接口</h2>
-<p><code>com.alibaba.dubbo.rpc.InvokerListener</code></p>
+<p><code>org.apache.dubbo.rpc.InvokerListener</code></p>
<h2>扩展配置</h2>
<pre><code class="language-xml"><span class="hljs-comment"><!-- 引用服务监听 --></span>
<span class="hljs-tag"><<span class="hljs-name">dubbo:reference</span> <span class="hljs-attr">listener</span>=<span class="hljs-string">"xxx,yyy"</span> /></span>
@@ -24,7 +24,7 @@
<span class="hljs-tag"><<span class="hljs-name">dubbo:consumer</span> <span class="hljs-attr">listener</span>=<span class="hljs-string">"xxx,yyy"</span> /></span>
</code></pre>
<h2>已知扩展</h2>
-<p><code>com.alibaba.dubbo.rpc.listener.DeprecatedInvokerListener</code></p>
+<p><code>org.apache.dubbo.rpc.listener.DeprecatedInvokerListener</code></p>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
<pre><code>src
@@ -36,14 +36,14 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.rpc.InvokerListener (纯文本文件,内容为:xxx=com.xxx.XxxInvokerListener)
+ |-org.apache.dubbo.rpc.InvokerListener (纯文本文件,内容为:xxx=com.xxx.XxxInvokerListener)
</code></pre>
<p>XxxInvokerListener.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.InvokerListener;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Invoker;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.RpcException;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.InvokerListener;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Invoker;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.RpcException;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxInvokerListener</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">InvokerListener</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">referred</span><span class="hljs-params">(Invoker<?> invoker)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
@@ -54,7 +54,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.rpc.InvokerListener:</p>
+<p>META-INF/dubbo/org.apache.dubbo.rpc.InvokerListener:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxInvokerListener</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/invoker-listener.json b/zh-cn/docs/dev/impls/invoker-listener.json
index 7db8d2e..eb2fef1 100644
--- a/zh-cn/docs/dev/impls/invoker-listener.json
+++ b/zh-cn/docs/dev/impls/invoker-listener.json
@@ -1,6 +1,6 @@
{
"filename": "invoker-listener.md",
- "__html": "<h1>引用监听扩展</h1>\n<h2>扩展说明</h2>\n<p>当有服务引用时,触发该事件。</p>\n<h2>扩展接口</h2>\n<p><code>com.alibaba.dubbo.rpc.InvokerListener</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-comment\"><!-- 引用服务监听 --></span>\n<span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:reference</span> <span class=\"hljs-attr\">listener</span>=<span class=\"hljs-string\">\"xxx,yyy\"</span> /></span> \n<span class=\"hljs-comment\"><!-- 引用服务缺省监听器 --></span> [...]
+ "__html": "<h1>引用监听扩展</h1>\n<h2>扩展说明</h2>\n<p>当有服务引用时,触发该事件。</p>\n<h2>扩展接口</h2>\n<p><code>org.apache.dubbo.rpc.InvokerListener</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-comment\"><!-- 引用服务监听 --></span>\n<span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:reference</span> <span class=\"hljs-attr\">listener</span>=<span class=\"hljs-string\">\"xxx,yyy\"</span> /></span> \n<span class=\"hljs-comment\"><!-- 引用服务缺省监听器 --></span>\ [...]
"link": "/zh-cn/docs/dev/impls/invoker-listener.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/load-balance.html b/zh-cn/docs/dev/impls/load-balance.html
index a2b7e9d..2d9693a 100644
--- a/zh-cn/docs/dev/impls/load-balance.html
+++ b/zh-cn/docs/dev/impls/load-balance.html
@@ -16,7 +16,7 @@
<h2>扩展说明</h2>
<p>从多个服务提者方中选择一个进行调用</p>
<h2>扩展接口</h2>
-<p><code>com.alibaba.dubbo.rpc.cluster.LoadBalance</code></p>
+<p><code>org.apache.dubbo.rpc.cluster.LoadBalance</code></p>
<h2>扩展配置</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">loadbalance</span>=<span class="hljs-string">"xxx"</span> /></span>
<span class="hljs-comment"><!-- 缺省值设置,当<dubbo:protocol>没有配置loadbalance时,使用此配置 --></span>
@@ -24,9 +24,9 @@
</code></pre>
<h2>已知扩展</h2>
<ul>
-<li><code>com.alibaba.dubbo.rpc.cluster.loadbalance.RandomLoadBalance</code></li>
-<li><code>com.alibaba.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance</code></li>
-<li><code>com.alibaba.dubbo.rpc.cluster.loadbalance.LeastActiveLoadBalance</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.loadbalance.RandomLoadBalance</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.loadbalance.LeastActiveLoadBalance</code></li>
</ul>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
@@ -39,15 +39,15 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.rpc.cluster.LoadBalance (纯文本文件,内容为:xxx=com.xxx.XxxLoadBalance)
+ |-org.apache.dubbo.rpc.cluster.LoadBalance (纯文本文件,内容为:xxx=com.xxx.XxxLoadBalance)
</code></pre>
<p>XxxLoadBalance.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.cluster.LoadBalance;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Invoker;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Invocation;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.RpcException;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.cluster.LoadBalance;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Invoker;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Invocation;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.RpcException;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxLoadBalance</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">LoadBalance</span> </span>{
<span class="hljs-keyword">public</span> <T> <span class="hljs-function">Invoker<T> <span class="hljs-title">select</span><span class="hljs-params">(List<Invoker<T>> invokers, Invocation invocation)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
@@ -55,7 +55,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.rpc.cluster.LoadBalance:</p>
+<p>META-INF/dubbo/org.apache.dubbo.rpc.cluster.LoadBalance:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxLoadBalance</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/load-balance.json b/zh-cn/docs/dev/impls/load-balance.json
index 08e7743..23e3b56 100644
--- a/zh-cn/docs/dev/impls/load-balance.json
+++ b/zh-cn/docs/dev/impls/load-balance.json
@@ -1,6 +1,6 @@
{
"filename": "load-balance.md",
- "__html": "<h1>负载均衡扩展</h1>\n<h2>扩展说明</h2>\n<p>从多个服务提者方中选择一个进行调用</p>\n<h2>扩展接口</h2>\n<p><code>com.alibaba.dubbo.rpc.cluster.LoadBalance</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">loadbalance</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n<span class=\"hljs-comment\"><!-- 缺省值设置,当<dubbo:protocol>没有配置loadbalance时,使用此配置 --></span>\n<span class [...]
+ "__html": "<h1>负载均衡扩展</h1>\n<h2>扩展说明</h2>\n<p>从多个服务提者方中选择一个进行调用</p>\n<h2>扩展接口</h2>\n<p><code>org.apache.dubbo.rpc.cluster.LoadBalance</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">loadbalance</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n<span class=\"hljs-comment\"><!-- 缺省值设置,当<dubbo:protocol>没有配置loadbalance时,使用此配置 --></span>\n<span class= [...]
"link": "/zh-cn/docs/dev/impls/load-balance.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/logger-adapter.html b/zh-cn/docs/dev/impls/logger-adapter.html
index 81c1d13..8432b61 100644
--- a/zh-cn/docs/dev/impls/logger-adapter.html
+++ b/zh-cn/docs/dev/impls/logger-adapter.html
@@ -16,7 +16,7 @@
<h2>扩展说明</h2>
<p>日志输出适配扩展点。</p>
<h2>扩展接口</h2>
-<p><code>com.alibaba.dubbo.common.logger.LoggerAdapter</code></p>
+<p><code>org.apache.dubbo.common.logger.LoggerAdapter</code></p>
<h2>扩展配置</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:application</span> <span class="hljs-attr">logger</span>=<span class="hljs-string">"xxx"</span> /></span>
</code></pre>
@@ -25,11 +25,11 @@
</code></pre>
<h2>已知扩展</h2>
<ul>
-<li><code>com.alibaba.dubbo.common.logger.slf4j.Slf4jLoggerAdapter</code></li>
-<li><code>com.alibaba.dubbo.common.logger.jcl.JclLoggerAdapter</code></li>
-<li><code>com.alibaba.dubbo.common.logger.log4j.Log4jLoggerAdapter</code></li>
-<li><code>com.alibaba.dubbo.common.logger.log4j2.Log4j2LoggerAdapter</code></li>
-<li><code>com.alibaba.dubbo.common.logger.jdk.JdkLoggerAdapter</code></li>
+<li><code>org.apache.dubbo.common.logger.slf4j.Slf4jLoggerAdapter</code></li>
+<li><code>org.apache.dubbo.common.logger.jcl.JclLoggerAdapter</code></li>
+<li><code>org.apache.dubbo.common.logger.log4j.Log4jLoggerAdapter</code></li>
+<li><code>org.apache.dubbo.common.logger.log4j2.Log4j2LoggerAdapter</code></li>
+<li><code>org.apache.dubbo.common.logger.jdk.JdkLoggerAdapter</code></li>
</ul>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
@@ -42,12 +42,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.common.logger.LoggerAdapter (纯文本文件,内容为:xxx=com.xxx.XxxLoggerAdapter)
+ |-org.apache.dubbo.common.logger.LoggerAdapter (纯文本文件,内容为:xxx=com.xxx.XxxLoggerAdapter)
</code></pre>
<p>XxxLoggerAdapter.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.logger.LoggerAdapter;
+<span class="hljs-keyword">import</span> org.apache.dubbo.common.logger.LoggerAdapter;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxLoggerAdapter</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">LoggerAdapter</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Logger <span class="hljs-title">getLogger</span><span class="hljs-params">(URL url)</span> </span>{
@@ -58,7 +58,7 @@
<p>XxxLogger.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.logger.Logger;
+<span class="hljs-keyword">import</span> org.apache.dubbo.common.logger.Logger;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxLogger</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Logger</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">XxxLogger</span><span class="hljs-params">(URL url)</span> </span>{
@@ -70,7 +70,7 @@
<span class="hljs-comment">// ...</span>
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.common.logger.LoggerAdapter:</p>
+<p>META-INF/dubbo/org.apache.dubbo.common.logger.LoggerAdapter:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxLoggerAdapter</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/logger-adapter.json b/zh-cn/docs/dev/impls/logger-adapter.json
index 0921499..1b800d7 100644
--- a/zh-cn/docs/dev/impls/logger-adapter.json
+++ b/zh-cn/docs/dev/impls/logger-adapter.json
@@ -1,6 +1,6 @@
{
"filename": "logger-adapter.md",
- "__html": "<h1>日志适配扩展</h1>\n<h2>扩展说明</h2>\n<p>日志输出适配扩展点。</p>\n<h2>扩展接口</h2>\n<p><code>com.alibaba.dubbo.common.logger.LoggerAdapter</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:application</span> <span class=\"hljs-attr\">logger</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n</code></pre>\n<p>或者:</p>\n<pre><code class=\"language-sh\">-Ddubbo:application.logger=xxx\n</code></pre>\n<h2>已知扩展</h2> [...]
+ "__html": "<h1>日志适配扩展</h1>\n<h2>扩展说明</h2>\n<p>日志输出适配扩展点。</p>\n<h2>扩展接口</h2>\n<p><code>org.apache.dubbo.common.logger.LoggerAdapter</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:application</span> <span class=\"hljs-attr\">logger</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n</code></pre>\n<p>或者:</p>\n<pre><code class=\"language-sh\">-Ddubbo:application.logger=xxx\n</code></pre>\n<h2>已知扩展</h2>\ [...]
"link": "/zh-cn/docs/dev/impls/logger-adapter.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/merger.html b/zh-cn/docs/dev/impls/merger.html
index 73589cb..893f7ea 100644
--- a/zh-cn/docs/dev/impls/merger.html
+++ b/zh-cn/docs/dev/impls/merger.html
@@ -16,16 +16,16 @@
<h2>扩展说明</h2>
<p>合并返回结果,用于分组聚合。</p>
<h2>扩展接口</h2>
-<p><code>com.alibaba.dubbo.rpc.cluster.Merger</code></p>
+<p><code>org.apache.dubbo.rpc.cluster.Merger</code></p>
<h2>扩展配置</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:method</span> <span class="hljs-attr">merger</span>=<span class="hljs-string">"xxx"</span> /></span>
</code></pre>
<h2>已知扩展</h2>
<ul>
-<li><code>com.alibaba.dubbo.rpc.cluster.merger.ArrayMerger</code></li>
-<li><code>com.alibaba.dubbo.rpc.cluster.merger.ListMerger</code></li>
-<li><code>com.alibaba.dubbo.rpc.cluster.merger.SetMerger</code></li>
-<li><code>com.alibaba.dubbo.rpc.cluster.merger.MapMerger</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.merger.ArrayMerger</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.merger.ListMerger</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.merger.SetMerger</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.merger.MapMerger</code></li>
</ul>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
@@ -38,12 +38,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.rpc.cluster.Merger (纯文本文件,内容为:xxx=com.xxx.XxxMerger)
+ |-org.apache.dubbo.rpc.cluster.Merger (纯文本文件,内容为:xxx=com.xxx.XxxMerger)
</code></pre>
<p>XxxMerger.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.cluster.Merger;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.cluster.Merger;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxMerger</span><<span class="hljs-title">T</span>> <span class="hljs-keyword">implements</span> <span class="hljs-title">Merger</span><<span class="hljs-title">T</span>> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> T <span class="hljs-title">merge</span><span class="hljs-params">(T... results)</span> </span>{
@@ -51,7 +51,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.rpc.cluster.Merger:</p>
+<p>META-INF/dubbo/org.apache.dubbo.rpc.cluster.Merger:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxMerger</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/merger.json b/zh-cn/docs/dev/impls/merger.json
index ee2f2cd..bf99d77 100644
--- a/zh-cn/docs/dev/impls/merger.json
+++ b/zh-cn/docs/dev/impls/merger.json
@@ -1,6 +1,6 @@
{
"filename": "merger.md",
- "__html": "<h1>合并结果扩展</h1>\n<h2>扩展说明</h2>\n<p>合并返回结果,用于分组聚合。</p>\n<h2>扩展接口</h2>\n<p><code>com.alibaba.dubbo.rpc.cluster.Merger</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:method</span> <span class=\"hljs-attr\">merger</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n</code></pre>\n<h2>已知扩展</h2>\n<ul>\n<li><code>com.alibaba.dubbo.rpc.cluster.merger.ArrayMerger</code></li>\n<li><code>com.alibaba. [...]
+ "__html": "<h1>合并结果扩展</h1>\n<h2>扩展说明</h2>\n<p>合并返回结果,用于分组聚合。</p>\n<h2>扩展接口</h2>\n<p><code>org.apache.dubbo.rpc.cluster.Merger</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:method</span> <span class=\"hljs-attr\">merger</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n</code></pre>\n<h2>已知扩展</h2>\n<ul>\n<li><code>org.apache.dubbo.rpc.cluster.merger.ArrayMerger</code></li>\n<li><code>org.apache.dub [...]
"link": "/zh-cn/docs/dev/impls/merger.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/monitor.html b/zh-cn/docs/dev/impls/monitor.html
index e16cc1a..6b1b126 100644
--- a/zh-cn/docs/dev/impls/monitor.html
+++ b/zh-cn/docs/dev/impls/monitor.html
@@ -17,15 +17,15 @@
<p>负责服务调用次和调用时间的监控。</p>
<h2>扩展接口</h2>
<ul>
-<li><code>com.alibaba.dubbo.monitor.MonitorFactory</code></li>
-<li><code>com.alibaba.dubbo.monitor.Monitor</code></li>
+<li><code>org.apache.dubbo.monitor.MonitorFactory</code></li>
+<li><code>org.apache.dubbo.monitor.Monitor</code></li>
</ul>
<h2>扩展配置</h2>
<pre><code class="language-xml"><span class="hljs-comment"><!-- 定义监控中心 --></span>
<span class="hljs-tag"><<span class="hljs-name">dubbo:monitor</span> <span class="hljs-attr">address</span>=<span class="hljs-string">"xxx://ip:port"</span> /></span>
</code></pre>
<h2>已知扩展</h2>
-<p>com.alibaba.dubbo.monitor.support.dubbo.DubboMonitorFactory</p>
+<p>org.apache.dubbo.monitor.support.dubbo.DubboMonitorFactory</p>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
<pre><code>src
@@ -38,14 +38,14 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.monitor.MonitorFactory (纯文本文件,内容为:xxx=com.xxx.XxxMonitorFactory)
+ |-org.apache.dubbo.monitor.MonitorFactory (纯文本文件,内容为:xxx=com.xxx.XxxMonitorFactory)
</code></pre>
<p>XxxMonitorFactory.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.monitor.MonitorFactory;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.monitor.Monitor;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.URL;
+<span class="hljs-keyword">import</span> org.apache.dubbo.monitor.MonitorFactory;
+<span class="hljs-keyword">import</span> org.apache.dubbo.monitor.Monitor;
+<span class="hljs-keyword">import</span> org.apache.dubbo.common.URL;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxMonitorFactory</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">MonitorFactory</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Monitor <span class="hljs-title">getMonitor</span><span class="hljs-params">(URL url)</span> </span>{
@@ -56,7 +56,7 @@
<p>XxxMonitor.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.monitor.Monitor;
+<span class="hljs-keyword">import</span> org.apache.dubbo.monitor.Monitor;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxMonitor</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Monitor</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">count</span><span class="hljs-params">(URL statistics)</span> </span>{
@@ -64,7 +64,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.monitor.MonitorFactory:</p>
+<p>META-INF/dubbo/org.apache.dubbo.monitor.MonitorFactory:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxMonitorFactory</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/monitor.json b/zh-cn/docs/dev/impls/monitor.json
index e6477dd..6fd9bff 100644
--- a/zh-cn/docs/dev/impls/monitor.json
+++ b/zh-cn/docs/dev/impls/monitor.json
@@ -1,6 +1,6 @@
{
"filename": "monitor.md",
- "__html": "<h1>监控中心扩展</h1>\n<h2>扩展说明</h2>\n<p>负责服务调用次和调用时间的监控。</p>\n<h2>扩展接口</h2>\n<ul>\n<li><code>com.alibaba.dubbo.monitor.MonitorFactory</code></li>\n<li><code>com.alibaba.dubbo.monitor.Monitor</code></li>\n</ul>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-comment\"><!-- 定义监控中心 --></span>\n<span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:monitor</span> <span class=\"hljs-attr\">address</span>=<span class=\"hljs-string\">\"xxx://ip:port\"</s [...]
+ "__html": "<h1>监控中心扩展</h1>\n<h2>扩展说明</h2>\n<p>负责服务调用次和调用时间的监控。</p>\n<h2>扩展接口</h2>\n<ul>\n<li><code>org.apache.dubbo.monitor.MonitorFactory</code></li>\n<li><code>org.apache.dubbo.monitor.Monitor</code></li>\n</ul>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-comment\"><!-- 定义监控中心 --></span>\n<span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:monitor</span> <span class=\"hljs-attr\">address</span>=<span class=\"hljs-string\">\"xxx://ip:port\"</spa [...]
"link": "/zh-cn/docs/dev/impls/monitor.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/networker.html b/zh-cn/docs/dev/impls/networker.html
index def4432..21c8e40 100644
--- a/zh-cn/docs/dev/impls/networker.html
+++ b/zh-cn/docs/dev/impls/networker.html
@@ -16,7 +16,7 @@
<h2>扩展说明</h2>
<p>对等网络节点组网器。</p>
<h2>扩展接口</h2>
-<p><code>com.alibaba.dubbo.remoting.p2p.Networker</code></p>
+<p><code>org.apache.dubbo.remoting.p2p.Networker</code></p>
<h2>扩展配置</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">networker</span>=<span class="hljs-string">"xxx"</span> /></span>
<span class="hljs-comment"><!-- 缺省值设置,当<dubbo:protocol>没有配置networker属性时,使用此配置 --></span>
@@ -24,8 +24,8 @@
</code></pre>
<h2>已知扩展</h2>
<ul>
-<li><code>com.alibaba.dubbo.remoting.p2p.support.MulticastNetworker</code></li>
-<li><code>com.alibaba.dubbo.remoting.p2p.support.FileNetworker</code></li>
+<li><code>org.apache.dubbo.remoting.p2p.support.MulticastNetworker</code></li>
+<li><code>org.apache.dubbo.remoting.p2p.support.FileNetworker</code></li>
</ul>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
@@ -38,12 +38,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.remoting.p2p.Networker (纯文本文件,内容为:xxx=com.xxx.XxxNetworker)
+ |-org.apache.dubbo.remoting.p2p.Networker (纯文本文件,内容为:xxx=com.xxx.XxxNetworker)
</code></pre>
<p>XxxNetworker.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.remoting.p2p.Networker;
+<span class="hljs-keyword">import</span> org.apache.dubbo.remoting.p2p.Networker;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxNetworker</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Networker</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Group <span class="hljs-title">lookup</span><span class="hljs-params">(URL url)</span> </span>{
@@ -51,7 +51,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.remoting.p2p.Networker:</p>
+<p>META-INF/dubbo/org.apache.dubbo.remoting.p2p.Networker:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxNetworker</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/networker.json b/zh-cn/docs/dev/impls/networker.json
index 287b46d..a828a8a 100644
--- a/zh-cn/docs/dev/impls/networker.json
+++ b/zh-cn/docs/dev/impls/networker.json
@@ -1,6 +1,6 @@
{
"filename": "networker.md",
- "__html": "<h1>组网扩展</h1>\n<h2>扩展说明</h2>\n<p>对等网络节点组网器。</p>\n<h2>扩展接口</h2>\n<p><code>com.alibaba.dubbo.remoting.p2p.Networker</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">networker</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n<span class=\"hljs-comment\"><!-- 缺省值设置,当<dubbo:protocol>没有配置networker属性时,使用此配置 --></span>\n<span class=\"hljs-tag\ [...]
+ "__html": "<h1>组网扩展</h1>\n<h2>扩展说明</h2>\n<p>对等网络节点组网器。</p>\n<h2>扩展接口</h2>\n<p><code>org.apache.dubbo.remoting.p2p.Networker</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">networker</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n<span class=\"hljs-comment\"><!-- 缺省值设置,当<dubbo:protocol>没有配置networker属性时,使用此配置 --></span>\n<span class=\"hljs-tag\" [...]
"link": "/zh-cn/docs/dev/impls/networker.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/page.html b/zh-cn/docs/dev/impls/page.html
index 3f91f02..26a324e 100644
--- a/zh-cn/docs/dev/impls/page.html
+++ b/zh-cn/docs/dev/impls/page.html
@@ -16,7 +16,7 @@
<h2>扩展说明</h2>
<p>对等网络节点组网器。</p>
<h2>扩展接口</h2>
-<p><code>com.alibaba.dubbo.container.page.PageHandler</code></p>
+<p><code>org.apache.dubbo.container.page.PageHandler</code></p>
<h2>扩展配置</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">page</span>=<span class="hljs-string">"xxx,yyy"</span> /></span>
<span class="hljs-comment"><!-- 缺省值设置,当<dubbo:protocol>没有配置page属性时,使用此配置 --></span>
@@ -24,10 +24,10 @@
</code></pre>
<h2>已知扩展</h2>
<ul>
-<li><code>com.alibaba.dubbo.container.page.pages.HomePageHandler</code></li>
-<li><code>com.alibaba.dubbo.container.page.pages.StatusPageHandler</code></li>
-<li><code>com.alibaba.dubbo.container.page.pages.LogPageHandler</code></li>
-<li><code>com.alibaba.dubbo.container.page.pages.SystemPageHandler</code></li>
+<li><code>org.apache.dubbo.container.page.pages.HomePageHandler</code></li>
+<li><code>org.apache.dubbo.container.page.pages.StatusPageHandler</code></li>
+<li><code>org.apache.dubbo.container.page.pages.LogPageHandler</code></li>
+<li><code>org.apache.dubbo.container.page.pages.SystemPageHandler</code></li>
</ul>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
@@ -40,12 +40,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.container.page.PageHandler (纯文本文件,内容为:xxx=com.xxx.XxxPageHandler)
+ |-org.apache.dubbo.container.page.PageHandler (纯文本文件,内容为:xxx=com.xxx.XxxPageHandler)
</code></pre>
<p>XxxPageHandler.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.container.page.PageHandler;
+<span class="hljs-keyword">import</span> org.apache.dubbo.container.page.PageHandler;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxPageHandler</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">PageHandler</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Group <span class="hljs-title">lookup</span><span class="hljs-params">(URL url)</span> </span>{
@@ -53,7 +53,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.container.page.PageHandler:</p>
+<p>META-INF/dubbo/org.apache.dubbo.container.page.PageHandler:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxPageHandler</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/page.json b/zh-cn/docs/dev/impls/page.json
index 1d88277..1cc2b37 100644
--- a/zh-cn/docs/dev/impls/page.json
+++ b/zh-cn/docs/dev/impls/page.json
@@ -1,6 +1,6 @@
{
"filename": "page.md",
- "__html": "<h1>页面扩展</h1>\n<h2>扩展说明</h2>\n<p>对等网络节点组网器。</p>\n<h2>扩展接口</h2>\n<p><code>com.alibaba.dubbo.container.page.PageHandler</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">page</span>=<span class=\"hljs-string\">\"xxx,yyy\"</span> /></span>\n<span class=\"hljs-comment\"><!-- 缺省值设置,当<dubbo:protocol>没有配置page属性时,使用此配置 --></span>\n<span class=\"hljs-tag\"> [...]
+ "__html": "<h1>页面扩展</h1>\n<h2>扩展说明</h2>\n<p>对等网络节点组网器。</p>\n<h2>扩展接口</h2>\n<p><code>org.apache.dubbo.container.page.PageHandler</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">page</span>=<span class=\"hljs-string\">\"xxx,yyy\"</span> /></span>\n<span class=\"hljs-comment\"><!-- 缺省值设置,当<dubbo:protocol>没有配置page属性时,使用此配置 --></span>\n<span class=\"hljs-tag\">& [...]
"link": "/zh-cn/docs/dev/impls/page.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/protocol.html b/zh-cn/docs/dev/impls/protocol.html
index 145241e..433d3a5 100644
--- a/zh-cn/docs/dev/impls/protocol.html
+++ b/zh-cn/docs/dev/impls/protocol.html
@@ -27,9 +27,9 @@
</ul>
<h2>扩展接口</h2>
<ul>
-<li><code>com.alibaba.dubbo.rpc.Protocol</code></li>
-<li><code>com.alibaba.dubbo.rpc.Exporter</code></li>
-<li><code>com.alibaba.dubbo.rpc.Invoker</code></li>
+<li><code>org.apache.dubbo.rpc.Protocol</code></li>
+<li><code>org.apache.dubbo.rpc.Exporter</code></li>
+<li><code>org.apache.dubbo.rpc.Invoker</code></li>
</ul>
<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Protocol</span> </span>{
<span class="hljs-comment">/**
@@ -71,11 +71,11 @@
</code></pre>
<h2>已知扩展</h2>
<ul>
-<li><code>com.alibaba.dubbo.rpc.injvm.InjvmProtocol</code></li>
-<li><code>com.alibaba.dubbo.rpc.dubbo.DubboProtocol</code></li>
-<li><code>com.alibaba.dubbo.rpc.rmi.RmiProtocol</code></li>
-<li><code>com.alibaba.dubbo.rpc.http.HttpProtocol</code></li>
-<li><code>com.alibaba.dubbo.rpc.http.hessian.HessianProtocol</code></li>
+<li><code>org.apache.dubbo.rpc.injvm.InjvmProtocol</code></li>
+<li><code>org.apache.dubbo.rpc.dubbo.DubboProtocol</code></li>
+<li><code>org.apache.dubbo.rpc.rmi.RmiProtocol</code></li>
+<li><code>org.apache.dubbo.rpc.http.HttpProtocol</code></li>
+<li><code>org.apache.dubbo.rpc.http.hessian.HessianProtocol</code></li>
</ul>
<h2>扩展示例</h2>
<p>Maven项目结构:</p>
@@ -91,12 +91,12 @@ src
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.rpc.Protocol (纯文本文件,内容为:xxx=com.xxx.XxxProtocol)
+ |-org.apache.dubbo.rpc.Protocol (纯文本文件,内容为:xxx=com.xxx.XxxProtocol)
</code></pre>
<p>XxxProtocol.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Protocol;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Protocol;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxProtocol</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Protocol</span> </span>{
<span class="hljs-keyword">public</span> <T> <span class="hljs-function">Exporter<T> <span class="hljs-title">export</span><span class="hljs-params">(Invoker<T> invoker)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
@@ -110,7 +110,7 @@ src
<p>XxxExporter.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.support.AbstractExporter;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.support.AbstractExporter;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxExporter</span><<span class="hljs-title">T</span>> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractExporter</span><<span class="hljs-title">T</span>> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">XxxExporter</span><span class="hljs-params">(Invoker<T> invoker)</span> <span class="hljs-keyword">throws</span> RemotingException</span>{
@@ -126,7 +126,7 @@ src
<p>XxxInvoker.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.support.AbstractInvoker;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.support.AbstractInvoker;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxInvoker</span><<span class="hljs-title">T</span>> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractInvoker</span><<span class="hljs-title">T</span>> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">XxxInvoker</span><span class="hljs-params">(Class<T> type, URL url)</span> <span class="hljs-keyword">throws</span> RemotingException</span>{
@@ -137,7 +137,7 @@ src
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.rpc.Protocol:</p>
+<p>META-INF/dubbo/org.apache.dubbo.rpc.Protocol:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxProtocol</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/protocol.json b/zh-cn/docs/dev/impls/protocol.json
index 78eb463..4349d20 100644
--- a/zh-cn/docs/dev/impls/protocol.json
+++ b/zh-cn/docs/dev/impls/protocol.json
@@ -1,6 +1,6 @@
{
"filename": "protocol.md",
- "__html": "<h1>协议扩展</h1>\n<h2>扩展说明</h2>\n<p>RPC 协议扩展,封装远程调用细节。</p>\n<p>契约:</p>\n<ul>\n<li>当用户调用 <code>refer()</code> 所返回的 <code>Invoker</code> 对象的 <code>invoke()</code> 方法时,协议需相应执行同 URL 远端 <code>export()</code> 传入的 <code>Invoker</code> 对象的 <code>invoke()</code> 方法。</li>\n<li>其中,<code>refer()</code> 返回的 <code>Invoker</code> 由协议实现,协议通常需要在此 <code>Invoker</code> 中发送远程请求,<code>export()</code> 传入的 <code>Invoker</code> 由框架实现并传入,协议不需要关心。</li>\n</ul>\n<p>注意:</p>\n<ul>\n<li>协议不关心业务接口的透明代理,以 <cod [...]
+ "__html": "<h1>协议扩展</h1>\n<h2>扩展说明</h2>\n<p>RPC 协议扩展,封装远程调用细节。</p>\n<p>契约:</p>\n<ul>\n<li>当用户调用 <code>refer()</code> 所返回的 <code>Invoker</code> 对象的 <code>invoke()</code> 方法时,协议需相应执行同 URL 远端 <code>export()</code> 传入的 <code>Invoker</code> 对象的 <code>invoke()</code> 方法。</li>\n<li>其中,<code>refer()</code> 返回的 <code>Invoker</code> 由协议实现,协议通常需要在此 <code>Invoker</code> 中发送远程请求,<code>export()</code> 传入的 <code>Invoker</code> 由框架实现并传入,协议不需要关心。</li>\n</ul>\n<p>注意:</p>\n<ul>\n<li>协议不关心业务接口的透明代理,以 <cod [...]
"link": "/zh-cn/docs/dev/impls/protocol.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/proxy-factory.html b/zh-cn/docs/dev/impls/proxy-factory.html
index dc5ac0e..87b464e 100644
--- a/zh-cn/docs/dev/impls/proxy-factory.html
+++ b/zh-cn/docs/dev/impls/proxy-factory.html
@@ -16,7 +16,7 @@
<h2>扩展说明</h2>
<p>将 <code>Invoker</code> 接口转换成业务接口。</p>
<h2>扩展接口</h2>
-<p><code>com.alibaba.dubbo.rpc.ProxyFactory</code></p>
+<p><code>org.apache.dubbo.rpc.ProxyFactory</code></p>
<h2>扩展配置</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">proxy</span>=<span class="hljs-string">"xxx"</span> /></span>
<span class="hljs-comment"><!-- 缺省值配置,当<dubbo:protocol>没有配置proxy属性时,使用此配置 --></span>
@@ -24,8 +24,8 @@
</code></pre>
<h2>已知扩展</h2>
<ul>
-<li><code>com.alibaba.dubbo.rpc.proxy.JdkProxyFactory</code></li>
-<li><code>com.alibaba.dubbo.rpc.proxy.JavassistProxyFactory</code></li>
+<li><code>org.apache.dubbo.rpc.proxy.JdkProxyFactory</code></li>
+<li><code>org.apache.dubbo.rpc.proxy.JavassistProxyFactory</code></li>
</ul>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
@@ -38,14 +38,14 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.rpc.ProxyFactory (纯文本文件,内容为:xxx=com.xxx.XxxProxyFactory)
+ |-org.apache.dubbo.rpc.ProxyFactory (纯文本文件,内容为:xxx=com.xxx.XxxProxyFactory)
</code></pre>
<p>XxxProxyFactory.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.ProxyFactory;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Invoker;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.RpcException;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.ProxyFactory;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Invoker;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.RpcException;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxProxyFactory</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">ProxyFactory</span> </span>{
@@ -57,7 +57,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.rpc.ProxyFactory:</p>
+<p>META-INF/dubbo/org.apache.dubbo.rpc.ProxyFactory:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxProxyFactory</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/proxy-factory.json b/zh-cn/docs/dev/impls/proxy-factory.json
index 9d3aea6..4eabc56 100644
--- a/zh-cn/docs/dev/impls/proxy-factory.json
+++ b/zh-cn/docs/dev/impls/proxy-factory.json
@@ -1,6 +1,6 @@
{
"filename": "proxy-factory.md",
- "__html": "<h1>动态代理扩展</h1>\n<h2>扩展说明</h2>\n<p>将 <code>Invoker</code> 接口转换成业务接口。</p>\n<h2>扩展接口</h2>\n<p><code>com.alibaba.dubbo.rpc.ProxyFactory</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">proxy</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n<span class=\"hljs-comment\"><!-- 缺省值配置,当<dubbo:protocol>没有配置proxy属性时,使用此配置 --></span>\n<span class= [...]
+ "__html": "<h1>动态代理扩展</h1>\n<h2>扩展说明</h2>\n<p>将 <code>Invoker</code> 接口转换成业务接口。</p>\n<h2>扩展接口</h2>\n<p><code>org.apache.dubbo.rpc.ProxyFactory</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">proxy</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n<span class=\"hljs-comment\"><!-- 缺省值配置,当<dubbo:protocol>没有配置proxy属性时,使用此配置 --></span>\n<span class=\ [...]
"link": "/zh-cn/docs/dev/impls/proxy-factory.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/registry.html b/zh-cn/docs/dev/impls/registry.html
index 08d474a..f2035c8 100644
--- a/zh-cn/docs/dev/impls/registry.html
+++ b/zh-cn/docs/dev/impls/registry.html
@@ -17,8 +17,8 @@
<p>负责服务的注册与发现。</p>
<h2>扩展接口</h2>
<ul>
-<li><code>com.alibaba.dubbo.registry.RegistryFactory</code></li>
-<li><code>com.alibaba.dubbo.registry.Registry</code></li>
+<li><code>org.apache.dubbo.registry.RegistryFactory</code></li>
+<li><code>org.apache.dubbo.registry.Registry</code></li>
</ul>
<h2>扩展配置</h2>
<pre><code class="language-xml"><span class="hljs-comment"><!-- 定义注册中心 --></span>
@@ -107,9 +107,9 @@
<span class="hljs-comment">/**
* 查询注册列表,与订阅的推模式相对应,这里为拉模式,只返回一次结果。
*
- * <span class="hljs-doctag">@see</span> com.alibaba.dubbo.registry.NotifyListener#notify(List)
+ * <span class="hljs-doctag">@see</span> org.apache.dubbo.registry.NotifyListener#notify(List)
* <span class="hljs-doctag">@param</span> url 查询条件,不允许为空,如:consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
- * <span class="hljs-doctag">@return</span> 已注册信息列表,可能为空,含义同{<span class="hljs-doctag">@link</span> com.alibaba.dubbo.registry.NotifyListener#notify(List<URL>)}的参数。
+ * <span class="hljs-doctag">@return</span> 已注册信息列表,可能为空,含义同{<span class="hljs-doctag">@link</span> org.apache.dubbo.registry.NotifyListener#notify(List<URL>)}的参数。
*/</span>
<span class="hljs-function">List<URL> <span class="hljs-title">lookup</span><span class="hljs-params">(URL url)</span></span>;
@@ -127,14 +127,14 @@
* 4. 如果一种类型的数据为空,需通知一个empty协议并带category参数的标识性URL数据。<br>
* 5. 通知者(即注册中心实现)需保证通知的顺序,比如:单线程推送,队列串行化,带版本对比。<br>
*
- * <span class="hljs-doctag">@param</span> urls 已注册信息列表,总不为空,含义同{<span class="hljs-doctag">@link</span> com.alibaba.dubbo.registry.RegistryService#lookup(URL)}的返回值。
+ * <span class="hljs-doctag">@param</span> urls 已注册信息列表,总不为空,含义同{<span class="hljs-doctag">@link</span> org.apache.dubbo.registry.RegistryService#lookup(URL)}的返回值。
*/</span>
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">notify</span><span class="hljs-params">(List<URL> urls)</span></span>;
}
</code></pre>
<h2>已知扩展</h2>
-<p><code>com.alibaba.dubbo.registry.support.dubbo.DubboRegistryFactory</code></p>
+<p><code>org.apache.dubbo.registry.support.dubbo.DubboRegistryFactory</code></p>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
<pre><code>src
@@ -147,14 +147,14 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.registry.RegistryFactory (纯文本文件,内容为:xxx=com.xxx.XxxRegistryFactory)
+ |-org.apache.dubbo.registry.RegistryFactory (纯文本文件,内容为:xxx=com.xxx.XxxRegistryFactory)
</code></pre>
<p>XxxRegistryFactory.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.registry.RegistryFactory;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.registry.Registry;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.URL;
+<span class="hljs-keyword">import</span> org.apache.dubbo.registry.RegistryFactory;
+<span class="hljs-keyword">import</span> org.apache.dubbo.registry.Registry;
+<span class="hljs-keyword">import</span> org.apache.dubbo.common.URL;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxRegistryFactory</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">RegistryFactory</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Registry <span class="hljs-title">getRegistry</span><span class="hljs-params">(URL url)</span> </span>{
@@ -165,9 +165,9 @@
<p>XxxRegistry.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.registry.Registry;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.registry.NotifyListener;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.URL;
+<span class="hljs-keyword">import</span> org.apache.dubbo.registry.Registry;
+<span class="hljs-keyword">import</span> org.apache.dubbo.registry.NotifyListener;
+<span class="hljs-keyword">import</span> org.apache.dubbo.common.URL;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxRegistry</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Registry</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">register</span><span class="hljs-params">(URL url)</span> </span>{
@@ -184,7 +184,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.registry.RegistryFactory:</p>
+<p>META-INF/dubbo/org.apache.dubbo.registry.RegistryFactory:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxRegistryFactory</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/registry.json b/zh-cn/docs/dev/impls/registry.json
index 547e12f..ec8bdd5 100644
--- a/zh-cn/docs/dev/impls/registry.json
+++ b/zh-cn/docs/dev/impls/registry.json
@@ -1,6 +1,6 @@
{
"filename": "registry.md",
- "__html": "<h1>注册中心扩展</h1>\n<h2>扩展说明</h2>\n<p>负责服务的注册与发现。</p>\n<h2>扩展接口</h2>\n<ul>\n<li><code>com.alibaba.dubbo.registry.RegistryFactory</code></li>\n<li><code>com.alibaba.dubbo.registry.Registry</code></li>\n</ul>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-comment\"><!-- 定义注册中心 --></span>\n<span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:registry</span> <span class=\"hljs-attr\">id</span>=<span class=\"hljs-string\">\"xxx1\"</span> <span cla [...]
+ "__html": "<h1>注册中心扩展</h1>\n<h2>扩展说明</h2>\n<p>负责服务的注册与发现。</p>\n<h2>扩展接口</h2>\n<ul>\n<li><code>org.apache.dubbo.registry.RegistryFactory</code></li>\n<li><code>org.apache.dubbo.registry.Registry</code></li>\n</ul>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-comment\"><!-- 定义注册中心 --></span>\n<span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:registry</span> <span class=\"hljs-attr\">id</span>=<span class=\"hljs-string\">\"xxx1\"</span> <span class [...]
"link": "/zh-cn/docs/dev/impls/registry.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/remoting.html b/zh-cn/docs/dev/impls/remoting.html
index b6c3881..cf54fde 100644
--- a/zh-cn/docs/dev/impls/remoting.html
+++ b/zh-cn/docs/dev/impls/remoting.html
@@ -17,9 +17,9 @@
<p>远程通讯的服务器及客户端传输实现。</p>
<h2>扩展接口</h2>
<ul>
-<li><code>com.alibaba.dubbo.remoting.Transporter</code></li>
-<li><code>com.alibaba.dubbo.remoting.Server</code></li>
-<li><code>com.alibaba.dubbo.remoting.Client</code></li>
+<li><code>org.apache.dubbo.remoting.Transporter</code></li>
+<li><code>org.apache.dubbo.remoting.Server</code></li>
+<li><code>org.apache.dubbo.remoting.Client</code></li>
</ul>
<h2>扩展配置</h2>
<pre><code class="language-xml"><span class="hljs-comment"><!-- 服务器和客户端使用相同的传输实现 --></span>
@@ -31,9 +31,9 @@
</code></pre>
<h2>已知扩展</h2>
<ul>
-<li><code>com.alibaba.dubbo.remoting.transport.transporter.netty.NettyTransporter</code></li>
-<li><code>com.alibaba.dubbo.remoting.transport.transporter.mina.MinaTransporter</code></li>
-<li><code>com.alibaba.dubbo.remoting.transport.transporter.grizzly.GrizzlyTransporter</code></li>
+<li><code>org.apache.dubbo.remoting.transport.transporter.netty.NettyTransporter</code></li>
+<li><code>org.apache.dubbo.remoting.transport.transporter.mina.MinaTransporter</code></li>
+<li><code>org.apache.dubbo.remoting.transport.transporter.grizzly.GrizzlyTransporter</code></li>
</ul>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
@@ -48,12 +48,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.remoting.Transporter (纯文本文件,内容为:xxx=com.xxx.XxxTransporter)
+ |-org.apache.dubbo.remoting.Transporter (纯文本文件,内容为:xxx=com.xxx.XxxTransporter)
</code></pre>
<p>XxxTransporter.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.remoting.Transporter;
+<span class="hljs-keyword">import</span> org.apache.dubbo.remoting.Transporter;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxTransporter</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Transporter</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Server <span class="hljs-title">bind</span><span class="hljs-params">(URL url, ChannelHandler handler)</span> <span class="hljs-keyword">throws</span> RemotingException </span>{
@@ -67,7 +67,7 @@
<p>XxxServer.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.remoting.transport.transporter.AbstractServer;
+<span class="hljs-keyword">import</span> org.apache.dubbo.remoting.transport.transporter.AbstractServer;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxServer</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractServer</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">XxxServer</span><span class="hljs-params">(URL url, ChannelHandler handler)</span> <span class="hljs-keyword">throws</span> RemotingException</span>{
@@ -90,7 +90,7 @@
<p>XxxClient.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.remoting.transport.transporter.AbstractClient;
+<span class="hljs-keyword">import</span> org.apache.dubbo.remoting.transport.transporter.AbstractClient;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxClient</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractClient</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">XxxServer</span><span class="hljs-params">(URL url, ChannelHandler handler)</span> <span class="hljs-keyword">throws</span> RemotingException</span>{
@@ -110,7 +110,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.remoting.Transporter:</p>
+<p>META-INF/dubbo/org.apache.dubbo.remoting.Transporter:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxTransporter</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/remoting.json b/zh-cn/docs/dev/impls/remoting.json
index 258ace2..ec5282a 100644
--- a/zh-cn/docs/dev/impls/remoting.json
+++ b/zh-cn/docs/dev/impls/remoting.json
@@ -1,6 +1,6 @@
{
"filename": "remoting.md",
- "__html": "<h1>网络传输扩展</h1>\n<h2>扩展说明</h2>\n<p>远程通讯的服务器及客户端传输实现。</p>\n<h2>扩展接口</h2>\n<ul>\n<li><code>com.alibaba.dubbo.remoting.Transporter</code></li>\n<li><code>com.alibaba.dubbo.remoting.Server</code></li>\n<li><code>com.alibaba.dubbo.remoting.Client</code></li>\n</ul>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-comment\"><!-- 服务器和客户端使用相同的传输实现 --></span>\n<span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-att [...]
+ "__html": "<h1>网络传输扩展</h1>\n<h2>扩展说明</h2>\n<p>远程通讯的服务器及客户端传输实现。</p>\n<h2>扩展接口</h2>\n<ul>\n<li><code>org.apache.dubbo.remoting.Transporter</code></li>\n<li><code>org.apache.dubbo.remoting.Server</code></li>\n<li><code>org.apache.dubbo.remoting.Client</code></li>\n</ul>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-comment\"><!-- 服务器和客户端使用相同的传输实现 --></span>\n<span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\" [...]
"link": "/zh-cn/docs/dev/impls/remoting.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/router.html b/zh-cn/docs/dev/impls/router.html
index d72337a..793d786 100644
--- a/zh-cn/docs/dev/impls/router.html
+++ b/zh-cn/docs/dev/impls/router.html
@@ -17,13 +17,13 @@
<p>从多个服务提者方中选择一个进行调用。</p>
<h2>扩展接口</h2>
<ul>
-<li><code>com.alibaba.dubbo.rpc.cluster.RouterFactory</code></li>
-<li><code>com.alibaba.dubbo.rpc.cluster.Router</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.RouterFactory</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.Router</code></li>
</ul>
<h2>已知扩展</h2>
<ul>
-<li><code>com.alibaba.dubbo.rpc.cluster.router.ScriptRouterFactory</code></li>
-<li><code>com.alibaba.dubbo.rpc.cluster.router.FileRouterFactory</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.router.ScriptRouterFactory</code></li>
+<li><code>org.apache.dubbo.rpc.cluster.router.FileRouterFactory</code></li>
</ul>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
@@ -36,16 +36,16 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.rpc.cluster.RouterFactory (纯文本文件,内容为:xxx=com.xxx.XxxRouterFactory)
+ |-org.apache.dubbo.rpc.cluster.RouterFactory (纯文本文件,内容为:xxx=com.xxx.XxxRouterFactory)
</code></pre>
<p>XxxRouterFactory.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.cluster.RouterFactory;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Invoker;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.Invocation;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.rpc.RpcException;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.cluster.RouterFactory;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Invoker;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.Invocation;
+<span class="hljs-keyword">import</span> org.apache.dubbo.rpc.RpcException;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxRouterFactory</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">RouterFactory</span> </span>{
<span class="hljs-keyword">public</span> <T> List<Invoker<T>> select(List<Invoker<T>> invokers, Invocation invocation) <span class="hljs-keyword">throws</span> RpcException {
@@ -53,7 +53,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.rpc.cluster.RouterFactory:</p>
+<p>META-INF/dubbo/org.apache.dubbo.rpc.cluster.RouterFactory:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxRouterFactory</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/router.json b/zh-cn/docs/dev/impls/router.json
index 57c8b2b..d6f83f2 100644
--- a/zh-cn/docs/dev/impls/router.json
+++ b/zh-cn/docs/dev/impls/router.json
@@ -1,6 +1,6 @@
{
"filename": "router.md",
- "__html": "<h1>路由扩展</h1>\n<h2>扩展说明</h2>\n<p>从多个服务提者方中选择一个进行调用。</p>\n<h2>扩展接口</h2>\n<ul>\n<li><code>com.alibaba.dubbo.rpc.cluster.RouterFactory</code></li>\n<li><code>com.alibaba.dubbo.rpc.cluster.Router</code></li>\n</ul>\n<h2>已知扩展</h2>\n<ul>\n<li><code>com.alibaba.dubbo.rpc.cluster.router.ScriptRouterFactory</code></li>\n<li><code>com.alibaba.dubbo.rpc.cluster.router.FileRouterFactory</code></li>\n</ul>\n<h2>扩展示例</h2>\n<p>Maven 项目结构:</p>\n<pre><code>src\n |-main\n |-java\n | [...]
+ "__html": "<h1>路由扩展</h1>\n<h2>扩展说明</h2>\n<p>从多个服务提者方中选择一个进行调用。</p>\n<h2>扩展接口</h2>\n<ul>\n<li><code>org.apache.dubbo.rpc.cluster.RouterFactory</code></li>\n<li><code>org.apache.dubbo.rpc.cluster.Router</code></li>\n</ul>\n<h2>已知扩展</h2>\n<ul>\n<li><code>org.apache.dubbo.rpc.cluster.router.ScriptRouterFactory</code></li>\n<li><code>org.apache.dubbo.rpc.cluster.router.FileRouterFactory</code></li>\n</ul>\n<h2>扩展示例</h2>\n<p>Maven 项目结构:</p>\n<pre><code>src\n |-main\n |-java\n |-com [...]
"link": "/zh-cn/docs/dev/impls/router.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/serialize.html b/zh-cn/docs/dev/impls/serialize.html
index 666cf9f..1769810 100644
--- a/zh-cn/docs/dev/impls/serialize.html
+++ b/zh-cn/docs/dev/impls/serialize.html
@@ -17,9 +17,9 @@
<p>将对象转成字节流,用于网络传输,以及将字节流转为对象,用于在收到字节流数据后还原成对象。</p>
<h2>扩展接口</h2>
<ul>
-<li><code>com.alibaba.dubbo.common.serialize.Serialization</code></li>
-<li><code>com.alibaba.dubbo.common.serialize.ObjectInput</code></li>
-<li><code>com.alibaba.dubbo.common.serialize.ObjectOutput</code></li>
+<li><code>org.apache.dubbo.common.serialize.Serialization</code></li>
+<li><code>org.apache.dubbo.common.serialize.ObjectInput</code></li>
+<li><code>org.apache.dubbo.common.serialize.ObjectOutput</code></li>
</ul>
<h2>扩展配置</h2>
<pre><code class="language-xml"><span class="hljs-comment"><!-- 协议的序列化方式 --></span>
@@ -29,10 +29,10 @@
</code></pre>
<h2>已知扩展</h2>
<ul>
-<li><code>com.alibaba.dubbo.common.serialize.dubbo.DubboSerialization</code></li>
-<li><code>com.alibaba.dubbo.common.serialize.hessian.Hessian2Serialization</code></li>
-<li><code>com.alibaba.dubbo.common.serialize.java.JavaSerialization</code></li>
-<li><code>com.alibaba.dubbo.common.serialize.java.CompactedJavaSerialization</code></li>
+<li><code>org.apache.dubbo.common.serialize.dubbo.DubboSerialization</code></li>
+<li><code>org.apache.dubbo.common.serialize.hessian.Hessian2Serialization</code></li>
+<li><code>org.apache.dubbo.common.serialize.java.JavaSerialization</code></li>
+<li><code>org.apache.dubbo.common.serialize.java.CompactedJavaSerialization</code></li>
</ul>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
@@ -47,14 +47,14 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.common.serialize.Serialization (纯文本文件,内容为:xxx=com.xxx.XxxSerialization)
+ |-org.apache.dubbo.common.serialize.Serialization (纯文本文件,内容为:xxx=com.xxx.XxxSerialization)
</code></pre>
<p>XxxSerialization.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.serialize.Serialization;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.serialize.ObjectInput;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.serialize.ObjectOutput;
+<span class="hljs-keyword">import</span> org.apache.dubbo.common.serialize.Serialization;
+<span class="hljs-keyword">import</span> org.apache.dubbo.common.serialize.ObjectInput;
+<span class="hljs-keyword">import</span> org.apache.dubbo.common.serialize.ObjectOutput;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxSerialization</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Serialization</span> </span>{
@@ -66,7 +66,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.common.serialize.Serialization:</p>
+<p>META-INF/dubbo/org.apache.dubbo.common.serialize.Serialization:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxSerialization</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/serialize.json b/zh-cn/docs/dev/impls/serialize.json
index 3eca291..af094d0 100644
--- a/zh-cn/docs/dev/impls/serialize.json
+++ b/zh-cn/docs/dev/impls/serialize.json
@@ -1,6 +1,6 @@
{
"filename": "serialize.md",
- "__html": "<h1>序列化扩展</h1>\n<h2>扩展说明</h2>\n<p>将对象转成字节流,用于网络传输,以及将字节流转为对象,用于在收到字节流数据后还原成对象。</p>\n<h2>扩展接口</h2>\n<ul>\n<li><code>com.alibaba.dubbo.common.serialize.Serialization</code></li>\n<li><code>com.alibaba.dubbo.common.serialize.ObjectInput</code></li>\n<li><code>com.alibaba.dubbo.common.serialize.ObjectOutput</code></li>\n</ul>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-comment\"><!-- 协议的序列化方式 --></span>\n<span class=\"hljs-tag\"><<span class=\"h [...]
+ "__html": "<h1>序列化扩展</h1>\n<h2>扩展说明</h2>\n<p>将对象转成字节流,用于网络传输,以及将字节流转为对象,用于在收到字节流数据后还原成对象。</p>\n<h2>扩展接口</h2>\n<ul>\n<li><code>org.apache.dubbo.common.serialize.Serialization</code></li>\n<li><code>org.apache.dubbo.common.serialize.ObjectInput</code></li>\n<li><code>org.apache.dubbo.common.serialize.ObjectOutput</code></li>\n</ul>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-comment\"><!-- 协议的序列化方式 --></span>\n<span class=\"hljs-tag\"><<span class=\"hljs [...]
"link": "/zh-cn/docs/dev/impls/serialize.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/status-checker.html b/zh-cn/docs/dev/impls/status-checker.html
index 2e65838..1bb54c9 100644
--- a/zh-cn/docs/dev/impls/status-checker.html
+++ b/zh-cn/docs/dev/impls/status-checker.html
@@ -16,7 +16,7 @@
<h2>扩展说明</h2>
<p>检查服务依赖各种资源的状态,此状态检查可同时用于 telnet 的 status 命令和 hosting 的 status 页面。</p>
<h2>扩展接口</h2>
-<p><code>com.alibaba.dubbo.common.status.StatusChecker</code></p>
+<p><code>org.apache.dubbo.common.status.StatusChecker</code></p>
<h2>扩展配置</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">status</span>=<span class="hljs-string">"xxx,yyy"</span> /></span>
<span class="hljs-comment"><!-- 缺省值设置,当<dubbo:protocol>没有配置status属性时,使用此配置 --></span>
@@ -24,13 +24,13 @@
</code></pre>
<h2>已知扩展</h2>
<ul>
-<li><code>com.alibaba.dubbo.common.status.support.MemoryStatusChecker</code></li>
-<li><code>com.alibaba.dubbo.common.status.support.LoadStatusChecker</code></li>
-<li><code>com.alibaba.dubbo.rpc.dubbo.status.ServerStatusChecker</code></li>
-<li><code>com.alibaba.dubbo.rpc.dubbo.status.ThreadPoolStatusChecker</code></li>
-<li><code>com.alibaba.dubbo.registry.directory.RegistryStatusChecker</code></li>
-<li><code>com.alibaba.dubbo.rpc.config.spring.status.SpringStatusChecker</code></li>
-<li><code>com.alibaba.dubbo.rpc.config.spring.status.DataSourceStatusChecker</code></li>
+<li><code>org.apache.dubbo.common.status.support.MemoryStatusChecker</code></li>
+<li><code>org.apache.dubbo.common.status.support.LoadStatusChecker</code></li>
+<li><code>org.apache.dubbo.rpc.dubbo.status.ServerStatusChecker</code></li>
+<li><code>org.apache.dubbo.rpc.dubbo.status.ThreadPoolStatusChecker</code></li>
+<li><code>org.apache.dubbo.registry.directory.RegistryStatusChecker</code></li>
+<li><code>org.apache.dubbo.rpc.config.spring.status.SpringStatusChecker</code></li>
+<li><code>org.apache.dubbo.rpc.config.spring.status.DataSourceStatusChecker</code></li>
</ul>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
@@ -43,12 +43,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.common.status.StatusChecker (纯文本文件,内容为:xxx=com.xxx.XxxStatusChecker)
+ |-org.apache.dubbo.common.status.StatusChecker (纯文本文件,内容为:xxx=com.xxx.XxxStatusChecker)
</code></pre>
<p>XxxStatusChecker.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.status.StatusChecker;
+<span class="hljs-keyword">import</span> org.apache.dubbo.common.status.StatusChecker;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxStatusChecker</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">StatusChecker</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Status <span class="hljs-title">check</span><span class="hljs-params">()</span> </span>{
@@ -56,7 +56,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.common.status.StatusChecker:</p>
+<p>META-INF/dubbo/org.apache.dubbo.common.status.StatusChecker:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxStatusChecker</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/status-checker.json b/zh-cn/docs/dev/impls/status-checker.json
index 75427b3..929d7ca 100644
--- a/zh-cn/docs/dev/impls/status-checker.json
+++ b/zh-cn/docs/dev/impls/status-checker.json
@@ -1,6 +1,6 @@
{
"filename": "status-checker.md",
- "__html": "<h1>状态检查扩展</h1>\n<h2>扩展说明</h2>\n<p>检查服务依赖各种资源的状态,此状态检查可同时用于 telnet 的 status 命令和 hosting 的 status 页面。</p>\n<h2>扩展接口</h2>\n<p><code>com.alibaba.dubbo.common.status.StatusChecker</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">status</span>=<span class=\"hljs-string\">\"xxx,yyy\"</span> /></span>\n<span class=\"hljs-comment\"><!-- 缺省值设置,当<dubbo:protocol&g [...]
+ "__html": "<h1>状态检查扩展</h1>\n<h2>扩展说明</h2>\n<p>检查服务依赖各种资源的状态,此状态检查可同时用于 telnet 的 status 命令和 hosting 的 status 页面。</p>\n<h2>扩展接口</h2>\n<p><code>org.apache.dubbo.common.status.StatusChecker</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">status</span>=<span class=\"hljs-string\">\"xxx,yyy\"</span> /></span>\n<span class=\"hljs-comment\"><!-- 缺省值设置,当<dubbo:protocol> [...]
"link": "/zh-cn/docs/dev/impls/status-checker.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/telnet-handler.html b/zh-cn/docs/dev/impls/telnet-handler.html
index 3eaa586..bf5d0c4 100644
--- a/zh-cn/docs/dev/impls/telnet-handler.html
+++ b/zh-cn/docs/dev/impls/telnet-handler.html
@@ -16,7 +16,7 @@
<h2>扩展说明</h2>
<p>所有服务器均支持 telnet 访问,用于人工干预。</p>
<h2>扩展接口</h2>
-<p><code>com.alibaba.dubbo.remoting.telnet.TelnetHandler</code></p>
+<p><code>org.apache.dubbo.remoting.telnet.TelnetHandler</code></p>
<h2>扩展配置</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">telnet</span>=<span class="hljs-string">"xxx,yyy"</span> /></span>
<span class="hljs-comment"><!-- 缺省值设置,当<dubbo:protocol>没有配置telnet属性时,使用此配置 --></span>
@@ -24,17 +24,17 @@
</code></pre>
<h2>已知扩展</h2>
<ul>
-<li><code>com.alibaba.dubbo.remoting.telnet.support.ClearTelnetHandler</code></li>
-<li><code>com.alibaba.dubbo.remoting.telnet.support.ExitTelnetHandler</code></li>
-<li><code>com.alibaba.dubbo.remoting.telnet.support.HelpTelnetHandler</code></li>
-<li><code>com.alibaba.dubbo.remoting.telnet.support.StatusTelnetHandler</code></li>
-<li><code>com.alibaba.dubbo.rpc.dubbo.telnet.ListTelnetHandler</code></li>
-<li><code>com.alibaba.dubbo.rpc.dubbo.telnet.ChangeTelnetHandler</code></li>
-<li><code>com.alibaba.dubbo.rpc.dubbo.telnet.CurrentTelnetHandler</code></li>
-<li><code>com.alibaba.dubbo.rpc.dubbo.telnet.InvokeTelnetHandler</code></li>
-<li><code>com.alibaba.dubbo.rpc.dubbo.telnet.TraceTelnetHandler</code></li>
-<li><code>com.alibaba.dubbo.rpc.dubbo.telnet.CountTelnetHandler</code></li>
-<li><code>com.alibaba.dubbo.rpc.dubbo.telnet.PortTelnetHandler</code></li>
+<li><code>org.apache.dubbo.remoting.telnet.support.ClearTelnetHandler</code></li>
+<li><code>org.apache.dubbo.remoting.telnet.support.ExitTelnetHandler</code></li>
+<li><code>org.apache.dubbo.remoting.telnet.support.HelpTelnetHandler</code></li>
+<li><code>org.apache.dubbo.remoting.telnet.support.StatusTelnetHandler</code></li>
+<li><code>org.apache.dubbo.rpc.dubbo.telnet.ListTelnetHandler</code></li>
+<li><code>org.apache.dubbo.rpc.dubbo.telnet.ChangeTelnetHandler</code></li>
+<li><code>org.apache.dubbo.rpc.dubbo.telnet.CurrentTelnetHandler</code></li>
+<li><code>org.apache.dubbo.rpc.dubbo.telnet.InvokeTelnetHandler</code></li>
+<li><code>org.apache.dubbo.rpc.dubbo.telnet.TraceTelnetHandler</code></li>
+<li><code>org.apache.dubbo.rpc.dubbo.telnet.CountTelnetHandler</code></li>
+<li><code>org.apache.dubbo.rpc.dubbo.telnet.PortTelnetHandler</code></li>
</ul>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
@@ -47,12 +47,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.remoting.telnet.TelnetHandler (纯文本文件,内容为:xxx=com.xxx.XxxTelnetHandler)
+ |-org.apache.dubbo.remoting.telnet.TelnetHandler (纯文本文件,内容为:xxx=com.xxx.XxxTelnetHandler)
</code></pre>
<p>XxxTelnetHandler.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.remoting.telnet.TelnetHandler;
+<span class="hljs-keyword">import</span> org.apache.dubbo.remoting.telnet.TelnetHandler;
<span class="hljs-meta">@Help</span>(parameter=<span class="hljs-string">"..."</span>, summary=<span class="hljs-string">"..."</span>, detail=<span class="hljs-string">"..."</span>)
@@ -62,7 +62,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.remoting.telnet.TelnetHandler:</p>
+<p>META-INF/dubbo/org.apache.dubbo.remoting.telnet.TelnetHandler:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxTelnetHandler</span>
</code></pre>
<h2>用法</h2>
diff --git a/zh-cn/docs/dev/impls/telnet-handler.json b/zh-cn/docs/dev/impls/telnet-handler.json
index 10dc31f..dc7a529 100644
--- a/zh-cn/docs/dev/impls/telnet-handler.json
+++ b/zh-cn/docs/dev/impls/telnet-handler.json
@@ -1,6 +1,6 @@
{
"filename": "telnet-handler.md",
- "__html": "<h1>Telnet 命令扩展</h1>\n<h2>扩展说明</h2>\n<p>所有服务器均支持 telnet 访问,用于人工干预。</p>\n<h2>扩展接口</h2>\n<p><code>com.alibaba.dubbo.remoting.telnet.TelnetHandler</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">telnet</span>=<span class=\"hljs-string\">\"xxx,yyy\"</span> /></span>\n<span class=\"hljs-comment\"><!-- 缺省值设置,当<dubbo:protocol>没有配置telnet属性时,使用此配置 --></sp [...]
+ "__html": "<h1>Telnet 命令扩展</h1>\n<h2>扩展说明</h2>\n<p>所有服务器均支持 telnet 访问,用于人工干预。</p>\n<h2>扩展接口</h2>\n<p><code>org.apache.dubbo.remoting.telnet.TelnetHandler</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">telnet</span>=<span class=\"hljs-string\">\"xxx,yyy\"</span> /></span>\n<span class=\"hljs-comment\"><!-- 缺省值设置,当<dubbo:protocol>没有配置telnet属性时,使用此配置 --></spa [...]
"link": "/zh-cn/docs/dev/impls/telnet-handler.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/threadpool.html b/zh-cn/docs/dev/impls/threadpool.html
index 5d78036..c36f44c 100644
--- a/zh-cn/docs/dev/impls/threadpool.html
+++ b/zh-cn/docs/dev/impls/threadpool.html
@@ -16,7 +16,7 @@
<h2>扩展说明</h2>
<p>服务提供方线程程实现策略,当服务器收到一个请求时,需要在线程池中创建一个线程去执行服务提供方业务逻辑。</p>
<h2>扩展接口</h2>
-<p><code>com.alibaba.dubbo.common.threadpool.ThreadPool</code></p>
+<p><code>org.apache.dubbo.common.threadpool.ThreadPool</code></p>
<h2>扩展配置</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:protocol</span> <span class="hljs-attr">threadpool</span>=<span class="hljs-string">"xxx"</span> /></span>
<span class="hljs-comment"><!-- 缺省值设置,当<dubbo:protocol>没有配置threadpool时,使用此配置 --></span>
@@ -24,8 +24,8 @@
</code></pre>
<h2>已知扩展</h2>
<ul>
-<li><code>com.alibaba.dubbo.common.threadpool.FixedThreadPool</code></li>
-<li><code>com.alibaba.dubbo.common.threadpool.CachedThreadPool</code></li>
+<li><code>org.apache.dubbo.common.threadpool.FixedThreadPool</code></li>
+<li><code>org.apache.dubbo.common.threadpool.CachedThreadPool</code></li>
</ul>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
@@ -38,12 +38,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.common.threadpool.ThreadPool (纯文本文件,内容为:xxx=com.xxx.XxxThreadPool)
+ |-org.apache.dubbo.common.threadpool.ThreadPool (纯文本文件,内容为:xxx=com.xxx.XxxThreadPool)
</code></pre>
<p>XxxThreadPool.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.threadpool.ThreadPool;
+<span class="hljs-keyword">import</span> org.apache.dubbo.common.threadpool.ThreadPool;
<span class="hljs-keyword">import</span> java.util.concurrent.Executor;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxThreadPool</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">ThreadPool</span> </span>{
@@ -52,7 +52,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.common.threadpool.ThreadPool:</p>
+<p>META-INF/dubbo/org.apache.dubbo.common.threadpool.ThreadPool:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxThreadPool</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/threadpool.json b/zh-cn/docs/dev/impls/threadpool.json
index e5a508a..9fd33a3 100644
--- a/zh-cn/docs/dev/impls/threadpool.json
+++ b/zh-cn/docs/dev/impls/threadpool.json
@@ -1,6 +1,6 @@
{
"filename": "threadpool.md",
- "__html": "<h1>线程池扩展</h1>\n<h2>扩展说明</h2>\n<p>服务提供方线程程实现策略,当服务器收到一个请求时,需要在线程池中创建一个线程去执行服务提供方业务逻辑。</p>\n<h2>扩展接口</h2>\n<p><code>com.alibaba.dubbo.common.threadpool.ThreadPool</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">threadpool</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n<span class=\"hljs-comment\"><!-- 缺省值设置,当<dubbo:protocol>没有配置threadpo [...]
+ "__html": "<h1>线程池扩展</h1>\n<h2>扩展说明</h2>\n<p>服务提供方线程程实现策略,当服务器收到一个请求时,需要在线程池中创建一个线程去执行服务提供方业务逻辑。</p>\n<h2>扩展接口</h2>\n<p><code>org.apache.dubbo.common.threadpool.ThreadPool</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:protocol</span> <span class=\"hljs-attr\">threadpool</span>=<span class=\"hljs-string\">\"xxx\"</span> /></span>\n<span class=\"hljs-comment\"><!-- 缺省值设置,当<dubbo:protocol>没有配置threadpoo [...]
"link": "/zh-cn/docs/dev/impls/threadpool.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/impls/validation.html b/zh-cn/docs/dev/impls/validation.html
index 6438553..a5ed828 100644
--- a/zh-cn/docs/dev/impls/validation.html
+++ b/zh-cn/docs/dev/impls/validation.html
@@ -16,14 +16,14 @@
<h2>扩展说明</h2>
<p>参数验证扩展点。</p>
<h2>扩展接口</h2>
-<p><code>com.alibaba.dubbo.validation.Validation</code></p>
+<p><code>org.apache.dubbo.validation.Validation</code></p>
<h2>扩展配置</h2>
<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:service</span> <span class="hljs-attr">validation</span>=<span class="hljs-string">"xxx,yyy"</span> /></span>
<span class="hljs-comment"><!-- 缺省值设置,当<dubbo:service>没有配置validation属性时,使用此配置 --></span>
<span class="hljs-tag"><<span class="hljs-name">dubbo:provider</span> <span class="hljs-attr">validation</span>=<span class="hljs-string">"xxx,yyy"</span> /></span>
</code></pre>
<h2>已知扩展</h2>
-<p><code>com.alibaba.dubbo.validation.support.jvalidation.JValidation</code></p>
+<p><code>org.apache.dubbo.validation.support.jvalidation.JValidation</code></p>
<h2>扩展示例</h2>
<p>Maven 项目结构:</p>
<pre><code>src
@@ -35,12 +35,12 @@
|-resources
|-META-INF
|-dubbo
- |-com.alibaba.dubbo.validation.Validation (纯文本文件,内容为:xxx=com.xxx.XxxValidation)
+ |-org.apache.dubbo.validation.Validation (纯文本文件,内容为:xxx=com.xxx.XxxValidation)
</code></pre>
<p>XxxValidation.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.validation.Validation;
+<span class="hljs-keyword">import</span> org.apache.dubbo.validation.Validation;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxValidation</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Validation</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> Object <span class="hljs-title">getValidator</span><span class="hljs-params">(URL url)</span> </span>{
@@ -51,7 +51,7 @@
<p>XxxValidator.java:</p>
<pre><code class="language-java"><span class="hljs-keyword">package</span> com.xxx;
-<span class="hljs-keyword">import</span> com.alibaba.dubbo.validation.Validator;
+<span class="hljs-keyword">import</span> org.apache.dubbo.validation.Validator;
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">XxxValidator</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Validator</span> </span>{
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">XxxValidator</span><span class="hljs-params">(URL url)</span> </span>{
@@ -62,7 +62,7 @@
}
}
</code></pre>
-<p>META-INF/dubbo/com.alibaba.dubbo.validation.Validation:</p>
+<p>META-INF/dubbo/org.apache.dubbo.validation.Validation:</p>
<pre><code class="language-properties"><span class="hljs-attr">xxx</span>=<span class="hljs-string">com.xxx.XxxValidation</span>
</code></pre>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
diff --git a/zh-cn/docs/dev/impls/validation.json b/zh-cn/docs/dev/impls/validation.json
index 52cb8af..343827f 100644
--- a/zh-cn/docs/dev/impls/validation.json
+++ b/zh-cn/docs/dev/impls/validation.json
@@ -1,6 +1,6 @@
{
"filename": "validation.md",
- "__html": "<h1>验证扩展</h1>\n<h2>扩展说明</h2>\n<p>参数验证扩展点。</p>\n<h2>扩展接口</h2>\n<p><code>com.alibaba.dubbo.validation.Validation</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:service</span> <span class=\"hljs-attr\">validation</span>=<span class=\"hljs-string\">\"xxx,yyy\"</span> /></span>\n<span class=\"hljs-comment\"><!-- 缺省值设置,当<dubbo:service>没有配置validation属性时,使用此配置 --></span>\n<span class=\"hljs-tag [...]
+ "__html": "<h1>验证扩展</h1>\n<h2>扩展说明</h2>\n<p>参数验证扩展点。</p>\n<h2>扩展接口</h2>\n<p><code>org.apache.dubbo.validation.Validation</code></p>\n<h2>扩展配置</h2>\n<pre><code class=\"language-xml\"><span class=\"hljs-tag\"><<span class=\"hljs-name\">dubbo:service</span> <span class=\"hljs-attr\">validation</span>=<span class=\"hljs-string\">\"xxx,yyy\"</span> /></span>\n<span class=\"hljs-comment\"><!-- 缺省值设置,当<dubbo:service>没有配置validation属性时,使用此配置 --></span>\n<span class=\"hljs-tag\ [...]
"link": "/zh-cn/docs/dev/impls/validation.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/dev/principals/extension.html b/zh-cn/docs/dev/principals/extension.html
index 0d6c175..6c0eee4 100644
--- a/zh-cn/docs/dev/principals/extension.html
+++ b/zh-cn/docs/dev/principals/extension.html
@@ -25,7 +25,7 @@
<p>即然要扩展,扩展点的加载方式,首先要统一,微核心+插件式,是比较能达到 OCP 原则的思路。</p>
<p>由一个插件生命周期管理容器,构成微核心,核心不包括任何功能,这样可以确保所有功能都能被替换,并且,框架作者能做到的功能,扩展者也一定要能做到,以保证平等对待第三方,所以,框架自身的功能也要用插件的方式实现,不能有任何硬编码。</p>
<p>通常微核心都会采用 Factory、IoC、OSGi 等方式管理插件生命周期。考虑 Dubbo 的适用面,不想强依赖 Spring 等 IoC 容器。自已造一个小的 IoC 容器,也觉得有点过度设计,所以打算采用最简单的 Factory 方式管理插件。</p>
-<p>最终决定采用的是 JDK 标准的 SPI 扩展机制,参见:<code>java.util.ServiceLoader</code>,也就是扩展者在 jar 包的 <code>META-INF/services/</code> 目录下放置与接口同名的文本文件,内容为接口实现类名,多个实现类名用换行符分隔。比如,需要扩展 Dubbo 的协议,只需在 xxx.jar 中放置文件:<code>META-INF/services/com.alibaba.dubbo.rpc.Protocol</code>,内容为 <code>com.alibaba.xxx.XxxProtocol</code>。Dubbo 通过 ServiceLoader 扫描到所有 Protocol 实现。</p>
+<p>最终决定采用的是 JDK 标准的 SPI 扩展机制,参见:<code>java.util.ServiceLoader</code>,也就是扩展者在 jar 包的 <code>META-INF/services/</code> 目录下放置与接口同名的文本文件,内容为接口实现类名,多个实现类名用换行符分隔。比如,需要扩展 Dubbo 的协议,只需在 xxx.jar 中放置文件:<code>META-INF/services/org.apache.dubbo.rpc.Protocol</code>,内容为 <code>com.alibaba.xxx.XxxProtocol</code>。Dubbo 通过 ServiceLoader 扫描到所有 Protocol 实现。</p>
<p>并约定所有插件,都必须标注:<code>@Extension("name")</code>,作为加载后的标识性名称,用于配置选择。</p>
<h2>第二步,每个扩展点只封装一个变化因子,最大化复用</h2>
<p>每个扩展点的实现者,往往都只是关心一件事,现在的扩展点,并没有完全分离。比如:Failover, Route, LoadBalance, Directory 没有完全分开,全由 RoutingInvokerGroup 写死了。</p>
diff --git a/zh-cn/docs/dev/principals/extension.json b/zh-cn/docs/dev/principals/extension.json
index fad112b..d1b5ea6 100644
--- a/zh-cn/docs/dev/principals/extension.json
+++ b/zh-cn/docs/dev/principals/extension.json
@@ -1,6 +1,6 @@
{
"filename": "extension.md",
- "__html": "<h1>扩展点重构</h1>\n<blockquote>\n<p><a href=\"http://javatar.iteye.com/blog/1041832\">http://javatar.iteye.com/blog/1041832</a></p>\n</blockquote>\n<p>随着服务化的推广,网站对Dubbo服务框架的需求逐渐增多,Dubbo 的现有开发人员能实现的需求有限,很多需求都被 delay,而网站的同学也希望参与进来,加上领域的推动,所以平台计划将部分项目对公司内部开放,让大家一起来实现,Dubbo 为试点项目之一。</p>\n<p>既然要开放,那 Dubbo 就要留一些扩展点,让参与者尽量黑盒扩展,而不是白盒的修改代码,否则分支,质量,合并,冲突都会很难管理。</p>\n<p>先看一下 Dubbo 现有的设计:</p>\n<p><img src=\"../sources/images/design-step1.png\" alt=\"design-step-1\"></p>\n<p>这里面虽然有部分扩展接口,但并 [...]
+ "__html": "<h1>扩展点重构</h1>\n<blockquote>\n<p><a href=\"http://javatar.iteye.com/blog/1041832\">http://javatar.iteye.com/blog/1041832</a></p>\n</blockquote>\n<p>随着服务化的推广,网站对Dubbo服务框架的需求逐渐增多,Dubbo 的现有开发人员能实现的需求有限,很多需求都被 delay,而网站的同学也希望参与进来,加上领域的推动,所以平台计划将部分项目对公司内部开放,让大家一起来实现,Dubbo 为试点项目之一。</p>\n<p>既然要开放,那 Dubbo 就要留一些扩展点,让参与者尽量黑盒扩展,而不是白盒的修改代码,否则分支,质量,合并,冲突都会很难管理。</p>\n<p>先看一下 Dubbo 现有的设计:</p>\n<p><img src=\"../sources/images/design-step1.png\" alt=\"design-step-1\"></p>\n<p>这里面虽然有部分扩展接口,但并 [...]
"link": "/zh-cn/docs/dev/principals/extension.html",
"meta": {}
}
\ No newline at end of file
diff --git a/zh-cn/docs/source_code_guide/adaptive-extension.html b/zh-cn/docs/source_code_guide/adaptive-extension.html
new file mode 100644
index 0000000..ce6c131
--- /dev/null
+++ b/zh-cn/docs/source_code_guide/adaptive-extension.html
@@ -0,0 +1,697 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <meta name="keywords" content="Dubbo, SPI, Adaptive Extension" />
+ <meta name="description" content="本文介绍了自适应拓展的原理和实现细节" />
+ <!-- 网页标签标题 -->
+ <title>SPI 自适应拓展</title>
+ <link rel="shortcut icon" href="/img/dubbo.ico"/>
+ <link rel="stylesheet" href="/build/documentation.css" />
+</head>
+<body>
+ <div id="root"><div class="documentation-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a [...]
+<p>在 Dubbo 中,很多拓展都是通过 SPI 机制进行加载的,比如 Protocol、Cluster、LoadBalance 等。有时,有些拓展并不想在框架启动阶段被加载,而是希望在拓展方法被调用时,根据运行时参数进行加载。这听起来有些矛盾。拓展未被加载,那么拓展方法就无法被调用(静态方法除外)。拓展方法未被调用,拓展就无法被加载。对于这个矛盾的问题,Dubbo 通过自适应拓展机制很好的解决了。自适应拓展机制的实现逻辑比较复杂,首先 Dubbo 会为拓展接口生成具有代理功能的代码。然后通过 javassist 或 jdk 编译这段代码,得到 Class 类。最后再通过反射创建代理类,整个过程比较复杂。为了让大家对自适应拓展有一个感性的认识,下面我们通过一个示例进行演示。这是一个与汽车相关的例子,我们有一个车轮制造厂接口 WheelMaker:</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">WheelMaker</span> </span>{
+ <span class="hljs-function">Wheel <span class="hljs-title">makeWheel</span><span class="hljs-params">(URL url)</span></span>;
+}
+</code></pre>
+<p>WheelMaker 接口的自适应实现类如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AdaptiveWheelMaker</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">WheelMaker</span> </span>{
+ <span class="hljs-function"><span class="hljs-keyword">public</span> Wheel <span class="hljs-title">makeWheel</span><span class="hljs-params">(URL url)</span> </span>{
+ <span class="hljs-keyword">if</span> (url == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"url == null"</span>);
+ }
+
+ <span class="hljs-comment">// 1.从 URL 中获取 WheelMaker 名称</span>
+ String wheelMakerName = url.getParameter(<span class="hljs-string">"Wheel.maker"</span>);
+ <span class="hljs-keyword">if</span> (name == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"wheelMakerName == null"</span>);
+ }
+
+ <span class="hljs-comment">// 2.通过 SPI 加载具体的 WheelMaker</span>
+ WheelMaker wheelMaker = ExtensionLoader
+ .getExtensionLoader(WheelMaker.class).getExtension(wheelMakerName);
+
+ <span class="hljs-comment">// 3.调用目标方法</span>
+ <span class="hljs-keyword">return</span> wheelMaker.makeWheel(URL url);
+ }
+}
+</code></pre>
+<p>AdaptiveWheelMaker 是一个代理类,与传统的代理逻辑不同,AdaptiveWheelMaker 所代理的对象是在 makeWheel 方法中通过 SPI 加载得到的。makeWheel 方法主要做了三件事情:</p>
+<ol>
+<li>从 URL 中获取 WheelMaker 名称</li>
+<li>通过 SPI 加载具体的 WheelMaker 实现类</li>
+<li>调用目标方法</li>
+</ol>
+<p>接下来,我们来看看汽车制造厂 CarMaker 接口与其实现类。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">CarMaker</span> </span>{
+ <span class="hljs-function">Car <span class="hljs-title">makeCar</span><span class="hljs-params">(URL url)</span></span>;
+}
+
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RaceCarMaker</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">CarMaker</span> </span>{
+ WheelMaker wheelMaker;
+
+ <span class="hljs-comment">// 通过 setter 注入 AdaptiveWheelMaker</span>
+ <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">setWheelMaker</span><span class="hljs-params">(WheelMaker wheelMaker)</span> </span>{
+ <span class="hljs-keyword">this</span>.wheelMaker = wheelMaker;
+ }
+
+ <span class="hljs-function"><span class="hljs-keyword">public</span> Car <span class="hljs-title">makeCar</span><span class="hljs-params">(URL url)</span> </span>{
+ Wheel wheel = wheelMaker.makeWheel(url);
+ <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> RaceCar(wheel, ...);
+ }
+}
+</code></pre>
+<p>RaceCarMaker 持有一个 WheelMaker 类型的成员变量,在程序启动时,我们可以将 AdaptiveWheelMaker 通过 setter 方法注入到 RaceCarMaker 中。在运行时,假设有这样一个 url 参数传入:</p>
+<pre><code class="language-url">dubbo://192.168.0.101:20880/XxxService?wheel.maker=MichelinWheelMaker
+</code></pre>
+<p>RaceCarMaker 的 makeCar 方法将上面的 url 作为参数传给 AdaptiveWheelMaker 的 makeWheel 方法,makeWheel 方法从 url 中提取 wheel.maker 参数,得到 MichelinWheelMaker。之后再通过 SPI 加载配置名为 MichelinWheelMaker 的实现类,得到具体的 WheelMaker 实例。</p>
+<p>上面的示例展示了自适应拓展类的核心实现 ---- 在拓展接口的方法被调用时,通过 SPI 加载具体的拓展实现类,并调用拓展对象的同名方法。接下来,我们深入到源码中,探索自适应拓展类生成的过程。</p>
+<h2>2.源码分析</h2>
+<p>在对自适应拓展生成过程进行深入分析之前,我们先来看一下与自适应拓展息息相关的一个注解,即 Adaptive 注解。该注解的定义如下:</p>
+<pre><code class="language-java"><span class="hljs-meta">@Documented</span>
+<span class="hljs-meta">@Retention</span>(RetentionPolicy.RUNTIME)
+<span class="hljs-meta">@Target</span>({ElementType.TYPE, ElementType.METHOD})
+<span class="hljs-keyword">public</span> <span class="hljs-meta">@interface</span> Adaptive {
+ String[] value() <span class="hljs-keyword">default</span> {};
+}
+</code></pre>
+<p>从上面的代码中可知,Adaptive 可注解在类或方法上。当 Adaptive 注解在类上时,Dubbo 不会为该类生成代理类。注解在方法(接口方法)上时,Dubbo 则会为该方法生成代理逻辑。Adaptive 注解在类上的情况很少,在 Dubbo 中,仅有两个类被 Adaptive 注解了,分别是 AdaptiveCompiler 和 AdaptiveExtensionFactory。此种情况,表示拓展的加载逻辑由人工编码完成。更多时候,Adaptive 是注解在接口方法上的,表示拓展的加载逻辑需由框架自动生成。Adaptive 注解的地方不同,相应的处理逻辑也是不同的。注解在类上时,处理逻辑比较简单,本文就不分析了。注解在接口方法上时,处理逻辑较为复杂,本章将会重点分析此块逻辑。</p>
+<h3>2.1 获取自适应拓展</h3>
+<p>getAdaptiveExtension 方法是获取自适应拓展的入口方法,因此下面我们从这个方法进行分析。相关代码如下:</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">public</span> T <span class="hljs-title">getAdaptiveExtension</span><span class="hljs-params">()</span> </span>{
+ <span class="hljs-comment">// 从缓存中获取自适应拓展</span>
+ Object instance = cachedAdaptiveInstance.get();
+ <span class="hljs-keyword">if</span> (instance == <span class="hljs-keyword">null</span>) { <span class="hljs-comment">// 缓存未命中</span>
+ <span class="hljs-keyword">if</span> (createAdaptiveInstanceError == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">synchronized</span> (cachedAdaptiveInstance) {
+ instance = cachedAdaptiveInstance.get();
+ <span class="hljs-keyword">if</span> (instance == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-comment">// 创建自适应拓展</span>
+ instance = createAdaptiveExtension();
+ <span class="hljs-comment">// 设置自适应拓展到缓存中</span>
+ cachedAdaptiveInstance.set(instance);
+ } <span class="hljs-keyword">catch</span> (Throwable t) {
+ createAdaptiveInstanceError = t;
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"fail to create adaptive instance: ..."</span>);
+ }
+ }
+ }
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"fail to create adaptive instance: ..."</span>);
+ }
+ }
+
+ <span class="hljs-keyword">return</span> (T) instance;
+}
+</code></pre>
+<p>getAdaptiveExtension 方法首先会检查缓存,缓存未命中,则调用 createAdaptiveExtension 方法创建自适应拓展。下面,我们看一下 createAdaptiveExtension 方法的代码。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">private</span> T <span class="hljs-title">createAdaptiveExtension</span><span class="hljs-params">()</span> </span>{
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-comment">// 获取自适应拓展类,并通过反射实例化</span>
+ <span class="hljs-keyword">return</span> injectExtension((T) getAdaptiveExtensionClass().newInstance());
+ } <span class="hljs-keyword">catch</span> (Exception e) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"Can not create adaptive extension ..."</span>);
+ }
+}
+</code></pre>
+<p>createAdaptiveExtension 方法的代码比较少,但却包含了三个逻辑,分别如下:</p>
+<ol>
+<li>调用 getAdaptiveExtensionClass 方法获取自适应拓展 Class 对象</li>
+<li>通过反射进行实例化</li>
+<li>调用 injectExtension 方法向拓展实例中注入依赖</li>
+</ol>
+<p>前两个逻辑比较好理解,第三个逻辑用于向自适应拓展对象中注入依赖。这个逻辑看似多余,但有存在的必要,这里简单说明一下。前面说过,Dubbo 中有两种类型的自适应拓展,一种是手工编码的,一种是自动生成的。手工编码的自适应拓展中可能存在着一些依赖,而自动生成的 Adaptive 拓展则不会依赖其他类。这里调用 injectExtension 方法的目的是为手工编码的自适应拓展注入依赖,这一点需要大家注意一下。关于 injectExtension 方法,前文已经分析过了,这里不再赘述。接下来,分析 getAdaptiveExtensionClass 方法的逻辑。</p>
+<pre><code class="language-java"><span class="hljs-keyword">private</span> Class<?> getAdaptiveExtensionClass() {
+ <span class="hljs-comment">// 通过 SPI 获取所有的拓展类</span>
+ getExtensionClasses();
+ <span class="hljs-comment">// 检查缓存,若缓存不为空,则直接返回缓存</span>
+ <span class="hljs-keyword">if</span> (cachedAdaptiveClass != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">return</span> cachedAdaptiveClass;
+ }
+ <span class="hljs-comment">// 创建自适应拓展类</span>
+ <span class="hljs-keyword">return</span> cachedAdaptiveClass = createAdaptiveExtensionClass();
+}
+</code></pre>
+<p>getAdaptiveExtensionClass 方法同样包含了三个逻辑,如下:</p>
+<ol>
+<li>调用 getExtensionClasses 获取所有的拓展类</li>
+<li>检查缓存,若缓存不为空,则返回缓存</li>
+<li>若缓存为空,则调用 createAdaptiveExtensionClass 创建自适应拓展类</li>
+</ol>
+<p>这三个逻辑看起来平淡无奇,似乎没有多讲的必要。但是这些平淡无奇的代码中隐藏了着一些细节,需要说明一下。首先从第一个逻辑说起,getExtensionClasses 这个方法用于获取某个接口的所有实现类。比如该方法可以获取 Protocol 接口的 DubboProtocol、HttpProtocol、InjvmProtocol 等实现类。在获取实现类的过程中,如果某个某个实现类被 Adaptive 注解修饰了,那么该类就会被赋值给 cachedAdaptiveClass 变量。此时,上面步骤中的第二步条件成立(缓存不为空),直接返回 cachedAdaptiveClass 即可。如果所有的实现类均未被 Adaptive 注解修饰,那么执行第三步逻辑,创建自适应拓展类。相关代码如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">private</span> Class<?> createAdaptiveExtensionClass() {
+ <span class="hljs-comment">// 构建自适应拓展代码</span>
+ String code = createAdaptiveExtensionClassCode();
+ ClassLoader classLoader = findClassLoader();
+ <span class="hljs-comment">// 获取编译器实现类</span>
+ com.alibaba.dubbo.common.compiler.Compiler compiler = ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.common.compiler.Compiler.class).getAdaptiveExtension();
+ <span class="hljs-comment">// 编译代码,生成 Class</span>
+ <span class="hljs-keyword">return</span> compiler.compile(code, classLoader);
+}
+</code></pre>
+<p>createAdaptiveExtensionClass 方法用于生成自适应拓展类,该方法首先会生成自适应拓展类的源码,然后通过 Compiler 实例(Dubbo 默认使用 javassist 作为编译器)编译源码,得到代理类 Class 实例。接下来,我们把重点放在代理类代码生成的逻辑上,其他逻辑大家自行分析。</p>
+<h3>2.2 自适应拓展类代码生成</h3>
+<p>createAdaptiveExtensionClassCode 方法代码略多,约有两百行代码。因此本节将会对该方法的代码进行拆分分析,以帮助大家更好的理解代码逻辑。</p>
+<h4>2.2.1 Adaptive 注解检测</h4>
+<p>在生成代理类源码之前,createAdaptiveExtensionClassCode 方法首先会通过反射检测接口方法是否包含 Adaptive 注解。对于要生成自适应拓展的接口,Dubbo 要求该接口至少有一个方法被 Adaptive 注解修饰。若不满足此条件,就会抛出运行时异常。相关代码如下:</p>
+<pre><code class="language-java"><span class="hljs-comment">// 通过反射获取所有的方法</span>
+Method[] methods = type.getMethods();
+<span class="hljs-keyword">boolean</span> hasAdaptiveAnnotation = <span class="hljs-keyword">false</span>;
+<span class="hljs-comment">// 遍历方法列表</span>
+<span class="hljs-keyword">for</span> (Method m : methods) {
+ <span class="hljs-comment">// 检测方法上是否有 Adaptive 注解</span>
+ <span class="hljs-keyword">if</span> (m.isAnnotationPresent(Adaptive.class)) {
+ hasAdaptiveAnnotation = <span class="hljs-keyword">true</span>;
+ <span class="hljs-keyword">break</span>;
+ }
+}
+
+<span class="hljs-keyword">if</span> (!hasAdaptiveAnnotation)
+ <span class="hljs-comment">// 若所有的方法上均无 Adaptive 注解,则抛出异常</span>
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"No adaptive method on extension ..."</span>);
+</code></pre>
+<h4>2.2.2 生成类</h4>
+<p>通过 Adaptive 注解检测后,即可开始生成代码。代码生成的顺序与 Java 文件内容顺序一致,首先会生成 package 语句,然后生成 import 语句,紧接着生成类名等代码。整个逻辑如下:</p>
+<pre><code class="language-java"><span class="hljs-comment">// 生成 package 代码:package + type 所在包</span>
+codeBuilder.append(<span class="hljs-string">"package "</span>).append(type.getPackage().getName()).append(<span class="hljs-string">";"</span>);
+<span class="hljs-comment">// 生成 import 代码:import + ExtensionLoader 全限定名</span>
+codeBuilder.append(<span class="hljs-string">"\nimport "</span>).append(ExtensionLoader.class.getName()).append(<span class="hljs-string">";"</span>);
+<span class="hljs-comment">// 生成类代码:public class + type简单名称 + $Adaptive + implements + type全限定名 + {</span>
+codeBuilder.append(<span class="hljs-string">"\npublic class "</span>)
+ .append(type.getSimpleName())
+ .append(<span class="hljs-string">"$Adaptive"</span>)
+ .append(<span class="hljs-string">" implements "</span>)
+ .append(type.getCanonicalName())
+ .append(<span class="hljs-string">" {"</span>);
+
+<span class="hljs-comment">// ${生成方法}</span>
+
+codeBuilder.append(<span class="hljs-string">"\n}"</span>);
+</code></pre>
+<p>这里使用 ${...} 占位符代表其他代码的生成逻辑,该部分逻辑将在随后进行分析。上面代码不是很难理解,下面直接通过一个例子展示该段代码所生成的内容。以 Dubbo 的 Protocol 接口为例,生成的代码如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">package</span> com.alibaba.dubbo.rpc;
+<span class="hljs-keyword">import</span> com.alibaba.dubbo.common.extension.ExtensionLoader;
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Protocol</span>$<span class="hljs-title">Adaptive</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">com</span>.<span class="hljs-title">alibaba</span>.<span class="hljs-title">dubbo</span>.<span class="hljs-title">rpc</span>.<span class="hljs-title">Protocol</span> </span>{
+ <span class="hljs-comment">// 省略方法代码</span>
+}
+</code></pre>
+<h4>2.2.3 生成方法</h4>
+<p>一个方法可以被 Adaptive 注解修饰,也可以不被修饰。这里将未被 Adaptive 注解修饰的方法称为“无 Adaptive 注解方法”,下面我们先来看看此种方法的代码生成逻辑是怎样的。</p>
+<h5>2.2.3.1 无 Adaptive 注解方法代码生成逻辑</h5>
+<p>对于接口方法,我们可以按照需求标注 Adaptive 注解。以 Protocol 接口为例,该接口的 destroy 和 getDefaultPort 未标注 Adaptive 注解,其他方法均标注了 Adaptive 注解。Dubbo 不会为没有标注 Adaptive 注解的方法生成代理逻辑,对于该种类型的方法,仅会生成一句抛出异常的代码。生成逻辑如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">for</span> (Method method : methods) {
+
+ <span class="hljs-comment">// 省略无关逻辑</span>
+
+ Adaptive adaptiveAnnotation = method.getAnnotation(Adaptive.class);
+ StringBuilder code = <span class="hljs-keyword">new</span> StringBuilder(<span class="hljs-number">512</span>);
+ <span class="hljs-comment">// 如果方法上无 Adaptive 注解,则生成 throw new UnsupportedOperationException(...) 代码</span>
+ <span class="hljs-keyword">if</span> (adaptiveAnnotation == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 生成的代码格式如下:</span>
+ <span class="hljs-comment">// throw new UnsupportedOperationException(</span>
+ <span class="hljs-comment">// "method " + 方法签名 + of interface + 全限定接口名 + is not adaptive method!”)</span>
+ code.append(<span class="hljs-string">"throw new UnsupportedOperationException(\"method "</span>)
+ .append(method.toString()).append(<span class="hljs-string">" of interface "</span>)
+ .append(type.getName()).append(<span class="hljs-string">" is not adaptive method!\");"</span>);
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-comment">// 省略无关逻辑</span>
+ }
+
+ <span class="hljs-comment">// 省略无关逻辑</span>
+}
+</code></pre>
+<p>以 Protocol 接口的 destroy 方法为例,上面代码生成的内容如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> UnsupportedOperationException(
+ <span class="hljs-string">"method public abstract void com.alibaba.dubbo.rpc.Protocol.destroy() of interface com.alibaba.dubbo.rpc.Protocol is not adaptive method!"</span>);
+</code></pre>
+<h5>2.2.3.2 获取 URL 数据</h5>
+<p>前面说过方法代理逻辑会从 URL 中提取目标拓展的名称,因此代码生成逻辑的一个重要的任务是从方法的参数列表或者其他参数中获取 URL 数据。举例说明一下,我们要为 Protocol 接口的 refer 和 export 方法生成代理逻辑。在运行时,通过反射得到的方法定义大致如下:</p>
+<pre><code class="language-java"><span class="hljs-function">Invoker <span class="hljs-title">refer</span><span class="hljs-params">(Class<T> arg0, URL arg1)</span> <span class="hljs-keyword">throws</span> RpcException</span>;
+<span class="hljs-function">Exporter <span class="hljs-title">export</span><span class="hljs-params">(Invoker<T> arg0)</span> <span class="hljs-keyword">throws</span> RpcException</span>;
+</code></pre>
+<p>对于 refer 方法,通过遍历 refer 的参数列表即可获取 URL 数据,这个还比较简单。对于 export 方法,获取 URL 数据则要麻烦一些。export 参数列表中没有 URL 参数,因此需要从 Invoker 参数中获取 URL 数据。获取方式是调用 Invoker 中可返回 URL 的 getter 方法,比如 getUrl。如果 Invoker 中无相关 getter 方法,此时则会抛出异常。整个逻辑如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">for</span> (Method method : methods) {
+ Class<?> rt = method.getReturnType();
+ Class<?>[] pts = method.getParameterTypes();
+ Class<?>[] ets = method.getExceptionTypes();
+
+ Adaptive adaptiveAnnotation = method.getAnnotation(Adaptive.class);
+ StringBuilder code = <span class="hljs-keyword">new</span> StringBuilder(<span class="hljs-number">512</span>);
+ <span class="hljs-keyword">if</span> (adaptiveAnnotation == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// ${无 Adaptive 注解方法代码生成逻辑}</span>
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-keyword">int</span> urlTypeIndex = -<span class="hljs-number">1</span>;
+ <span class="hljs-comment">// 遍历参数列表,确定 URL 参数位置</span>
+ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < pts.length; ++i) {
+ <span class="hljs-keyword">if</span> (pts[i].equals(URL.class)) {
+ urlTypeIndex = i;
+ <span class="hljs-keyword">break</span>;
+ }
+ }
+
+ <span class="hljs-comment">// urlTypeIndex != -1,表示参数列表中存在 URL 参数</span>
+ <span class="hljs-keyword">if</span> (urlTypeIndex != -<span class="hljs-number">1</span>) {
+ <span class="hljs-comment">// 为 URL 类型参数生成判空代码,格式如下:</span>
+ <span class="hljs-comment">// if (arg + urlTypeIndex == null) </span>
+ <span class="hljs-comment">// throw new IllegalArgumentException("url == null");</span>
+ String s = String.format(<span class="hljs-string">"\nif (arg%d == null) throw new IllegalArgumentException(\"url == null\");"</span>,
+ urlTypeIndex);
+ code.append(s);
+
+ <span class="hljs-comment">// 为 URL 类型参数生成赋值代码,形如 URL url = arg1</span>
+ s = String.format(<span class="hljs-string">"\n%s url = arg%d;"</span>, URL.class.getName(), urlTypeIndex);
+ code.append(s);
+
+ <span class="hljs-comment">// 参数列表中不存在 URL 类型参数</span>
+ } <span class="hljs-keyword">else</span> {
+ String attribMethod = <span class="hljs-keyword">null</span>;
+
+ LBL_PTS:
+ <span class="hljs-comment">// 遍历方法的参数类型列表</span>
+ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < pts.length; ++i) {
+ <span class="hljs-comment">// 获取某一类型参数的全部方法</span>
+ Method[] ms = pts[i].getMethods();
+ <span class="hljs-comment">// 遍历方法列表,寻找可返回 URL 的 getter 方法</span>
+ <span class="hljs-keyword">for</span> (Method m : ms) {
+ String name = m.getName();
+ <span class="hljs-comment">// 1. 方法名以 get 开头,或方法名大于3个字符</span>
+ <span class="hljs-comment">// 2. 方法的访问权限为 public</span>
+ <span class="hljs-comment">// 3. 非静态方法</span>
+ <span class="hljs-comment">// 4. 方法参数数量为0</span>
+ <span class="hljs-comment">// 5. 方法返回值类型为 URL</span>
+ <span class="hljs-keyword">if</span> ((name.startsWith(<span class="hljs-string">"get"</span>) || name.length() > <span class="hljs-number">3</span>)
+ && Modifier.isPublic(m.getModifiers())
+ && !Modifier.isStatic(m.getModifiers())
+ && m.getParameterTypes().length == <span class="hljs-number">0</span>
+ && m.getReturnType() == URL.class) {
+ urlTypeIndex = i;
+ attribMethod = name;
+
+ <span class="hljs-comment">// 结束 for (int i = 0; i < pts.length; ++i) 循环</span>
+ <span class="hljs-keyword">break</span> LBL_PTS;
+ }
+ }
+ }
+ <span class="hljs-keyword">if</span> (attribMethod == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 如果所有参数中均不包含可返回 URL 的 getter 方法,则抛出异常</span>
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"fail to create adaptive class for interface ..."</span>);
+ }
+
+ <span class="hljs-comment">// 为可返回 URL 的参数生成判空代码,格式如下:</span>
+ <span class="hljs-comment">// if (arg + urlTypeIndex == null) </span>
+ <span class="hljs-comment">// throw new IllegalArgumentException("参数全限定名 + argument == null");</span>
+ String s = String.format(<span class="hljs-string">"\nif (arg%d == null) throw new IllegalArgumentException(\"%s argument == null\");"</span>,
+ urlTypeIndex, pts[urlTypeIndex].getName());
+ code.append(s);
+
+ <span class="hljs-comment">// 为 getter 方法返回的 URL 生成判空代码,格式如下:</span>
+ <span class="hljs-comment">// if (argN.getter方法名() == null) </span>
+ <span class="hljs-comment">// throw new IllegalArgumentException(参数全限定名 + argument getUrl() == null);</span>
+ s = String.format(<span class="hljs-string">"\nif (arg%d.%s() == null) throw new IllegalArgumentException(\"%s argument %s() == null\");"</span>,
+ urlTypeIndex, attribMethod, pts[urlTypeIndex].getName(), attribMethod);
+ code.append(s);
+
+ <span class="hljs-comment">// 生成赋值语句,格式如下:</span>
+ <span class="hljs-comment">// URL全限定名 url = argN.getter方法名(),比如 </span>
+ <span class="hljs-comment">// com.alibaba.dubbo.common.URL url = invoker.getUrl();</span>
+ s = String.format(<span class="hljs-string">"%s url = arg%d.%s();"</span>, URL.class.getName(), urlTypeIndex, attribMethod);
+ code.append(s);
+ }
+
+ <span class="hljs-comment">// 省略无关代码</span>
+ }
+
+ <span class="hljs-comment">// 省略无关代码</span>
+}
+</code></pre>
+<p>上面代码有点多,需要耐心看一下。这段代码主要目的是为了获取 URL 数据,并为之生成判空和赋值代码。以 Protocol 的 refer 和 export 方法为例,上面的代码为它们生成如下内容(代码已格式化):</p>
+<pre><code class="language-java">refer:
+<span class="hljs-keyword">if</span> (arg1 == <span class="hljs-keyword">null</span>)
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"url == null"</span>);
+com.alibaba.dubbo.common.URL url = arg1;
+
+export:
+<span class="hljs-keyword">if</span> (arg0 == <span class="hljs-keyword">null</span>)
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"com.alibaba.dubbo.rpc.Invoker argument == null"</span>);
+<span class="hljs-keyword">if</span> (arg0.getUrl() == <span class="hljs-keyword">null</span>)
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"com.alibaba.dubbo.rpc.Invoker argument getUrl() == null"</span>);
+com.alibaba.dubbo.common.URL url = arg0.getUrl();
+</code></pre>
+<h5>2.2.3.3 获取 Adaptive 注解值</h5>
+<p>Adaptive 注解值 value 类型为 String[],可填写多个值,默认情况下为空数组。若 value 为非空数组,直接获取数组内容即可。若 value 为空数组,则需进行额外处理。处理过程是将类名转换为字符数组,然后遍历字符数组,并将字符放入 StringBuilder 中。若字符为大写字母,则向 StringBuilder 中添加点号,随后将字符变为小写存入 StringBuilder 中。比如 LoadBalance 经过处理后,得到 load.balance。</p>
+<pre><code class="language-java"><span class="hljs-keyword">for</span> (Method method : methods) {
+ Class<?> rt = method.getReturnType();
+ Class<?>[] pts = method.getParameterTypes();
+ Class<?>[] ets = method.getExceptionTypes();
+
+ Adaptive adaptiveAnnotation = method.getAnnotation(Adaptive.class);
+ StringBuilder code = <span class="hljs-keyword">new</span> StringBuilder(<span class="hljs-number">512</span>);
+ <span class="hljs-keyword">if</span> (adaptiveAnnotation == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// ${无 Adaptive 注解方法代码生成逻辑}</span>
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-comment">// ${获取 URL 数据}</span>
+
+ String[] value = adaptiveAnnotation.value();
+ <span class="hljs-comment">// value 为空数组</span>
+ <span class="hljs-keyword">if</span> (value.length == <span class="hljs-number">0</span>) {
+ <span class="hljs-comment">// 获取类名,并将类名转换为字符数组</span>
+ <span class="hljs-keyword">char</span>[] charArray = type.getSimpleName().toCharArray();
+ StringBuilder sb = <span class="hljs-keyword">new</span> StringBuilder(<span class="hljs-number">128</span>);
+ <span class="hljs-comment">// 遍历字节数组</span>
+ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < charArray.length; i++) {
+ <span class="hljs-comment">// 检测当前字符是否为大写字母</span>
+ <span class="hljs-keyword">if</span> (Character.isUpperCase(charArray[i])) {
+ <span class="hljs-keyword">if</span> (i != <span class="hljs-number">0</span>) {
+ <span class="hljs-comment">// 向 sb 中添加点号</span>
+ sb.append(<span class="hljs-string">"."</span>);
+ }
+ <span class="hljs-comment">// 将字符变为小写,并添加到 sb 中</span>
+ sb.append(Character.toLowerCase(charArray[i]));
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-comment">// 添加字符到 sb 中</span>
+ sb.append(charArray[i]);
+ }
+ }
+ value = <span class="hljs-keyword">new</span> String[]{sb.toString()};
+ }
+
+ <span class="hljs-comment">// 省略无关代码</span>
+ }
+
+ <span class="hljs-comment">// 省略无关逻辑</span>
+}
+</code></pre>
+<h5>2.2.3.4 检测 Invocation 参数</h5>
+<p>此段逻辑是检测方法列表中是否存在 Invocation 类型的参数,若存在,则为其生成判空代码和其他一些代码。相应的逻辑如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">for</span> (Method method : methods) {
+ Class<?> rt = method.getReturnType();
+ Class<?>[] pts = method.getParameterTypes(); <span class="hljs-comment">// 获取参数类型列表</span>
+ Class<?>[] ets = method.getExceptionTypes();
+
+ Adaptive adaptiveAnnotation = method.getAnnotation(Adaptive.class);
+ StringBuilder code = <span class="hljs-keyword">new</span> StringBuilder(<span class="hljs-number">512</span>);
+ <span class="hljs-keyword">if</span> (adaptiveAnnotation == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// ${无 Adaptive 注解方法代码生成逻辑}</span>
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-comment">// ${获取 URL 数据}</span>
+
+ <span class="hljs-comment">// ${获取 Adaptive 注解值}</span>
+
+ <span class="hljs-keyword">boolean</span> hasInvocation = <span class="hljs-keyword">false</span>;
+ <span class="hljs-comment">// 遍历参数类型列表</span>
+ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < pts.length; ++i) {
+ <span class="hljs-comment">// 判断当前参数名称是否等于 com.alibaba.dubbo.rpc.Invocation</span>
+ <span class="hljs-keyword">if</span> (pts[i].getName().equals(<span class="hljs-string">"com.alibaba.dubbo.rpc.Invocation"</span>)) {
+ <span class="hljs-comment">// 为 Invocation 类型参数生成判空代码</span>
+ String s = String.format(<span class="hljs-string">"\nif (arg%d == null) throw new IllegalArgumentException(\"invocation == null\");"</span>, i);
+ code.append(s);
+ <span class="hljs-comment">// 生成 getMethodName 方法调用代码,格式为:</span>
+ <span class="hljs-comment">// String methodName = argN.getMethodName();</span>
+ s = String.format(<span class="hljs-string">"\nString methodName = arg%d.getMethodName();"</span>, i);
+ code.append(s);
+
+ <span class="hljs-comment">// 设置 hasInvocation 为 true</span>
+ hasInvocation = <span class="hljs-keyword">true</span>;
+ <span class="hljs-keyword">break</span>;
+ }
+ }
+ }
+
+ <span class="hljs-comment">// 省略无关逻辑</span>
+}
+</code></pre>
+<h5>2.2.3.5 生成拓展名获取逻辑</h5>
+<p>本段逻辑用于根据 SPI 和 Adaptive 注解值生成“获取拓展名逻辑”,同时生成逻辑也受 Invocation 类型参数影响,综合因素导致本段逻辑相对复杂。本段逻辑可以会生成但不限于下面的代码:</p>
+<pre><code class="language-java">String extName = (url.getProtocol() == <span class="hljs-keyword">null</span> ? <span class="hljs-string">"dubbo"</span> : url.getProtocol());
+</code></pre>
+<p>或</p>
+<pre><code class="language-java">String extName = url.getMethodParameter(methodName, <span class="hljs-string">"loadbalance"</span>, <span class="hljs-string">"random"</span>);
+</code></pre>
+<p>亦或是</p>
+<pre><code class="language-java">String extName = url.getParameter(<span class="hljs-string">"client"</span>, url.getParameter(<span class="hljs-string">"transporter"</span>, <span class="hljs-string">"netty"</span>));
+</code></pre>
+<p>本段逻辑复杂之处在于条件分支比较多,大家在阅读源码时需要知道每个条件分支的意义是什么,否则不太容易看懂相关代码。下面开始分析本段逻辑。</p>
+<pre><code class="language-java"><span class="hljs-keyword">for</span> (Method method : methods) {
+ Class<?> rt = method.getReturnType();
+ Class<?>[] pts = method.getParameterTypes();
+ Class<?>[] ets = method.getExceptionTypes();
+
+ Adaptive adaptiveAnnotation = method.getAnnotation(Adaptive.class);
+ StringBuilder code = <span class="hljs-keyword">new</span> StringBuilder(<span class="hljs-number">512</span>);
+ <span class="hljs-keyword">if</span> (adaptiveAnnotation == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// $无 Adaptive 注解方法代码生成逻辑}</span>
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-comment">// ${获取 URL 数据}</span>
+
+ <span class="hljs-comment">// ${获取 Adaptive 注解值}</span>
+
+ <span class="hljs-comment">// ${检测 Invocation 参数}</span>
+
+ <span class="hljs-comment">// 设置默认拓展名,cachedDefaultName 源于 SPI 注解值,默认情况下,</span>
+ <span class="hljs-comment">// SPI 注解值为空串,此时 cachedDefaultName = null</span>
+ String defaultExtName = cachedDefaultName;
+ String getNameCode = <span class="hljs-keyword">null</span>;
+
+ <span class="hljs-comment">// 遍历 value,这里的 value 是 Adaptive 的注解值,2.2.3.3 节分析过 value 变量的获取过程。</span>
+ <span class="hljs-comment">// 此处循环目的是生成从 URL 中获取拓展名的代码,生成的代码会赋值给 getNameCode 变量。注意这</span>
+ <span class="hljs-comment">// 个循环的遍历顺序是由后向前遍历的。</span>
+ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = value.length - <span class="hljs-number">1</span>; i >= <span class="hljs-number">0</span>; --i) {
+ <span class="hljs-comment">// 当 i 为最后一个元素的坐标时</span>
+ <span class="hljs-keyword">if</span> (i == value.length - <span class="hljs-number">1</span>) {
+ <span class="hljs-comment">// 默认拓展名非空</span>
+ <span class="hljs-keyword">if</span> (<span class="hljs-keyword">null</span> != defaultExtName) {
+ <span class="hljs-comment">// protocol 是 url 的一部分,可通过 getProtocol 方法获取,其他的则是从</span>
+ <span class="hljs-comment">// URL 参数中获取。因为获取方式不同,所以这里要判断 value[i] 是否为 protocol</span>
+ <span class="hljs-keyword">if</span> (!<span class="hljs-string">"protocol"</span>.equals(value[i]))
+ <span class="hljs-comment">// hasInvocation 用于标识方法参数列表中是否有 Invocation 类型参数</span>
+ <span class="hljs-keyword">if</span> (hasInvocation)
+ <span class="hljs-comment">// 生成的代码功能等价于下面的代码:</span>
+ <span class="hljs-comment">// url.getMethodParameter(methodName, value[i], defaultExtName)</span>
+ <span class="hljs-comment">// 以 LoadBalance 接口的 select 方法为例,最终生成的代码如下:</span>
+ <span class="hljs-comment">// url.getMethodParameter(methodName, "loadbalance", "random")</span>
+ getNameCode = String.format(<span class="hljs-string">"url.getMethodParameter(methodName, \"%s\", \"%s\")"</span>, value[i], defaultExtName);
+ <span class="hljs-keyword">else</span>
+ <span class="hljs-comment">// 生成的代码功能等价于下面的代码:</span>
+ <span class="hljs-comment">// url.getParameter(value[i], defaultExtName)</span>
+ getNameCode = String.format(<span class="hljs-string">"url.getParameter(\"%s\", \"%s\")"</span>, value[i], defaultExtName);
+ <span class="hljs-keyword">else</span>
+ <span class="hljs-comment">// 生成的代码功能等价于下面的代码:</span>
+ <span class="hljs-comment">// ( url.getProtocol() == null ? defaultExtName : url.getProtocol() )</span>
+ getNameCode = String.format(<span class="hljs-string">"( url.getProtocol() == null ? \"%s\" : url.getProtocol() )"</span>, defaultExtName);
+
+ <span class="hljs-comment">// 默认拓展名为空</span>
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-keyword">if</span> (!<span class="hljs-string">"protocol"</span>.equals(value[i]))
+ <span class="hljs-keyword">if</span> (hasInvocation)
+ <span class="hljs-comment">// 生成代码格式同上</span>
+ getNameCode = String.format(<span class="hljs-string">"url.getMethodParameter(methodName, \"%s\", \"%s\")"</span>, value[i], defaultExtName);
+ <span class="hljs-keyword">else</span>
+ <span class="hljs-comment">// 生成的代码功能等价于下面的代码:</span>
+ <span class="hljs-comment">// url.getParameter(value[i])</span>
+ getNameCode = String.format(<span class="hljs-string">"url.getParameter(\"%s\")"</span>, value[i]);
+ <span class="hljs-keyword">else</span>
+ <span class="hljs-comment">// 生成从 url 中获取协议的代码,比如 "dubbo"</span>
+ getNameCode = <span class="hljs-string">"url.getProtocol()"</span>;
+ }
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-keyword">if</span> (!<span class="hljs-string">"protocol"</span>.equals(value[i]))
+ <span class="hljs-keyword">if</span> (hasInvocation)
+ <span class="hljs-comment">// 生成代码格式同上</span>
+ getNameCode = String.format(<span class="hljs-string">"url.getMethodParameter(methodName, \"%s\", \"%s\")"</span>, value[i], defaultExtName);
+ <span class="hljs-keyword">else</span>
+ <span class="hljs-comment">// 生成的代码功能等价于下面的代码:</span>
+ <span class="hljs-comment">// url.getParameter(value[i], getNameCode)</span>
+ <span class="hljs-comment">// 以 Transporter 接口的 connect 方法为例,最终生成的代码如下:</span>
+ <span class="hljs-comment">// url.getParameter("client", url.getParameter("transporter", "netty"))</span>
+ getNameCode = String.format(<span class="hljs-string">"url.getParameter(\"%s\", %s)"</span>, value[i], getNameCode);
+ <span class="hljs-keyword">else</span>
+ <span class="hljs-comment">// 生成的代码功能等价于下面的代码:</span>
+ <span class="hljs-comment">// url.getProtocol() == null ? getNameCode : url.getProtocol()</span>
+ <span class="hljs-comment">// 以 Protocol 接口的 connect 方法为例,最终生成的代码如下:</span>
+ <span class="hljs-comment">// url.getProtocol() == null ? "dubbo" : url.getProtocol()</span>
+ getNameCode = String.format(<span class="hljs-string">"url.getProtocol() == null ? (%s) : url.getProtocol()"</span>, getNameCode);
+ }
+ }
+ <span class="hljs-comment">// 生成 extName 赋值代码</span>
+ code.append(<span class="hljs-string">"\nString extName = "</span>).append(getNameCode).append(<span class="hljs-string">";"</span>);
+ <span class="hljs-comment">// 生成 extName 判空代码</span>
+ String s = String.format(<span class="hljs-string">"\nif(extName == null) "</span> +
+ <span class="hljs-string">"throw new IllegalStateException(\"Fail to get extension(%s) name from url(\" + url.toString() + \") use keys(%s)\");"</span>,
+ type.getName(), Arrays.toString(value));
+ code.append(s);
+ }
+
+ <span class="hljs-comment">// 省略无关逻辑</span>
+}
+</code></pre>
+<p>上面代码比较复杂,不是很好理解。对于这段代码,建议大家写点测试用例,对 Protocol、LoadBalance 以及 Transporter 等接口的自适应拓展类代码生成过程进行调试。这里我以 Transporter 接口的自适应拓展类代码生成过程举例说明。首先看一下 Transporter 接口的定义,如下:</p>
+<pre><code class="language-java"><span class="hljs-meta">@SPI</span>(<span class="hljs-string">"netty"</span>)
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Transporter</span> </span>{
+ <span class="hljs-comment">// @Adaptive({server, transporter})</span>
+ <span class="hljs-meta">@Adaptive</span>({Constants.SERVER_KEY, Constants.TRANSPORTER_KEY})
+ <span class="hljs-function">Server <span class="hljs-title">bind</span><span class="hljs-params">(URL url, ChannelHandler handler)</span> <span class="hljs-keyword">throws</span> RemotingException</span>;
+
+ <span class="hljs-comment">// @Adaptive({client, transporter})</span>
+ <span class="hljs-meta">@Adaptive</span>({Constants.CLIENT_KEY, Constants.TRANSPORTER_KEY})
+ <span class="hljs-function">Client <span class="hljs-title">connect</span><span class="hljs-params">(URL url, ChannelHandler handler)</span> <span class="hljs-keyword">throws</span> RemotingException</span>;
+}
+</code></pre>
+<p>下面对 connect 方法代理逻辑生成的过程进行分析,此时生成代理逻辑所用到的变量如下:</p>
+<pre><code class="language-java">String defaultExtName = <span class="hljs-string">"netty"</span>;
+<span class="hljs-keyword">boolean</span> hasInvocation = <span class="hljs-keyword">false</span>;
+String getNameCode = <span class="hljs-keyword">null</span>;
+String[] value = [<span class="hljs-string">"client"</span>, <span class="hljs-string">"transporter"</span>];
+</code></pre>
+<p>下面对 value 数组进行遍历,此时 i = 1, value[i] = "transporter",生成的代码如下:</p>
+<pre><code class="language-java">getNameCode = url.getParameter(<span class="hljs-string">"transporter"</span>, <span class="hljs-string">"netty"</span>);
+</code></pre>
+<p>接下来,for 循环继续执行,此时 i = 0, value[i] = "client",生成的代码如下:</p>
+<pre><code class="language-java">getNameCode = url.getParameter(<span class="hljs-string">"client"</span>, url.getParameter(<span class="hljs-string">"transporter"</span>, <span class="hljs-string">"netty"</span>));
+</code></pre>
+<p>for 循环结束运行,现在为 extName 变量生成赋值和判空代码,如下:</p>
+<pre><code class="language-java">String extName = url.getParameter(<span class="hljs-string">"client"</span>, url.getParameter(<span class="hljs-string">"transporter"</span>, <span class="hljs-string">"netty"</span>));
+<span class="hljs-keyword">if</span> (extName == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(
+ <span class="hljs-string">"Fail to get extension(com.alibaba.dubbo.remoting.Transporter) name from url("</span> + url.toString()
+ + <span class="hljs-string">") use keys([client, transporter])"</span>);
+}
+</code></pre>
+<h5>2.2.3.6 生成拓展加载与目标方法调用逻辑</h5>
+<p>本段代码逻辑用于根据拓展名加载拓展实例,并调用拓展实例的目标方法。相关逻辑如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">for</span> (Method method : methods) {
+ Class<?> rt = method.getReturnType();
+ Class<?>[] pts = method.getParameterTypes();
+ Class<?>[] ets = method.getExceptionTypes();
+
+ Adaptive adaptiveAnnotation = method.getAnnotation(Adaptive.class);
+ StringBuilder code = <span class="hljs-keyword">new</span> StringBuilder(<span class="hljs-number">512</span>);
+ <span class="hljs-keyword">if</span> (adaptiveAnnotation == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// $无 Adaptive 注解方法代码生成逻辑}</span>
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-comment">// ${获取 URL 数据}</span>
+
+ <span class="hljs-comment">// ${获取 Adaptive 注解值}</span>
+
+ <span class="hljs-comment">// ${检测 Invocation 参数}</span>
+
+ <span class="hljs-comment">// ${生成拓展名获取逻辑}</span>
+
+ <span class="hljs-comment">// 生成拓展获取代码,格式如下:</span>
+ <span class="hljs-comment">// type全限定名 extension = (type全限定名)ExtensionLoader全限定名</span>
+ <span class="hljs-comment">// .getExtensionLoader(type全限定名.class).getExtension(extName);</span>
+ <span class="hljs-comment">// Tips: 格式化字符串中的 %<s 表示使用前一个转换符所描述的参数,即 type 全限定名</span>
+ s = String.format(<span class="hljs-string">"\n%s extension = (%<s)%s.getExtensionLoader(%s.class).getExtension(extName);"</span>,
+ type.getName(), ExtensionLoader.class.getSimpleName(), type.getName());
+ code.append(s);
+
+ <span class="hljs-comment">// 如果方法返回值类型非 void,则生成 return 语句。</span>
+ <span class="hljs-keyword">if</span> (!rt.equals(<span class="hljs-keyword">void</span>.class)) {
+ code.append(<span class="hljs-string">"\nreturn "</span>);
+ }
+
+ <span class="hljs-comment">// 生成目标方法调用逻辑,格式为:</span>
+ <span class="hljs-comment">// extension.方法名(arg0, arg2, ..., argN);</span>
+ s = String.format(<span class="hljs-string">"extension.%s("</span>, method.getName());
+ code.append(s);
+ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < pts.length; i++) {
+ <span class="hljs-keyword">if</span> (i != <span class="hljs-number">0</span>)
+ code.append(<span class="hljs-string">", "</span>);
+ code.append(<span class="hljs-string">"arg"</span>).append(i);
+ }
+ code.append(<span class="hljs-string">");"</span>);
+ }
+
+ <span class="hljs-comment">// 省略无关逻辑</span>
+}
+</code></pre>
+<p>以 Protocol 接口举例说明,上面代码生成的内容如下:</p>
+<pre><code class="language-java">com.alibaba.dubbo.rpc.Protocol extension = (com.alibaba.dubbo.rpc.Protocol) ExtensionLoader
+ .getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(extName);
+<span class="hljs-keyword">return</span> extension.refer(arg0, arg1);
+</code></pre>
+<h5>2.2.3.7 生成完整的方法</h5>
+<p>本节进行代码生成的收尾工作,主要用于生成方法定义的代码。相关逻辑如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">for</span> (Method method : methods) {
+ Class<?> rt = method.getReturnType();
+ Class<?>[] pts = method.getParameterTypes();
+ Class<?>[] ets = method.getExceptionTypes();
+
+ Adaptive adaptiveAnnotation = method.getAnnotation(Adaptive.class);
+ StringBuilder code = <span class="hljs-keyword">new</span> StringBuilder(<span class="hljs-number">512</span>);
+ <span class="hljs-keyword">if</span> (adaptiveAnnotation == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// $无 Adaptive 注解方法代码生成逻辑}</span>
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-comment">// ${获取 URL 数据}</span>
+
+ <span class="hljs-comment">// ${获取 Adaptive 注解值}</span>
+
+ <span class="hljs-comment">// ${检测 Invocation 参数}</span>
+
+ <span class="hljs-comment">// ${生成拓展名获取逻辑}</span>
+
+ <span class="hljs-comment">// ${生成拓展加载与目标方法调用逻辑}</span>
+ }
+}
+
+<span class="hljs-comment">// public + 返回值全限定名 + 方法名 + (</span>
+codeBuilder.append(<span class="hljs-string">"\npublic "</span>)
+ .append(rt.getCanonicalName())
+ .append(<span class="hljs-string">" "</span>)
+ .append(method.getName())
+ .append(<span class="hljs-string">"("</span>);
+
+<span class="hljs-comment">// 添加参数列表代码</span>
+<span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < pts.length; i++) {
+ <span class="hljs-keyword">if</span> (i > <span class="hljs-number">0</span>) {
+ codeBuilder.append(<span class="hljs-string">", "</span>);
+ }
+ codeBuilder.append(pts[i].getCanonicalName());
+ codeBuilder.append(<span class="hljs-string">" "</span>);
+ codeBuilder.append(<span class="hljs-string">"arg"</span>).append(i);
+}
+codeBuilder.append(<span class="hljs-string">")"</span>);
+
+<span class="hljs-comment">// 添加异常抛出代码</span>
+<span class="hljs-keyword">if</span> (ets.length > <span class="hljs-number">0</span>) {
+ codeBuilder.append(<span class="hljs-string">" throws "</span>);
+ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < ets.length; i++) {
+ <span class="hljs-keyword">if</span> (i > <span class="hljs-number">0</span>) {
+ codeBuilder.append(<span class="hljs-string">", "</span>);
+ }
+ codeBuilder.append(ets[i].getCanonicalName());
+ }
+}
+codeBuilder.append(<span class="hljs-string">" {"</span>);
+codeBuilder.append(code.toString());
+codeBuilder.append(<span class="hljs-string">"\n}"</span>);
+</code></pre>
+<p>以 Protocol 的 refer 方法为例,上面代码生成的内容如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> com.alibaba.dubbo.rpc.<span class="hljs-function">Invoker <span class="hljs-title">refer</span><span class="hljs-params">(java.lang.Class arg0, com.alibaba.dubbo.common.URL arg1)</span> </span>{
+ <span class="hljs-comment">// 方法体</span>
+}
+</code></pre>
+<h2>3.总结</h2>
+<p>到此,关于自适应拓展的原理,实现就分析完了。总的来说自适应拓展整个逻辑还是很复杂的,并不是很容易弄懂。因此,大家在阅读该部分源码时,耐心一些。同时多进行调试,也可以通过生成好的代码思考代码的生成逻辑。好了,本篇文章就分析到这里。</p>
+</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
+ <script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+ <script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+ <script>
+ window.rootPath = '';
+ </script>
+ <script src="/build/documentation.js"></script>
+ <!-- Global site tag (gtag.js) - Google Analytics -->
+ <script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+ <script>
+ window.dataLayer = window.dataLayer || [];
+ function gtag(){dataLayer.push(arguments);}
+ gtag('js', new Date());
+
+ gtag('config', 'UA-112489517-1');
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/zh-cn/docs/source_code_guide/adaptive-extension.json b/zh-cn/docs/source_code_guide/adaptive-extension.json
new file mode 100644
index 0000000..351dfda
--- /dev/null
+++ b/zh-cn/docs/source_code_guide/adaptive-extension.json
@@ -0,0 +1,10 @@
+{
+ "filename": "adaptive-extension.md",
+ "__html": "<h2>1.原理</h2>\n<p>在 Dubbo 中,很多拓展都是通过 SPI 机制进行加载的,比如 Protocol、Cluster、LoadBalance 等。有时,有些拓展并不想在框架启动阶段被加载,而是希望在拓展方法被调用时,根据运行时参数进行加载。这听起来有些矛盾。拓展未被加载,那么拓展方法就无法被调用(静态方法除外)。拓展方法未被调用,拓展就无法被加载。对于这个矛盾的问题,Dubbo 通过自适应拓展机制很好的解决了。自适应拓展机制的实现逻辑比较复杂,首先 Dubbo 会为拓展接口生成具有代理功能的代码。然后通过 javassist 或 jdk 编译这段代码,得到 Class 类。最后再通过反射创建代理类,整个过程比较复杂。为了让大家对自适应拓展有一个感性的认识,下面我们通过一个示例进行演示。这是一个与汽车相关的例子,我们有一个车轮制造厂接口 WheelMaker:</p>\n<p
re><code class=\"language-java\"><span class=\"hljs-keyword\">public</span> < [...]
+ "link": "/zh-cn/docs/source_code_guide/adaptive-extension.html",
+ "meta": {
+ "title": "SPI 自适应拓展",
+ "keywords": "Dubbo, SPI, Adaptive Extension",
+ "description": "本文介绍了自适应拓展的原理和实现细节"
+ }
+}
\ No newline at end of file
diff --git a/zh-cn/docs/source_code_guide/cluster.html b/zh-cn/docs/source_code_guide/cluster.html
new file mode 100644
index 0000000..8a7e499
--- /dev/null
+++ b/zh-cn/docs/source_code_guide/cluster.html
@@ -0,0 +1,559 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <meta name="keywords" content="Dubbo, Cluster" />
+ <meta name="description" content="本文介绍了集群的原理和实现细节" />
+ <!-- 网页标签标题 -->
+ <title>集群</title>
+ <link rel="shortcut icon" href="/img/dubbo.ico"/>
+ <link rel="stylesheet" href="/build/documentation.css" />
+</head>
+<body>
+ <div id="root"><div class="documentation-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a [...]
+<p>为了避免单点故障,现在的应用通常至少会部署在两台服务器上。对于一些负载比较高的服务,会部署更多的服务器。这样,在同一环境下的服务提供者数量会大于1。对于服务消费者来说,同一环境下出现了多个服务提供者。这时会出现一个问题,服务消费者需要决定选择哪个服务提供者进行调用。另外服务调用失败时的处理措施也是需要考虑的,是重试呢,还是抛出异常,亦或是只打印异常等。为了处理这些问题,Dubbo 定义了集群接口 Cluster 以及 Cluster Invoker。集群 Cluster 用途是将多个服务提供者合并为一个 Cluster Invoker,并将这个 Invoker 暴露给服务消费者。这样一来,服务消费者只需通过这个 Invoker 进行远程调用即可,至于具体调用哪个服务提供者,以及调用失败后如何处理等问题,现在都交给集群模块去处理。集群模块是服务提供者和服�
��消费者的中间层,为服务消费者屏蔽了服务提供者的情况,这样服务消费者就可以专心处理远程调用相关事宜。比如发请求,接受服务提供者返回的数据等。这就是集群的作用。</p>
+<p>Dubbo 提供了多种集群实现,包含但不限于 Failover Cluster、Failfast Cluster 和 Failsafe Cluster 等。每种集群实现类的用途不同,接下来会一一进行分析。</p>
+<h2>2. 集群容错</h2>
+<p>在对集群相关代码进行分析之前,这里有必要先来介绍一下集群容错的所有组件。包含 Cluster、Cluster Invoker、Directory、Router 和 LoadBalance 等。</p>
+<p><img src="./sources/images/cluster.jpg" alt=""></p>
+<p>集群工作过程可分为两个阶段,第一个阶段是在服务消费者初始化期间,集群 Cluster 实现类为服务消费者创建 Cluster Invoker 实例,即上图中的 merge 操作。第二个阶段是在服务消费者进行远程调用时。以 FailoverClusterInvoker 为例,该类型 Cluster Invoker 首先会调用 Directory 的 list 方法列举 Invoker 列表(可将 Invoker 简单理解为服务提供者)。Directory 的用途是保存 Invoker,可简单类比为 List<Invoker>。其实现类 RegistryDirectory 是一个动态服务目录,可感知注册中心配置的变化,它所持有的 Inovker 列表会随着注册中心内容的变化而变化。每次变化后,RegistryDirectory 会动态增删 Inovker,并调用 Router 的 route 方法进行路由,过滤掉不符合路由规则的 Invoker。当 FailoverClusterInvoker 拿到 Directory 返回的 Invoker 列表后,它会 [...]
+<p>以上就是集群工作的整个流程,这里并没介绍集群是如何容错的。Dubbo 主要提供了这样几种容错方式:</p>
+<ul>
+<li>Failover Cluster - 失败自动切换</li>
+<li>Failfast Cluster - 快速失败</li>
+<li>Failsafe Cluster - 失败安全</li>
+<li>Failback Cluster - 失败自动恢复</li>
+<li>Forking Cluster - 并行调用多个服务提供者</li>
+</ul>
+<p>下面开始分析源码。</p>
+<h2>3.源码分析</h2>
+<h3>3.1 Cluster 实现类分析</h3>
+<p>我们在上一章看到了两个概念,分别是集群接口 Cluster 和 Cluster Invoker,这两者是不同的。Cluster 是接口,而 Cluster Invoker 是一种 Invoker。服务提供者的选择逻辑,以及远程调用失败后的的处理逻辑均是封装在 Cluster Invoker 中。那么 Cluster 接口和相关实现类有什么用呢?用途比较简单,仅用于生成 Cluster Invoker。下面我们来看一下源码。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FailoverCluster</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Cluster</span> </span>{
+
+ <span class="hljs-keyword">public</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">static</span> String NAME = <span class="hljs-string">"failover"</span>;
+
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-keyword">public</span> <T> <span class="hljs-function">Invoker<T> <span class="hljs-title">join</span><span class="hljs-params">(Directory<T> directory)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
+ <span class="hljs-comment">// 创建并返回 FailoverClusterInvoker 对象</span>
+ <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> FailoverClusterInvoker<T>(directory);
+ }
+}
+</code></pre>
+<p>如上,FailoverCluster 总共就包含这几行代码,用于创建 FailoverClusterInvoker 对象,很简单。下面再看一个。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FailbackCluster</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Cluster</span> </span>{
+
+ <span class="hljs-keyword">public</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">static</span> String NAME = <span class="hljs-string">"failback"</span>;
+
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-keyword">public</span> <T> <span class="hljs-function">Invoker<T> <span class="hljs-title">join</span><span class="hljs-params">(Directory<T> directory)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
+ <span class="hljs-comment">// 创建并返回 FailbackClusterInvoker 对象</span>
+ <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> FailbackClusterInvoker<T>(directory);
+ }
+
+}
+</code></pre>
+<p>如上,FailbackCluster 的逻辑也是很简单,无需解释了。所以接下来,我们把重点放在各种 Cluster Invoker 上</p>
+<h3>3.2 Cluster Invoker 分析</h3>
+<p>我们首先从各种 Cluster Invoker 的父类 AbstractClusterInvoker 源码开始说起。前面说过,集群工作过程可分为两个阶段,第一个阶段是在服务消费者初始化期间,这个在<a href="">服务引用</a>那篇文章中分析过,就不赘述。第二个阶段是在服务消费者进行远程调用时,此时 AbstractClusterInvoker 的 invoke 方法会被调用。列举 Invoker,负载均衡等操作均会在此阶段被执行。因此下面先来看一下 invoke 方法的逻辑。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">public</span> Result <span class="hljs-title">invoke</span><span class="hljs-params">(<span class="hljs-keyword">final</span> Invocation invocation)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
+ checkWhetherDestroyed();
+ LoadBalance loadbalance = <span class="hljs-keyword">null</span>;
+
+ <span class="hljs-comment">// 绑定 attachments 到 invocation 中.</span>
+ Map<String, String> contextAttachments = RpcContext.getContext().getAttachments();
+ <span class="hljs-keyword">if</span> (contextAttachments != <span class="hljs-keyword">null</span> && contextAttachments.size() != <span class="hljs-number">0</span>) {
+ ((RpcInvocation) invocation).addAttachments(contextAttachments);
+ }
+
+ <span class="hljs-comment">// 列举 Invoker</span>
+ List<Invoker<T>> invokers = list(invocation);
+ <span class="hljs-keyword">if</span> (invokers != <span class="hljs-keyword">null</span> && !invokers.isEmpty()) {
+ <span class="hljs-comment">// 加载 LoadBalance</span>
+ loadbalance = ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(invokers.get(<span class="hljs-number">0</span>).getUrl()
+ .getMethodParameter(RpcUtils.getMethodName(invocation), Constants.LOADBALANCE_KEY, Constants.DEFAULT_LOADBALANCE));
+ }
+ RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);
+
+ <span class="hljs-comment">// 调用 doInvoke 进行后续操作</span>
+ <span class="hljs-keyword">return</span> doInvoke(invocation, invokers, loadbalance);
+}
+
+<span class="hljs-comment">// 抽象方法,由子类实现</span>
+<span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">abstract</span> Result <span class="hljs-title">doInvoke</span><span class="hljs-params">(Invocation invocation, List<Invoker<T>> invokers,
+ LoadBalance loadbalance)</span> <span class="hljs-keyword">throws</span> RpcException</span>;
+</code></pre>
+<p>AbstractClusterInvoker 的 invoke 方法主要用于列举 Invoker,以及加载 LoadBalance。最后再调用模板方法 doInvoke 进行后续操作。下面我们来看一下 Invoker 列举方法 list(Invocation) 的逻辑,如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">protected</span> List<Invoker<T>> list(Invocation invocation) <span class="hljs-keyword">throws</span> RpcException {
+ <span class="hljs-comment">// 调用 Directory 的 list 方法列举 Invoker</span>
+ List<Invoker<T>> invokers = directory.list(invocation);
+ <span class="hljs-keyword">return</span> invokers;
+}
+</code></pre>
+<p>如上,AbstractClusterInvoker 中的 list 方法做的事情很简单,只是简单的调用了 Directory 的 list 方法,没有其他更多的逻辑了。Directory 即相关实现类在前文已经分析过,这里就不多说了。接下来,我们把目光转移到 AbstractClusterInvoker 的各种实现类上,来看一下这些实现类是如何实现 doInvoke 方法逻辑的。</p>
+<h4>3.2.1 FailoverClusterInvoker</h4>
+<p>FailoverClusterInvoker 在调用失败时,会自动切换 Invoker 进行重试。默认确配置下,Dubbo 会使用这个类作为缺省 Cluster Invoker。下面来看一下该类的逻辑。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FailoverClusterInvoker</span><<span class="hljs-title">T</span>> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractClusterInvoker</span><<span class="hljs-title">T</span>> </span>{
+
+ <span class="hljs-comment">// 省略部分代码</span>
+
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-function"><span class="hljs-keyword">public</span> Result <span class="hljs-title">doInvoke</span><span class="hljs-params">(Invocation invocation, <span class="hljs-keyword">final</span> List<Invoker<T>> invokers, LoadBalance loadbalance)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
+ List<Invoker<T>> copyinvokers = invokers;
+ checkInvokers(copyinvokers, invocation);
+ <span class="hljs-comment">// 获取重试次数</span>
+ <span class="hljs-keyword">int</span> len = getUrl().getMethodParameter(invocation.getMethodName(), Constants.RETRIES_KEY, Constants.DEFAULT_RETRIES) + <span class="hljs-number">1</span>;
+ <span class="hljs-keyword">if</span> (len <= <span class="hljs-number">0</span>) {
+ len = <span class="hljs-number">1</span>;
+ }
+ RpcException le = <span class="hljs-keyword">null</span>;
+ List<Invoker<T>> invoked = <span class="hljs-keyword">new</span> ArrayList<Invoker<T>>(copyinvokers.size());
+ Set<String> providers = <span class="hljs-keyword">new</span> HashSet<String>(len);
+ <span class="hljs-comment">// 循环调用,失败重试</span>
+ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < len; i++) {
+ <span class="hljs-keyword">if</span> (i > <span class="hljs-number">0</span>) {
+ checkWhetherDestroyed();
+ <span class="hljs-comment">// 在进行重试前重新列举 Invoker,这样做的好处是,如果某个服务挂了,</span>
+ <span class="hljs-comment">// 通过调用 list 可得到最新可用的 Invoker 列表</span>
+ copyinvokers = list(invocation);
+ <span class="hljs-comment">// 对 copyinvokers 进行判空检查</span>
+ checkInvokers(copyinvokers, invocation);
+ }
+
+ <span class="hljs-comment">// 通过负载均衡选择 Invoker</span>
+ Invoker<T> invoker = select(loadbalance, invocation, copyinvokers, invoked);
+ <span class="hljs-comment">// 添加到 invoker 到 invoked 列表中</span>
+ invoked.add(invoker);
+ <span class="hljs-comment">// 设置 invoked 到 RPC 上下文中</span>
+ RpcContext.getContext().setInvokers((List) invoked);
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-comment">// 调用目标 Invoker 的 invoke 方法</span>
+ Result result = invoker.invoke(invocation);
+ <span class="hljs-keyword">return</span> result;
+ } <span class="hljs-keyword">catch</span> (RpcException e) {
+ <span class="hljs-keyword">if</span> (e.isBiz()) {
+ <span class="hljs-keyword">throw</span> e;
+ }
+ le = e;
+ } <span class="hljs-keyword">catch</span> (Throwable e) {
+ le = <span class="hljs-keyword">new</span> RpcException(e.getMessage(), e);
+ } <span class="hljs-keyword">finally</span> {
+ providers.add(invoker.getUrl().getAddress());
+ }
+ }
+
+ <span class="hljs-comment">// 若重试失败,则抛出异常</span>
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RpcException(..., <span class="hljs-string">"Failed to invoke the method ..."</span>);
+ }
+}
+</code></pre>
+<p>如上,FailoverClusterInvoker 的 doInvoke 方法首先是获取重试次数,然后根据重试次数进行循环调用,失败后进行重试。在 for 循环内,首先是通过负载均衡组件选择一个 Invoker,然后再通过这个 Invoker 的 invoke 方法进行远程调用。如果失败了,记录下异常,并进行重试。重试时会再次调用父类的 list 方法列举 Invoker。整个流程大致如此,不是很难理解。下面我们看一下 select 方法的逻辑。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">protected</span> Invoker<T> <span class="hljs-title">select</span><span class="hljs-params">(LoadBalance loadbalance, Invocation invocation, List<Invoker<T>> invokers, List<Invoker<T>> selected)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
+ <span class="hljs-keyword">if</span> (invokers == <span class="hljs-keyword">null</span> || invokers.isEmpty())
+ <span class="hljs-keyword">return</span> <span class="hljs-keyword">null</span>;
+ <span class="hljs-comment">// 获取调用方法名</span>
+ String methodName = invocation == <span class="hljs-keyword">null</span> ? <span class="hljs-string">""</span> : invocation.getMethodName();
+
+ <span class="hljs-comment">// 获取 sticky 配置,sticky 表示粘滞连接。所谓粘滞连接是指让服务消费者尽可能的</span>
+ <span class="hljs-comment">// 调用同一个服务提供者,除非该提供者挂了再进行切换</span>
+ <span class="hljs-keyword">boolean</span> sticky = invokers.get(<span class="hljs-number">0</span>).getUrl().getMethodParameter(methodName, Constants.CLUSTER_STICKY_KEY, Constants.DEFAULT_CLUSTER_STICKY);
+ {
+ <span class="hljs-comment">// 检测 invokers 列表是否包含 stickyInvoker,如果不包含,</span>
+ <span class="hljs-comment">// 说明 stickyInvoker 代表的服务提供者挂了,此时需要将其置空</span>
+ <span class="hljs-keyword">if</span> (stickyInvoker != <span class="hljs-keyword">null</span> && !invokers.contains(stickyInvoker)) {
+ stickyInvoker = <span class="hljs-keyword">null</span>;
+ }
+
+ <span class="hljs-comment">// 在 sticky 为 true,且 stickyInvoker != null 的情况下。如果 selected 包含 </span>
+ <span class="hljs-comment">// stickyInvoker,表明 stickyInvoker 对应的服务提供者可能因网络原因未能成功提供服务。</span>
+ <span class="hljs-comment">// 但是该提供者并没挂,此时 invokers 列表中仍存在该服务提供者对应的 Invoker。</span>
+ <span class="hljs-keyword">if</span> (sticky && stickyInvoker != <span class="hljs-keyword">null</span> && (selected == <span class="hljs-keyword">null</span> || !selected.contains(stickyInvoker))) {
+ <span class="hljs-comment">// availablecheck 表示是否开启了可用性检查,如果开启了,则调用 stickyInvoker 的 </span>
+ <span class="hljs-comment">// isAvailable 方法进行检查,如果检查通过,则直接返回 stickyInvoker。</span>
+ <span class="hljs-keyword">if</span> (availablecheck && stickyInvoker.isAvailable()) {
+ <span class="hljs-keyword">return</span> stickyInvoker;
+ }
+ }
+ }
+
+ <span class="hljs-comment">// 如果线程走到当前代码处,说明前面的 stickyInvoker 为空,或者不可用。</span>
+ <span class="hljs-comment">// 此时继续调用 doSelect 选择 Invoker</span>
+ Invoker<T> invoker = doSelect(loadbalance, invocation, invokers, selected);
+
+ <span class="hljs-comment">// 如果 sticky 为 true,则将负载均衡组件选出的 Invoker 赋值给 stickyInvoker</span>
+ <span class="hljs-keyword">if</span> (sticky) {
+ stickyInvoker = invoker;
+ }
+ <span class="hljs-keyword">return</span> invoker;
+}
+</code></pre>
+<p>如上,select 方法的主要逻辑集中在了对粘滞连接特性的支持上。首先是获取 sticky 配置,然后再检测 invokers 列表中是否包含 stickyInvoker,如果不包含,则认为该 stickyInvoker 不可用,此时将其置空。这里的 invokers 列表可以看做是<strong>存活着的服务提供者</strong>列表,如果这个列表不包含 stickyInvoker,那自然而然的认为 stickyInvoker 挂了,所以置空。如果 stickyInvoker 存在于 invokers 列表中,此时要进行下一项检测 — 检测 selected 中是否包含 stickyInvoker。如果包含的话,说明 stickyInvoker 在此之前没有成功提供服务(但其仍然处于存活状态)。此时我们认为这个服务不可靠,不应该在重试期间内再次被调用,因此这个时候不会返回该 stickyInvoker。如果 selected 不包含 stickyInvoker,此时还需要进行可用性检测,比如检测服务提供者网络连通性等。当可用性检测
通过,才可返回 stickyI [...]
+<p>以上就是 select 方法的逻辑,这段逻辑看起来不是很复杂,但是信息量比较大。不搞懂 invokers 和 selected 两个入参的含义,以及粘滞连接特性,这段代码是不容易看懂的。所以大家在阅读这段代码时,不要忽略了对背景知识的理解。关于 select 方法先分析这么多,继续向下分析。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">private</span> Invoker<T> <span class="hljs-title">doSelect</span><span class="hljs-params">(LoadBalance loadbalance, Invocation invocation, List<Invoker<T>> invokers, List<Invoker<T>> selected)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
+ <span class="hljs-keyword">if</span> (invokers == <span class="hljs-keyword">null</span> || invokers.isEmpty())
+ <span class="hljs-keyword">return</span> <span class="hljs-keyword">null</span>;
+ <span class="hljs-keyword">if</span> (invokers.size() == <span class="hljs-number">1</span>)
+ <span class="hljs-keyword">return</span> invokers.get(<span class="hljs-number">0</span>);
+ <span class="hljs-keyword">if</span> (loadbalance == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 如果 loadbalance 为空,这里通过 SPI 加载 Loadbalance,默认为 RandomLoadBalance</span>
+ loadbalance = ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(Constants.DEFAULT_LOADBALANCE);
+ }
+
+ <span class="hljs-comment">// 通过负载均衡组件选择 Invoker</span>
+ Invoker<T> invoker = loadbalance.select(invokers, getUrl(), invocation);
+
+ <span class="hljs-comment">// 如果 selected 包含负载均衡选择出的 Invoker,或者该 Invoker 无法经过可用性检查,此时进行重选</span>
+ <span class="hljs-keyword">if</span> ((selected != <span class="hljs-keyword">null</span> && selected.contains(invoker))
+ || (!invoker.isAvailable() && getUrl() != <span class="hljs-keyword">null</span> && availablecheck)) {
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-comment">// 进行重选</span>
+ Invoker<T> rinvoker = reselect(loadbalance, invocation, invokers, selected, availablecheck);
+ <span class="hljs-keyword">if</span> (rinvoker != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 如果 rinvoker 不为空,则将其赋值给 invoker</span>
+ invoker = rinvoker;
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-comment">// rinvoker 为空,定位 invoker 在 invokers 中的位置</span>
+ <span class="hljs-keyword">int</span> index = invokers.indexOf(invoker);
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-comment">// 获取 index + 1 位置处的 Invoker,以下代码等价于:</span>
+ <span class="hljs-comment">// invoker = invokers.get((index + 1) % invokers.size());</span>
+ invoker = index < invokers.size() - <span class="hljs-number">1</span> ? invokers.get(index + <span class="hljs-number">1</span>) : invokers.get(<span class="hljs-number">0</span>);
+ } <span class="hljs-keyword">catch</span> (Exception e) {
+ logger.warn(<span class="hljs-string">"... may because invokers list dynamic change, ignore."</span>);
+ }
+ }
+ } <span class="hljs-keyword">catch</span> (Throwable t) {
+ logger.error(<span class="hljs-string">"cluster reselect fail reason is : ..."</span>);
+ }
+ }
+ <span class="hljs-keyword">return</span> invoker;
+}
+</code></pre>
+<p>doSelect 主要做了两件事,第一是通过负载均衡组件选择 Invoker。第二是,如果选出来的 Invoker 不稳定,或不可用,此时需要调用 reselect 方法进行重选。若 reselect 选出来的 Invoker 为空,此时定位 invoker 在 invokers 列表中的位置 index,然后获取 index + 1 处的 invoker,这也可以看做是重选逻辑的一部分。下面我们来看一下 reselect 方法的逻辑。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">private</span> Invoker<T> <span class="hljs-title">reselect</span><span class="hljs-params">(LoadBalance loadbalance, Invocation invocation,
+ List<Invoker<T>> invokers, List<Invoker<T>> selected, <span class="hljs-keyword">boolean</span> availablecheck)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
+
+ List<Invoker<T>> reselectInvokers = <span class="hljs-keyword">new</span> ArrayList<Invoker<T>>(invokers.size() > <span class="hljs-number">1</span> ? (invokers.size() - <span class="hljs-number">1</span>) : invokers.size());
+
+ <span class="hljs-comment">// 下面的 if-else 分支逻辑有些冗余,pull request #2826 对这段代码进行了简化,可以参考一下</span>
+ <span class="hljs-comment">// 根据 availablecheck 进行不同的处理</span>
+ <span class="hljs-keyword">if</span> (availablecheck) {
+ <span class="hljs-comment">// 遍历 invokers 列表</span>
+ <span class="hljs-keyword">for</span> (Invoker<T> invoker : invokers) {
+ <span class="hljs-comment">// 检测可用性</span>
+ <span class="hljs-keyword">if</span> (invoker.isAvailable()) {
+ <span class="hljs-comment">// 如果 selected 列表不包含当前 invoker,则将其添加到 reselectInvokers 中</span>
+ <span class="hljs-keyword">if</span> (selected == <span class="hljs-keyword">null</span> || !selected.contains(invoker)) {
+ reselectInvokers.add(invoker);
+ }
+ }
+ }
+
+ <span class="hljs-comment">// reselectInvokers 不为空,此时通过负载均衡组件进行选择</span>
+ <span class="hljs-keyword">if</span> (!reselectInvokers.isEmpty()) {
+ <span class="hljs-keyword">return</span> loadbalance.select(reselectInvokers, getUrl(), invocation);
+ }
+
+ <span class="hljs-comment">// 不检查 Invoker 可用性</span>
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-keyword">for</span> (Invoker<T> invoker : invokers) {
+ <span class="hljs-comment">// 如果 selected 列表不包含当前 invoker,则将其添加到 reselectInvokers 中</span>
+ <span class="hljs-keyword">if</span> (selected == <span class="hljs-keyword">null</span> || !selected.contains(invoker)) {
+ reselectInvokers.add(invoker);
+ }
+ }
+ <span class="hljs-keyword">if</span> (!reselectInvokers.isEmpty()) {
+ <span class="hljs-comment">// 通过负载均衡组件进行选择</span>
+ <span class="hljs-keyword">return</span> loadbalance.select(reselectInvokers, getUrl(), invocation);
+ }
+ }
+
+ {
+ <span class="hljs-comment">// 若线程走到此处,说明 reselectInvokers 集合为空,此时不会调用负载均衡组件进行筛选。</span>
+ <span class="hljs-comment">// 这里从 selected 列表中查找可用的 Invoker,并将其添加到 reselectInvokers 集合中</span>
+ <span class="hljs-keyword">if</span> (selected != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">for</span> (Invoker<T> invoker : selected) {
+ <span class="hljs-keyword">if</span> ((invoker.isAvailable())
+ && !reselectInvokers.contains(invoker)) {
+ reselectInvokers.add(invoker);
+ }
+ }
+ }
+ <span class="hljs-keyword">if</span> (!reselectInvokers.isEmpty()) {
+ <span class="hljs-comment">// 再次进行选择,并返回选择结果</span>
+ <span class="hljs-keyword">return</span> loadbalance.select(reselectInvokers, getUrl(), invocation);
+ }
+ }
+ <span class="hljs-keyword">return</span> <span class="hljs-keyword">null</span>;
+}
+</code></pre>
+<p>reselect 方法总结下来其实只做了两件事情,第一是查找可用的 Invoker,并将其添加到 reselectInvokers 集合中。第二,如果 reselectInvokers 不为空,则通过负载均衡组件再次进行选择。其中第一件事情又可进行细分,一开始,reselect 从 invokers 列表中查找有效可用的 Invoker,若未能找到,此时再到 selected 列表中继续查找。关于 reselect 方法就先分析到这,继续分析其他的 Cluster Invoker。</p>
+<h4>3.2.2 FailbackClusterInvoker</h4>
+<p>FailbackClusterInvoker 会在调用失败后,返回一个空结果给服务提供者。并通过定时任务对失败的调用进行重传,适合执行消息通知等操作。下面来看一下它的实现逻辑。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FailbackClusterInvoker</span><<span class="hljs-title">T</span>> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractClusterInvoker</span><<span class="hljs-title">T</span>> </span>{
+
+ <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">long</span> RETRY_FAILED_PERIOD = <span class="hljs-number">5</span> * <span class="hljs-number">1000</span>;
+
+ <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(<span class="hljs-number">2</span>,
+ <span class="hljs-keyword">new</span> NamedInternalThreadFactory(<span class="hljs-string">"failback-cluster-timer"</span>, <span class="hljs-keyword">true</span>));
+
+ <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> ConcurrentMap<Invocation, AbstractClusterInvoker<?>> failed = <span class="hljs-keyword">new</span> ConcurrentHashMap<Invocation, AbstractClusterInvoker<?>>();
+ <span class="hljs-keyword">private</span> <span class="hljs-keyword">volatile</span> ScheduledFuture<?> retryFuture;
+
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-function"><span class="hljs-keyword">protected</span> Result <span class="hljs-title">doInvoke</span><span class="hljs-params">(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
+ <span class="hljs-keyword">try</span> {
+ checkInvokers(invokers, invocation);
+ <span class="hljs-comment">// 选择 Invoker</span>
+ Invoker<T> invoker = select(loadbalance, invocation, invokers, <span class="hljs-keyword">null</span>);
+ <span class="hljs-comment">// 进行调用</span>
+ <span class="hljs-keyword">return</span> invoker.invoke(invocation);
+ } <span class="hljs-keyword">catch</span> (Throwable e) {
+ <span class="hljs-comment">// 如果调用过程中发生异常,此时仅打印错误日志,不抛出异常</span>
+ logger.error(<span class="hljs-string">"Failback to invoke method ..."</span>);
+
+ <span class="hljs-comment">// 记录调用信息</span>
+ addFailed(invocation, <span class="hljs-keyword">this</span>);
+ <span class="hljs-comment">// 返回一个空结果给服务消费者</span>
+ <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> RpcResult();
+ }
+ }
+
+ <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">addFailed</span><span class="hljs-params">(Invocation invocation, AbstractClusterInvoker<?> router)</span> </span>{
+ <span class="hljs-keyword">if</span> (retryFuture == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">synchronized</span> (<span class="hljs-keyword">this</span>) {
+ <span class="hljs-keyword">if</span> (retryFuture == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 创建定时任务,每隔5秒执行一次</span>
+ retryFuture = scheduledExecutorService.scheduleWithFixedDelay(<span class="hljs-keyword">new</span> Runnable() {
+
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span><span class="hljs-params">()</span> </span>{
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-comment">// 对失败的调用进行重试</span>
+ retryFailed();
+ } <span class="hljs-keyword">catch</span> (Throwable t) {
+ <span class="hljs-comment">// 如果发生异常,仅打印异常日志,不抛出</span>
+ logger.error(<span class="hljs-string">"Unexpected error occur at collect statistic"</span>, t);
+ }
+ }
+ }, RETRY_FAILED_PERIOD, RETRY_FAILED_PERIOD, TimeUnit.MILLISECONDS);
+ }
+ }
+ }
+
+ <span class="hljs-comment">// 添加 invocation 和 invoker 到 failed 中</span>
+ failed.put(invocation, router);
+ }
+
+ <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">retryFailed</span><span class="hljs-params">()</span> </span>{
+ <span class="hljs-keyword">if</span> (failed.size() == <span class="hljs-number">0</span>) {
+ <span class="hljs-keyword">return</span>;
+ }
+
+ <span class="hljs-comment">// 遍历 failed,对失败的调用进行重试</span>
+ <span class="hljs-keyword">for</span> (Map.Entry<Invocation, AbstractClusterInvoker<?>> entry : <span class="hljs-keyword">new</span> HashMap<Invocation, AbstractClusterInvoker<?>>(failed).entrySet()) {
+ Invocation invocation = entry.getKey();
+ Invoker<?> invoker = entry.getValue();
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-comment">// 再次进行调用</span>
+ invoker.invoke(invocation);
+ <span class="hljs-comment">// 调用成功后,从 failed 中移除 invoker</span>
+ failed.remove(invocation);
+ } <span class="hljs-keyword">catch</span> (Throwable e) {
+ <span class="hljs-comment">// 仅打印异常,不抛出</span>
+ logger.error(<span class="hljs-string">"Failed retry to invoke method ..."</span>);
+ }
+ }
+ }
+}
+</code></pre>
+<p>这个类主要由3个方法组成,首先是 doInvoker,该方法负责初次的远程调用。若远程调用失败,则通过 addFailed 方法将调用信息存入到 failed 中,等待定时重试。addFailed 在开始阶段会根据 retryFuture 为空与否,来决定是否开启定时任务。retryFailed 方法则是包含了失败重试的逻辑,该方法会对 failed 进行遍历,然后依次对 Invoker 进行调用。调用成功则将 Invoker 从 failed 中移除,调用失败则忽略失败原因。</p>
+<p>以上就是 FailbackClusterInvoker 的执行逻辑,不是很复杂,继续往下看。</p>
+<h4>3.2.3 FailfastClusterInvoker</h4>
+<p>FailfastClusterInvoker 只会进行一次调用,失败后立即抛出异常。适用于幂等操作,比如新增记录。源码如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FailfastClusterInvoker</span><<span class="hljs-title">T</span>> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractClusterInvoker</span><<span class="hljs-title">T</span>> </span>{
+
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-function"><span class="hljs-keyword">public</span> Result <span class="hljs-title">doInvoke</span><span class="hljs-params">(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
+ checkInvokers(invokers, invocation);
+ <span class="hljs-comment">// 选择 Invoker</span>
+ Invoker<T> invoker = select(loadbalance, invocation, invokers, <span class="hljs-keyword">null</span>);
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-comment">// 调用 Invoker</span>
+ <span class="hljs-keyword">return</span> invoker.invoke(invocation);
+ } <span class="hljs-keyword">catch</span> (Throwable e) {
+ <span class="hljs-keyword">if</span> (e <span class="hljs-keyword">instanceof</span> RpcException && ((RpcException) e).isBiz()) {
+ <span class="hljs-comment">// 抛出异常</span>
+ <span class="hljs-keyword">throw</span> (RpcException) e;
+ }
+ <span class="hljs-comment">// 抛出异常</span>
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RpcException(..., <span class="hljs-string">"Failfast invoke providers ..."</span>);
+ }
+ }
+}
+</code></pre>
+<p>如上,首先是通过 select 方法选择 Invoker,然后进行远程调用。如果调用失败,则立即抛出异常。FailfastClusterInvoker 就先分析到这,下面分析 FailsafeClusterInvoker。</p>
+<h4>3.2.4 FailsafeClusterInvoker</h4>
+<p>FailsafeClusterInvoker 是一种失败安全的 Cluster Invoker。所谓的失败安全是指,当调用过程中出现异常时,FailsafeClusterInvoker 仅会打印异常,而不会抛出异常。适用于写入审计日志等操作。下面分析源码。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FailsafeClusterInvoker</span><<span class="hljs-title">T</span>> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractClusterInvoker</span><<span class="hljs-title">T</span>> </span>{
+
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-function"><span class="hljs-keyword">public</span> Result <span class="hljs-title">doInvoke</span><span class="hljs-params">(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
+ <span class="hljs-keyword">try</span> {
+ checkInvokers(invokers, invocation);
+ <span class="hljs-comment">// 选择 Invoker</span>
+ Invoker<T> invoker = select(loadbalance, invocation, invokers, <span class="hljs-keyword">null</span>);
+ <span class="hljs-comment">// 进行远程调用</span>
+ <span class="hljs-keyword">return</span> invoker.invoke(invocation);
+ } <span class="hljs-keyword">catch</span> (Throwable e) {
+ <span class="hljs-comment">// 打印错误日志,但不抛出</span>
+ logger.error(<span class="hljs-string">"Failsafe ignore exception: "</span> + e.getMessage(), e);
+ <span class="hljs-comment">// 返回空结果忽略错误</span>
+ <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> RpcResult();
+ }
+ }
+}
+</code></pre>
+<p>FailsafeClusterInvoker 的逻辑和 FailfastClusterInvoker 的逻辑一样简单,无需过多说明。继续向下分析。</p>
+<h4>3.2.5 ForkingClusterInvoker</h4>
+<p>ForkingClusterInvoker 会在运行时通过线程池创建多个线程,并发调用多个服务提供者。只要有一个服务提供者成功返回了结果,doInvoke 方法就会立即结束运行。ForkingClusterInvoker 的应用场景是在一些对实时性要求比较高<strong>读操作</strong>(注意是读操作,并行写操作可能不安全)下使用,但这将会耗费更多的资源。下面来看该类的实现。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ForkingClusterInvoker</span><<span class="hljs-title">T</span>> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractClusterInvoker</span><<span class="hljs-title">T</span>> </span>{
+
+ <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> ExecutorService executor = Executors.newCachedThreadPool(
+ <span class="hljs-keyword">new</span> NamedInternalThreadFactory(<span class="hljs-string">"forking-cluster-timer"</span>, <span class="hljs-keyword">true</span>));
+
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-function"><span class="hljs-keyword">public</span> Result <span class="hljs-title">doInvoke</span><span class="hljs-params">(<span class="hljs-keyword">final</span> Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
+ <span class="hljs-keyword">try</span> {
+ checkInvokers(invokers, invocation);
+ <span class="hljs-keyword">final</span> List<Invoker<T>> selected;
+ <span class="hljs-comment">// 获取 forks 配置</span>
+ <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> forks = getUrl().getParameter(Constants.FORKS_KEY, Constants.DEFAULT_FORKS);
+ <span class="hljs-comment">// 获取超时配置</span>
+ <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> timeout = getUrl().getParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT);
+ <span class="hljs-comment">// 如果 forks 配置不合理,则直接将 invokers 赋值给 selected</span>
+ <span class="hljs-keyword">if</span> (forks <= <span class="hljs-number">0</span> || forks >= invokers.size()) {
+ selected = invokers;
+ } <span class="hljs-keyword">else</span> {
+ selected = <span class="hljs-keyword">new</span> ArrayList<Invoker<T>>();
+ <span class="hljs-comment">// 循环选出 forks 个 Invoker,并添加到 selected 中</span>
+ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < forks; i++) {
+ <span class="hljs-comment">// 选择 Invoker</span>
+ Invoker<T> invoker = select(loadbalance, invocation, invokers, selected);
+ <span class="hljs-keyword">if</span> (!selected.contains(invoker)) {
+ selected.add(invoker);
+ }
+ }
+ }
+
+ <span class="hljs-comment">// ----------------------✨ 分割线1 ✨---------------------- //</span>
+
+ RpcContext.getContext().setInvokers((List) selected);
+ <span class="hljs-keyword">final</span> AtomicInteger count = <span class="hljs-keyword">new</span> AtomicInteger();
+ <span class="hljs-keyword">final</span> BlockingQueue<Object> ref = <span class="hljs-keyword">new</span> LinkedBlockingQueue<Object>();
+ <span class="hljs-comment">// 遍历 selected 列表</span>
+ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">final</span> Invoker<T> invoker : selected) {
+ <span class="hljs-comment">// 为每个 Invoker 创建一个执行线程</span>
+ executor.execute(<span class="hljs-keyword">new</span> Runnable() {
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span><span class="hljs-params">()</span> </span>{
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-comment">// 进行远程调用</span>
+ Result result = invoker.invoke(invocation);
+ <span class="hljs-comment">// 将结果存到阻塞队列中</span>
+ ref.offer(result);
+ } <span class="hljs-keyword">catch</span> (Throwable e) {
+ <span class="hljs-keyword">int</span> value = count.incrementAndGet();
+ <span class="hljs-comment">// 仅在 value 大于等于 selected.size() 时,才将异常对象</span>
+ <span class="hljs-comment">// 放入阻塞队列中,请大家思考一下为什么要这样做。</span>
+ <span class="hljs-keyword">if</span> (value >= selected.size()) {
+ <span class="hljs-comment">// 将异常对象存入到阻塞队列中</span>
+ ref.offer(e);
+ }
+ }
+ }
+ });
+ }
+
+ <span class="hljs-comment">// ----------------------✨ 分割线2 ✨---------------------- //</span>
+
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-comment">// 从阻塞队列中取出远程调用结果</span>
+ Object ret = ref.poll(timeout, TimeUnit.MILLISECONDS);
+
+ <span class="hljs-comment">// 如果结果类型为 Throwable,则抛出异常</span>
+ <span class="hljs-keyword">if</span> (ret <span class="hljs-keyword">instanceof</span> Throwable) {
+ Throwable e = (Throwable) ret;
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RpcException(..., <span class="hljs-string">"Failed to forking invoke provider ..."</span>);
+ }
+
+ <span class="hljs-comment">// 返回结果</span>
+ <span class="hljs-keyword">return</span> (Result) ret;
+ } <span class="hljs-keyword">catch</span> (InterruptedException e) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RpcException(<span class="hljs-string">"Failed to forking invoke provider ..."</span>);
+ }
+ } <span class="hljs-keyword">finally</span> {
+ RpcContext.getContext().clearAttachments();
+ }
+ }
+}
+</code></pre>
+<p>ForkingClusterInvoker 的 doInvoker 方法比较长,这里通过两个分割线将整个方法划分为三个逻辑块。从方法开始到分割线1之间的代码主要是用于选出 forks 个 Invoker,为接下来的并发调用提供输入。分割线1和分割线2之间的逻辑通过线程池并发调用多个 Invoker,并将结果存储在阻塞队列中。分割线2到方法结尾之间的逻辑主要用于从阻塞队列中获取返回结果,并对返回结果类型进行判断。如果为异常类型,则直接抛出,否则返回。</p>
+<p>以上就是ForkingClusterInvoker 的 doInvoker 方法大致过程。我们在分割线1和分割线2之间的代码上留了一个问题,问题是这样的:为什么要在<code>value >= selected.size()</code>的情况下,才将异常对象添加到阻塞队列中?这里来解答一下。原因是这样的,在并行调用多个服务提供者的情况下,只要有一个服务提供者能够成功返回结果,而其他全部失败。此时 ForkingClusterInvoker 仍应该返回成功的结果,而非抛出异常。在<code>value >= selected.size()</code>时将异常对象放入阻塞队列中,可以保证异常对象不会出现在正常结果的前面,这样可从阻塞队列中优先取出正常的结果。</p>
+<p>关于 ForkingClusterInvoker 就先分析到这,接下来分析最后一个 Cluster Invoker。</p>
+<h4>3.2.6 BroadcastClusterInvoker</h4>
+<p>本章的最后,我们再来看一下 BroadcastClusterInvoker。BroadcastClusterInvoker 会逐个调用每个服务提供者,如果其中一台报错,在循环调用结束后,BroadcastClusterInvoker 会抛出异常。该类通常用于通知所有提供者更新缓存或日志等本地资源信息。源码如下。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">BroadcastClusterInvoker</span><<span class="hljs-title">T</span>> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractClusterInvoker</span><<span class="hljs-title">T</span>> </span>{
+
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-function"><span class="hljs-keyword">public</span> Result <span class="hljs-title">doInvoke</span><span class="hljs-params">(<span class="hljs-keyword">final</span> Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
+ checkInvokers(invokers, invocation);
+ RpcContext.getContext().setInvokers((List) invokers);
+ RpcException exception = <span class="hljs-keyword">null</span>;
+ Result result = <span class="hljs-keyword">null</span>;
+ <span class="hljs-comment">// 遍历 Invoker 列表,逐个调用</span>
+ <span class="hljs-keyword">for</span> (Invoker<T> invoker : invokers) {
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-comment">// 进行远程调用</span>
+ result = invoker.invoke(invocation);
+ } <span class="hljs-keyword">catch</span> (RpcException e) {
+ exception = e;
+ logger.warn(e.getMessage(), e);
+ } <span class="hljs-keyword">catch</span> (Throwable e) {
+ exception = <span class="hljs-keyword">new</span> RpcException(e.getMessage(), e);
+ logger.warn(e.getMessage(), e);
+ }
+ }
+
+ <span class="hljs-comment">// exception 不为空,则抛出异常</span>
+ <span class="hljs-keyword">if</span> (exception != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">throw</span> exception;
+ }
+ <span class="hljs-keyword">return</span> result;
+ }
+}
+</code></pre>
+<p>以上就是 BroadcastClusterInvoker 的代码,比较简单,就不多说了。</p>
+<h2>4.总结</h2>
+<p>本篇文章详细分析了集群容错的几种实现方式。集群容错对于 Dubbo 框架来说,是很重要的逻辑。集群模块处于服务提供者和消费者之间,对于服务消费者来说,集群可向其屏蔽服务提供者集群的情况,使其能够专心进行远程调用。除此之外,通过集群模块,我们还可以对服务之间的调用链路进行编排优化,治理服务。总的来说,对于 Dubbo 而言,集群容错相关逻辑是非常重要的。想要对 Dubbo 有比较深的理解,集群容错是必须要掌握的。</p>
+<p>关于集群模块就先分析到这,感谢阅读。</p>
+</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
+ <script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+ <script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+ <script>
+ window.rootPath = '';
+ </script>
+ <script src="/build/documentation.js"></script>
+ <!-- Global site tag (gtag.js) - Google Analytics -->
+ <script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+ <script>
+ window.dataLayer = window.dataLayer || [];
+ function gtag(){dataLayer.push(arguments);}
+ gtag('js', new Date());
+
+ gtag('config', 'UA-112489517-1');
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/zh-cn/docs/source_code_guide/cluster.json b/zh-cn/docs/source_code_guide/cluster.json
new file mode 100644
index 0000000..9c933f7
--- /dev/null
+++ b/zh-cn/docs/source_code_guide/cluster.json
@@ -0,0 +1,10 @@
+{
+ "filename": "cluster.md",
+ "__html": "<h2>1.简介</h2>\n<p>为了避免单点故障,现在的应用通常至少会部署在两台服务器上。对于一些负载比较高的服务,会部署更多的服务器。这样,在同一环境下的服务提供者数量会大于1。对于服务消费者来说,同一环境下出现了多个服务提供者。这时会出现一个问题,服务消费者需要决定选择哪个服务提供者进行调用。另外服务调用失败时的处理措施也是需要考虑的,是重试呢,还是抛出异常,亦或是只打印异常等。为了处理这些问题,Dubbo 定义了集群接口 Cluster 以及 Cluster Invoker。集群 Cluster 用途是将多个服务提供者合并为一个 Cluster Invoker,并将这个 Invoker 暴露给服务消费者。这样一来,服务消费者只需通过这个 Invoker 进行远程调用即可,至于具体调用哪个服务提供者,以及调用失败后如何处理等问题,现在都交给集群模块去处理。集�
�模块是服务提供者和服务消费者的中间层,为服务消费者屏蔽了服务提供者的情况,这样服务消费者就可以专心处理远程调用相关事宜。比如发请求,接受服务提供者返回的数据等。这就是集群的作用。< [...]
+ "link": "/zh-cn/docs/source_code_guide/cluster.html",
+ "meta": {
+ "title": "集群",
+ "keywords": "Dubbo, Cluster",
+ "description": "本文介绍了集群的原理和实现细节"
+ }
+}
\ No newline at end of file
diff --git a/zh-cn/docs/source_code_guide/directory.html b/zh-cn/docs/source_code_guide/directory.html
new file mode 100644
index 0000000..d7e97e1
--- /dev/null
+++ b/zh-cn/docs/source_code_guide/directory.html
@@ -0,0 +1,516 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <meta name="keywords" content="Dubbo, Directory" />
+ <meta name="description" content="本文介绍了服务目录的原理和实现细节" />
+ <!-- 网页标签标题 -->
+ <title>服务目录</title>
+ <link rel="shortcut icon" href="/img/dubbo.ico"/>
+ <link rel="stylesheet" href="/build/documentation.css" />
+</head>
+<body>
+ <div id="root"><div class="documentation-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a [...]
+<p>本篇文章,将开始分析 Dubbo 集群容错方面的源码。集群容错源码包含四个部分,分别是服务目录 Directory、服务路由 Router、集群 Cluster 和负载均衡 LoadBalance。这几个部分的源码逻辑相对比较独立,我们将会分四篇文章进行分析。本篇文章作为集群容错的开篇文章,将和大家一起分析服务目录相关的源码。在进行深入分析之前,我们先来了解一下服务目录是什么。服务目录中存储了一些和服务提供者有关的信息,通过服务目录,服务消费者可获取到服务提供者的信息,比如 ip、端口、服务协议等。通过这些信息,服务消费者就可通过 Netty 等客户端进行远程调用。在一个服务集群中,服务提供者数量并不是一成不变的,如果集群中新增了一台机器,相应地在服务目录中就要新增一条服务提供者记录。或者,如果服务提供者的配置修改了,服务目录
中的记录也要做相应的更新。如果这样说,服务目录和注册中心的功能不就雷同了吗?确实如此,这里这么说是为了方便大家理解。实际上服务目录在获取注册中心的服务配置信息后,会为每条配置信息生成一个 Invoker 对象,并把这个 Invoker 对象存 [...]
+<p>关于服务目录这里就先介绍这些,大家先有个大致印象。接下来我们通过继承体系图来了解一下服务目录的家族成员都有哪些。</p>
+<h2>2. 继承体系</h2>
+<p>服务目录目前内置的实现有两个,分别为 StaticDirectory 和 RegistryDirectory,它们均是 AbstractDirectory 的子类。AbstractDirectory 实现了 Directory 接口,这个接口包含了一个重要的方法定义,即 list(Invocation),用于列举 Invoker。下面我们来看一下他们的继承体系图。</p>
+<p><img src="./sources/images/directory-inherit-hierarchy.png" alt=""></p>
+<p>如上,Directory 继承自 Node 接口,Node 这个接口继承者比较多,像 Registry、Monitor、Invoker 等均继承了这个接口。这个接口包含了一个获取配置信息的方法 getUrl,实现该接口的类可以向外提供配置信息。另外,大家注意看 RegistryDirectory 实现了 NotifyListener 接口,当注册中心节点信息发生变化后,RegistryDirectory 可以通过此接口方法得到变更信息,并根据变更信息动态调整内部 Invoker 列表。</p>
+<h2>3. 源码分析</h2>
+<p>本章将分析 AbstractDirectory 和它两个子类的源码。AbstractDirectory 封装了 Invoker 列举流程,具体的列举逻辑则由子类实现,这是典型的模板模式。所以,接下来我们先来看一下 AbstractDirectory 的源码。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> List<Invoker<T>> list(Invocation invocation) <span class="hljs-keyword">throws</span> RpcException {
+ <span class="hljs-keyword">if</span> (destroyed) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RpcException(<span class="hljs-string">"Directory already destroyed..."</span>);
+ }
+
+ <span class="hljs-comment">// 调用 doList 方法列举 Invoker,doList 是模板方法,由子类实现</span>
+ List<Invoker<T>> invokers = doList(invocation);
+
+ <span class="hljs-comment">// 获取路由 Router 列表</span>
+ List<Router> localRouters = <span class="hljs-keyword">this</span>.routers;
+ <span class="hljs-keyword">if</span> (localRouters != <span class="hljs-keyword">null</span> && !localRouters.isEmpty()) {
+ <span class="hljs-keyword">for</span> (Router router : localRouters) {
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-comment">// 获取 runtime 参数,并根据参数决定是否进行路由</span>
+ <span class="hljs-keyword">if</span> (router.getUrl() == <span class="hljs-keyword">null</span> || router.getUrl().getParameter(Constants.RUNTIME_KEY, <span class="hljs-keyword">false</span>)) {
+ <span class="hljs-comment">// 进行服务路由</span>
+ invokers = router.route(invokers, getConsumerUrl(), invocation);
+ }
+ } <span class="hljs-keyword">catch</span> (Throwable t) {
+ logger.error(<span class="hljs-string">"Failed to execute router: ..."</span>);
+ }
+ }
+ }
+ <span class="hljs-keyword">return</span> invokers;
+}
+
+<span class="hljs-comment">// 模板方法,由子类实现</span>
+<span class="hljs-keyword">protected</span> <span class="hljs-keyword">abstract</span> List<Invoker<T>> doList(Invocation invocation) <span class="hljs-keyword">throws</span> RpcException;
+</code></pre>
+<p>上面就是 AbstractDirectory 的 list 方法源码,这个方法封装了 Invoker 的列举过程。如下:</p>
+<ol>
+<li>调用 doList 获取 Invoker 列表</li>
+<li>根据 Router 的 getUrl 返回值为空与否,以及 runtime 参数决定是否进行服务路由</li>
+</ol>
+<p>以上步骤中,doList 是模板方法,需由子类实现。Router 的 runtime 参数这里简单说明一下,这个参数决定了是否在每次调用服务时都执行路由规则。如果 runtime 为 true,那么每次调用服务前,都需要进行服务路由。这个对性能造成影响,配置时需要注意。</p>
+<p>关于 AbstractDirectory 就分析这么多,下面开始分析子类的源码。</p>
+<h3>3.1 StaticDirectory</h3>
+<p>StaticDirectory 即静态服务目录,顾名思义,它内部存放的 Invoker 是不会变动的。所以,理论上它和不可变 List 的功能很相似。下面我们来看一下这个类的实现。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StaticDirectory</span><<span class="hljs-title">T</span>> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractDirectory</span><<span class="hljs-title">T</span>> </span>{
+
+ <span class="hljs-comment">// Invoker 列表</span>
+ <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> List<Invoker<T>> invokers;
+
+ <span class="hljs-comment">// 省略构造方法</span>
+
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-function"><span class="hljs-keyword">public</span> Class<T> <span class="hljs-title">getInterface</span><span class="hljs-params">()</span> </span>{
+ <span class="hljs-comment">// 获取接口类</span>
+ <span class="hljs-keyword">return</span> invokers.get(<span class="hljs-number">0</span>).getInterface();
+ }
+
+ <span class="hljs-comment">// 检测服务目录是否可用</span>
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">isAvailable</span><span class="hljs-params">()</span> </span>{
+ <span class="hljs-keyword">if</span> (isDestroyed()) {
+ <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
+ }
+ <span class="hljs-keyword">for</span> (Invoker<T> invoker : invokers) {
+ <span class="hljs-keyword">if</span> (invoker.isAvailable()) {
+ <span class="hljs-comment">// 只要有一个 Invoker 是可用的,就认为当前目录是可用的</span>
+ <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
+ }
+ }
+ <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
+ }
+
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">destroy</span><span class="hljs-params">()</span> </span>{
+ <span class="hljs-keyword">if</span> (isDestroyed()) {
+ <span class="hljs-keyword">return</span>;
+ }
+ <span class="hljs-comment">// 调用父类销毁逻辑</span>
+ <span class="hljs-keyword">super</span>.destroy();
+ <span class="hljs-comment">// 遍历 Invoker 列表,并执行相应的销毁逻辑</span>
+ <span class="hljs-keyword">for</span> (Invoker<T> invoker : invokers) {
+ invoker.destroy();
+ }
+ invokers.clear();
+ }
+
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-keyword">protected</span> List<Invoker<T>> doList(Invocation invocation) <span class="hljs-keyword">throws</span> RpcException {
+ <span class="hljs-comment">// 列举 Inovker,也就是直接返回 invokers 成员变量</span>
+ <span class="hljs-keyword">return</span> invokers;
+ }
+}
+</code></pre>
+<p>以上就是 StaticDirectory 的代码逻辑,很简单,就不多说了。下面来看看 RegistryDirectory,这个类的逻辑比较复杂。</p>
+<h3>3.2 RegistryDirectory</h3>
+<p>RegistryDirectory 是一种动态服务目录,实现了 NotifyListener 接口。当注册中心服务配置发生变化后,RegistryDirectory 可收到与当前服务相关的变化。收到变更通知后,RegistryDirectory 可根据配置变更信息刷新 Invoker 列表。RegistryDirectory 中有几个比较重要的逻辑,第一是 Invoker 的列举逻辑,第二是接收服务配置变更的逻辑,第三是 Invoker 列表的刷新逻辑。接下来按顺序对这三块逻辑。</p>
+<h4>3.2.1 列举 Invoker</h4>
+<p>Invoker 列举逻辑封装在 doList 方法中,相关代码如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> List<Invoker<T>> doList(Invocation invocation) {
+ <span class="hljs-keyword">if</span> (forbidden) {
+ <span class="hljs-comment">// 服务提供者关闭或禁用了服务,此时抛出 No provider 异常</span>
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RpcException(RpcException.FORBIDDEN_EXCEPTION,
+ <span class="hljs-string">"No provider available from registry ..."</span>);
+ }
+ List<Invoker<T>> invokers = <span class="hljs-keyword">null</span>;
+ <span class="hljs-comment">// 获取 Invoker 本地缓存</span>
+ Map<String, List<Invoker<T>>> localMethodInvokerMap = <span class="hljs-keyword">this</span>.methodInvokerMap;
+ <span class="hljs-keyword">if</span> (localMethodInvokerMap != <span class="hljs-keyword">null</span> && localMethodInvokerMap.size() > <span class="hljs-number">0</span>) {
+ <span class="hljs-comment">// 获取方法名和参数列表</span>
+ String methodName = RpcUtils.getMethodName(invocation);
+ Object[] args = RpcUtils.getArguments(invocation);
+ <span class="hljs-comment">// 检测参数列表的第一个参数是否为 String 或 enum 类型</span>
+ <span class="hljs-keyword">if</span> (args != <span class="hljs-keyword">null</span> && args.length > <span class="hljs-number">0</span> && args[<span class="hljs-number">0</span>] != <span class="hljs-keyword">null</span>
+ && (args[<span class="hljs-number">0</span>] <span class="hljs-keyword">instanceof</span> String || args[<span class="hljs-number">0</span>].getClass().isEnum())) {
+ <span class="hljs-comment">// 通过 方法名 + 第一个参数名称 查询 Invoker 列表,具体的使用场景暂时没想到</span>
+ invokers = localMethodInvokerMap.get(methodName + <span class="hljs-string">"."</span> + args[<span class="hljs-number">0</span>]);
+ }
+ <span class="hljs-keyword">if</span> (invokers == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 通过方法名获取 Invoker 列表</span>
+ invokers = localMethodInvokerMap.get(methodName);
+ }
+ <span class="hljs-keyword">if</span> (invokers == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 通过星号 * 获取 Invoker 列表</span>
+ invokers = localMethodInvokerMap.get(Constants.ANY_VALUE);
+ }
+
+ <span class="hljs-comment">// 冗余逻辑,pull request #2861 移除了下面的 if 分支代码</span>
+ <span class="hljs-keyword">if</span> (invokers == <span class="hljs-keyword">null</span>) {
+ Iterator<List<Invoker<T>>> iterator = localMethodInvokerMap.values().iterator();
+ <span class="hljs-keyword">if</span> (iterator.hasNext()) {
+ invokers = iterator.next();
+ }
+ }
+ }
+
+ <span class="hljs-comment">// 返回 Invoker 列表</span>
+ <span class="hljs-keyword">return</span> invokers == <span class="hljs-keyword">null</span> ? <span class="hljs-keyword">new</span> ArrayList<Invoker<T>>(<span class="hljs-number">0</span>) : invokers;
+}
+</code></pre>
+<p>以上代码进行多次尝试,以期从 localMethodInvokerMap 中获取到 Invoker 列表。一般情况下,普通的调用可通过方法名获取到对应的 Invoker 列表,泛化调用可通过 ***** 获取到 Invoker 列表。localMethodInvokerMap 源自 RegistryDirectory 类的成员变量 methodInvokerMap。doList 方法可以看做是对 methodInvokerMap 变量的读操作,至于对 methodInvokerMap 变量的写操作,下一节进行分析。</p>
+<h4>3.2.2 接收服务变更通知</h4>
+<p>RegistryDirectory 是一个动态服务目录,会随注册中心配置的变化进行动态调整。因此 RegistryDirectory 实现了 NotifyListener 接口,通过这个接口获取注册中心变更通知。下面我们来看一下具体的逻辑。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">synchronized</span> <span class="hljs-keyword">void</span> <span class="hljs-title">notify</span><span class="hljs-params">(List<URL> urls)</span> </span>{
+ <span class="hljs-comment">// 定义三个集合,分别用于存放服务提供者 url,路由 url,配置器 url</span>
+ List<URL> invokerUrls = <span class="hljs-keyword">new</span> ArrayList<URL>();
+ List<URL> routerUrls = <span class="hljs-keyword">new</span> ArrayList<URL>();
+ List<URL> configuratorUrls = <span class="hljs-keyword">new</span> ArrayList<URL>();
+ <span class="hljs-keyword">for</span> (URL url : urls) {
+ String protocol = url.getProtocol();
+ <span class="hljs-comment">// 获取 category 参数</span>
+ String category = url.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY);
+ <span class="hljs-comment">// 根据 category 参数将 url 分别放到不同的列表中</span>
+ <span class="hljs-keyword">if</span> (Constants.ROUTERS_CATEGORY.equals(category)
+ || Constants.ROUTE_PROTOCOL.equals(protocol)) {
+ <span class="hljs-comment">// 添加路由器 url</span>
+ routerUrls.add(url);
+ } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (Constants.CONFIGURATORS_CATEGORY.equals(category)
+ || Constants.OVERRIDE_PROTOCOL.equals(protocol)) {
+ <span class="hljs-comment">// 添加配置器 url</span>
+ configuratorUrls.add(url);
+ } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (Constants.PROVIDERS_CATEGORY.equals(category)) {
+ <span class="hljs-comment">// 添加服务提供者 url</span>
+ invokerUrls.add(url);
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-comment">// 忽略不支持的 category</span>
+ logger.warn(<span class="hljs-string">"Unsupported category ..."</span>);
+ }
+ }
+ <span class="hljs-keyword">if</span> (configuratorUrls != <span class="hljs-keyword">null</span> && !configuratorUrls.isEmpty()) {
+ <span class="hljs-comment">// 将 url 转成 Configurator</span>
+ <span class="hljs-keyword">this</span>.configurators = toConfigurators(configuratorUrls);
+ }
+ <span class="hljs-keyword">if</span> (routerUrls != <span class="hljs-keyword">null</span> && !routerUrls.isEmpty()) {
+ <span class="hljs-comment">// 将 url 转成 Router</span>
+ List<Router> routers = toRouters(routerUrls);
+ <span class="hljs-keyword">if</span> (routers != <span class="hljs-keyword">null</span>) {
+ setRouters(routers);
+ }
+ }
+ List<Configurator> localConfigurators = <span class="hljs-keyword">this</span>.configurators;
+ <span class="hljs-keyword">this</span>.overrideDirectoryUrl = directoryUrl;
+ <span class="hljs-keyword">if</span> (localConfigurators != <span class="hljs-keyword">null</span> && !localConfigurators.isEmpty()) {
+ <span class="hljs-keyword">for</span> (Configurator configurator : localConfigurators) {
+ <span class="hljs-comment">// 配置 overrideDirectoryUrl</span>
+ <span class="hljs-keyword">this</span>.overrideDirectoryUrl = configurator.configure(overrideDirectoryUrl);
+ }
+ }
+
+ <span class="hljs-comment">// 刷新 Invoker 列表</span>
+ refreshInvoker(invokerUrls);
+}
+</code></pre>
+<p>如上,notify 方法首先是根据 url 的 category 参数对 url 进行分门别类存储,然后通过 toRouters 和 toConfigurators 将 url 列表转成 Router 和 Configurator 列表。最后调用 refreshInvoker 方法刷新 Invoker 列表。这里的 toRouters 和 toConfigurators 方法逻辑不复杂,大家自行分析。接下来,我们把重点放在 refreshInvoker 方法上。</p>
+<h4>3.2.3 刷新 Invoker 列表</h4>
+<p>refreshInvoker 方法是保证 RegistryDirectory 随注册中心变化而变化的关键所在。这一块逻辑比较多,接下来一一进行分析。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">refreshInvoker</span><span class="hljs-params">(List<URL> invokerUrls)</span> </span>{
+ <span class="hljs-comment">// invokerUrls 仅有一个元素,且 url 协议头为 empty,此时表示禁用所有服务</span>
+ <span class="hljs-keyword">if</span> (invokerUrls != <span class="hljs-keyword">null</span> && invokerUrls.size() == <span class="hljs-number">1</span> && invokerUrls.get(<span class="hljs-number">0</span>) != <span class="hljs-keyword">null</span>
+ && Constants.EMPTY_PROTOCOL.equals(invokerUrls.get(<span class="hljs-number">0</span>).getProtocol())) {
+ <span class="hljs-comment">// 设置 forbidden 为 true</span>
+ <span class="hljs-keyword">this</span>.forbidden = <span class="hljs-keyword">true</span>;
+ <span class="hljs-keyword">this</span>.methodInvokerMap = <span class="hljs-keyword">null</span>;
+ <span class="hljs-comment">// 销毁所有 Invoker</span>
+ destroyAllInvokers();
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-keyword">this</span>.forbidden = <span class="hljs-keyword">false</span>;
+ Map<String, Invoker<T>> oldUrlInvokerMap = <span class="hljs-keyword">this</span>.urlInvokerMap;
+ <span class="hljs-keyword">if</span> (invokerUrls.isEmpty() && <span class="hljs-keyword">this</span>.cachedInvokerUrls != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 添加缓存 url 到 invokerUrls 中</span>
+ invokerUrls.addAll(<span class="hljs-keyword">this</span>.cachedInvokerUrls);
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-keyword">this</span>.cachedInvokerUrls = <span class="hljs-keyword">new</span> HashSet<URL>();
+ <span class="hljs-comment">// 缓存 invokerUrls</span>
+ <span class="hljs-keyword">this</span>.cachedInvokerUrls.addAll(invokerUrls);
+ }
+ <span class="hljs-keyword">if</span> (invokerUrls.isEmpty()) {
+ <span class="hljs-keyword">return</span>;
+ }
+ <span class="hljs-comment">// 将 url 转成 Invoker</span>
+ Map<String, Invoker<T>> newUrlInvokerMap = toInvokers(invokerUrls);
+ <span class="hljs-comment">// 将 newUrlInvokerMap 转成方法名到 Invoker 列表的映射</span>
+ Map<String, List<Invoker<T>>> newMethodInvokerMap = toMethodInvokers(newUrlInvokerMap);
+ <span class="hljs-comment">// 转换出错,直接打印异常,并返回</span>
+ <span class="hljs-keyword">if</span> (newUrlInvokerMap == <span class="hljs-keyword">null</span> || newUrlInvokerMap.size() == <span class="hljs-number">0</span>) {
+ logger.error(<span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"urls to invokers error ..."</span>));
+ <span class="hljs-keyword">return</span>;
+ }
+ <span class="hljs-comment">// 合并多个组的 Invoker</span>
+ <span class="hljs-keyword">this</span>.methodInvokerMap = multiGroup ? toMergeMethodInvokerMap(newMethodInvokerMap) : newMethodInvokerMap;
+ <span class="hljs-keyword">this</span>.urlInvokerMap = newUrlInvokerMap;
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-comment">// 销毁无用 Invoker</span>
+ destroyUnusedInvokers(oldUrlInvokerMap, newUrlInvokerMap);
+ } <span class="hljs-keyword">catch</span> (Exception e) {
+ logger.warn(<span class="hljs-string">"destroyUnusedInvokers error. "</span>, e);
+ }
+ }
+}
+</code></pre>
+<p>refreshInvoker 方法首先会根据入参 invokerUrls 的数量和协议头判断是否禁用所有的服务,如果禁用,则将 forbidden 设为 true,并销毁所有的 Invoker。若不禁用,则将 url 转成 Invoker,得到 <url, Invoker> 的映射关系。然后进一步进行转换,得到 <methodName, Invoker 列表> 映射关系。之后进行多组 Invoker 合并操作,并将合并结果赋值给 methodInvokerMap。methodInvokerMap 变量在 doList 方法中会被用到,doList 会对该变量进行读操作,在这里是写操作。当新的 Invoker 列表生成后,还要一个重要的工作要做,就是销毁无用的 Invoker,避免服务消费者调用已下线的服务的服务。</p>
+<p>接下来对 refreshInvoker 方法中涉及到的调用一一进行分析。按照顺序,先来分析 url 到 Invoker 的转换过程。</p>
+<pre><code class="language-java"><span class="hljs-keyword">private</span> Map<String, Invoker<T>> toInvokers(List<URL> urls) {
+ Map<String, Invoker<T>> newUrlInvokerMap = <span class="hljs-keyword">new</span> HashMap<String, Invoker<T>>();
+ <span class="hljs-keyword">if</span> (urls == <span class="hljs-keyword">null</span> || urls.isEmpty()) {
+ <span class="hljs-keyword">return</span> newUrlInvokerMap;
+ }
+ Set<String> keys = <span class="hljs-keyword">new</span> HashSet<String>();
+ <span class="hljs-comment">// 获取服务消费端配置的协议</span>
+ String queryProtocols = <span class="hljs-keyword">this</span>.queryMap.get(Constants.PROTOCOL_KEY);
+ <span class="hljs-keyword">for</span> (URL providerUrl : urls) {
+ <span class="hljs-keyword">if</span> (queryProtocols != <span class="hljs-keyword">null</span> && queryProtocols.length() > <span class="hljs-number">0</span>) {
+ <span class="hljs-keyword">boolean</span> accept = <span class="hljs-keyword">false</span>;
+ String[] acceptProtocols = queryProtocols.split(<span class="hljs-string">","</span>);
+ <span class="hljs-comment">// 检测服务提供者协议是否被服务消费者所支持</span>
+ <span class="hljs-keyword">for</span> (String acceptProtocol : acceptProtocols) {
+ <span class="hljs-keyword">if</span> (providerUrl.getProtocol().equals(acceptProtocol)) {
+ accept = <span class="hljs-keyword">true</span>;
+ <span class="hljs-keyword">break</span>;
+ }
+ }
+ <span class="hljs-keyword">if</span> (!accept) {
+ <span class="hljs-comment">// 若服务消费者协议头不被消费者所支持,则忽略当前 providerUrl</span>
+ <span class="hljs-keyword">continue</span>;
+ }
+ }
+ <span class="hljs-comment">// 忽略 empty 协议</span>
+ <span class="hljs-keyword">if</span> (Constants.EMPTY_PROTOCOL.equals(providerUrl.getProtocol())) {
+ <span class="hljs-keyword">continue</span>;
+ }
+ <span class="hljs-comment">// 通过 SPI 检测服务端协议是否被消费端支持,不支持则抛出异常</span>
+ <span class="hljs-keyword">if</span> (!ExtensionLoader.getExtensionLoader(Protocol.class).hasExtension(providerUrl.getProtocol())) {
+ logger.error(<span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"Unsupported protocol..."</span>));
+ <span class="hljs-keyword">continue</span>;
+ }
+
+ <span class="hljs-comment">// 合并 url</span>
+ URL url = mergeUrl(providerUrl);
+
+ String key = url.toFullString();
+ <span class="hljs-keyword">if</span> (keys.contains(key)) {
+ <span class="hljs-comment">// 忽略重复 url</span>
+ <span class="hljs-keyword">continue</span>;
+ }
+ keys.add(key);
+ <span class="hljs-comment">// 将本地 Invoker 缓存赋值给 localUrlInvokerMap</span>
+ Map<String, Invoker<T>> localUrlInvokerMap = <span class="hljs-keyword">this</span>.urlInvokerMap;
+ <span class="hljs-comment">// 获取与 url 对应的 Invoker</span>
+ Invoker<T> invoker = localUrlInvokerMap == <span class="hljs-keyword">null</span> ? <span class="hljs-keyword">null</span> : localUrlInvokerMap.get(key);
+ <span class="hljs-comment">// 缓存未命中</span>
+ <span class="hljs-keyword">if</span> (invoker == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-keyword">boolean</span> enabled = <span class="hljs-keyword">true</span>;
+ <span class="hljs-keyword">if</span> (url.hasParameter(Constants.DISABLED_KEY)) {
+ <span class="hljs-comment">// 获取 disable 配置,取反,然后赋值给 enable 变量</span>
+ enabled = !url.getParameter(Constants.DISABLED_KEY, <span class="hljs-keyword">false</span>);
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-comment">// 获取 enable 配置,并赋值给 enable 变量</span>
+ enabled = url.getParameter(Constants.ENABLED_KEY, <span class="hljs-keyword">true</span>);
+ }
+ <span class="hljs-keyword">if</span> (enabled) {
+ <span class="hljs-comment">// 调用 refer 获取 Invoker</span>
+ invoker = <span class="hljs-keyword">new</span> InvokerDelegate<T>(protocol.refer(serviceType, url), url, providerUrl);
+ }
+ } <span class="hljs-keyword">catch</span> (Throwable t) {
+ logger.error(<span class="hljs-string">"Failed to refer invoker for interface..."</span>);
+ }
+ <span class="hljs-keyword">if</span> (invoker != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 缓存 Invoker 实例</span>
+ newUrlInvokerMap.put(key, invoker);
+ }
+
+ <span class="hljs-comment">// 缓存命中</span>
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-comment">// 将 invoker 存储到 newUrlInvokerMap 中</span>
+ newUrlInvokerMap.put(key, invoker);
+ }
+ }
+ keys.clear();
+ <span class="hljs-keyword">return</span> newUrlInvokerMap;
+}
+</code></pre>
+<p>toInvokers 方法一开始会对服务提供者 url 进行检测,若服务消费端的配置不支持服务端的协议,或服务端 url 协议头为 empty 时,toInvokers 均会忽略服务提供方 url。必要的检测做完后,紧接着是合并 url,然后访问缓存,尝试获取与 url 对应的 invoker。如果缓存命中,直接将 Invoker 存入 newUrlInvokerMap 中即可。如果未命中,则需新建 Invoker。</p>
+<p>toInvokers 方法返回的是 <url, Invoker> 映射关系表,接下来还要对这个结果进行进一步处理,得到方法名到 Invoker 列表的映射关系。这个过程由 toMethodInvokers 方法完成,如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">private</span> Map<String, List<Invoker<T>>> toMethodInvokers(Map<String, Invoker<T>> invokersMap) {
+ <span class="hljs-comment">// 方法名 -> Invoker 列表</span>
+ Map<String, List<Invoker<T>>> newMethodInvokerMap = <span class="hljs-keyword">new</span> HashMap<String, List<Invoker<T>>>();
+ List<Invoker<T>> invokersList = <span class="hljs-keyword">new</span> ArrayList<Invoker<T>>();
+ <span class="hljs-keyword">if</span> (invokersMap != <span class="hljs-keyword">null</span> && invokersMap.size() > <span class="hljs-number">0</span>) {
+ <span class="hljs-keyword">for</span> (Invoker<T> invoker : invokersMap.values()) {
+ <span class="hljs-comment">// 获取 methods 参数</span>
+ String parameter = invoker.getUrl().getParameter(Constants.METHODS_KEY);
+ <span class="hljs-keyword">if</span> (parameter != <span class="hljs-keyword">null</span> && parameter.length() > <span class="hljs-number">0</span>) {
+ <span class="hljs-comment">// 切分 methods 参数值,得到方法名数组</span>
+ String[] methods = Constants.COMMA_SPLIT_PATTERN.split(parameter);
+ <span class="hljs-keyword">if</span> (methods != <span class="hljs-keyword">null</span> && methods.length > <span class="hljs-number">0</span>) {
+ <span class="hljs-keyword">for</span> (String method : methods) {
+ <span class="hljs-comment">// 方法名不为 *</span>
+ <span class="hljs-keyword">if</span> (method != <span class="hljs-keyword">null</span> && method.length() > <span class="hljs-number">0</span>
+ && !Constants.ANY_VALUE.equals(method)) {
+ <span class="hljs-comment">// 根据方法名获取 Invoker 列表</span>
+ List<Invoker<T>> methodInvokers = newMethodInvokerMap.get(method);
+ <span class="hljs-keyword">if</span> (methodInvokers == <span class="hljs-keyword">null</span>) {
+ methodInvokers = <span class="hljs-keyword">new</span> ArrayList<Invoker<T>>();
+ newMethodInvokerMap.put(method, methodInvokers);
+ }
+ <span class="hljs-comment">// 存储 Invoker 到列表中</span>
+ methodInvokers.add(invoker);
+ }
+ }
+ }
+ }
+ invokersList.add(invoker);
+ }
+ }
+
+ <span class="hljs-comment">// 进行服务级别路由,参考 pull request #749</span>
+ List<Invoker<T>> newInvokersList = route(invokersList, <span class="hljs-keyword">null</span>);
+ <span class="hljs-comment">// 存储 <*, newInvokersList> 映射关系</span>
+ newMethodInvokerMap.put(Constants.ANY_VALUE, newInvokersList);
+ <span class="hljs-keyword">if</span> (serviceMethods != <span class="hljs-keyword">null</span> && serviceMethods.length > <span class="hljs-number">0</span>) {
+ <span class="hljs-keyword">for</span> (String method : serviceMethods) {
+ List<Invoker<T>> methodInvokers = newMethodInvokerMap.get(method);
+ <span class="hljs-keyword">if</span> (methodInvokers == <span class="hljs-keyword">null</span> || methodInvokers.isEmpty()) {
+ methodInvokers = newInvokersList;
+ }
+ <span class="hljs-comment">// 进行方法级别路由</span>
+ newMethodInvokerMap.put(method, route(methodInvokers, method));
+ }
+ }
+ <span class="hljs-comment">// 排序,转成不可变列表</span>
+ <span class="hljs-keyword">for</span> (String method : <span class="hljs-keyword">new</span> HashSet<String>(newMethodInvokerMap.keySet())) {
+ List<Invoker<T>> methodInvokers = newMethodInvokerMap.get(method);
+ Collections.sort(methodInvokers, InvokerComparator.getComparator());
+ newMethodInvokerMap.put(method, Collections.unmodifiableList(methodInvokers));
+ }
+ <span class="hljs-keyword">return</span> Collections.unmodifiableMap(newMethodInvokerMap);
+}
+</code></pre>
+<p>上面方法主要做了三件事情, 第一是对入参进行遍历,然后从 Invoker 的 url 成员变量中获取 methods 参数,并切分成数组。随后以方法名为键,Invoker 列表为值,将映射关系存储到 newMethodInvokerMap 中。第二是分别基于类和方法对 Invoker 列表进行路由操作。第三是对 Invoker 列表进行排序,并转成不可变列表。关于 toMethodInvokers 方法就先分析到这,我们继续向下分析,这次要分析的多组服务的合并逻辑。</p>
+<pre><code class="language-java"><span class="hljs-keyword">private</span> Map<String, List<Invoker<T>>> toMergeMethodInvokerMap(Map<String, List<Invoker<T>>> methodMap) {
+ Map<String, List<Invoker<T>>> result = <span class="hljs-keyword">new</span> HashMap<String, List<Invoker<T>>>();
+ <span class="hljs-comment">// 遍历入参</span>
+ <span class="hljs-keyword">for</span> (Map.Entry<String, List<Invoker<T>>> entry : methodMap.entrySet()) {
+ String method = entry.getKey();
+ List<Invoker<T>> invokers = entry.getValue();
+ <span class="hljs-comment">// group -> Invoker 列表</span>
+ Map<String, List<Invoker<T>>> groupMap = <span class="hljs-keyword">new</span> HashMap<String, List<Invoker<T>>>();
+ <span class="hljs-comment">// 遍历 Invoker 列表</span>
+ <span class="hljs-keyword">for</span> (Invoker<T> invoker : invokers) {
+ <span class="hljs-comment">// 获取分组配置</span>
+ String group = invoker.getUrl().getParameter(Constants.GROUP_KEY, <span class="hljs-string">""</span>);
+ List<Invoker<T>> groupInvokers = groupMap.get(group);
+ <span class="hljs-keyword">if</span> (groupInvokers == <span class="hljs-keyword">null</span>) {
+ groupInvokers = <span class="hljs-keyword">new</span> ArrayList<Invoker<T>>();
+ <span class="hljs-comment">// 缓存 <group, List<Invoker>> 到 groupMap 中</span>
+ groupMap.put(group, groupInvokers);
+ }
+ <span class="hljs-comment">// 存储 invoker 到 groupInvokers</span>
+ groupInvokers.add(invoker);
+ }
+ <span class="hljs-keyword">if</span> (groupMap.size() == <span class="hljs-number">1</span>) {
+ <span class="hljs-comment">// 如果 groupMap 中仅包含一组键值对,此时直接取出该键值对的值即可</span>
+ result.put(method, groupMap.values().iterator().next());
+
+ <span class="hljs-comment">// groupMap.size() > 1 成立,表示 groupMap 中包含多组键值对,比如:</span>
+ <span class="hljs-comment">// {</span>
+ <span class="hljs-comment">// "dubbo": [invoker1, invoker2, invoker3, ...],</span>
+ <span class="hljs-comment">// "hello": [invoker4, invoker5, invoker6, ...]</span>
+ <span class="hljs-comment">// }</span>
+ } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (groupMap.size() > <span class="hljs-number">1</span>) {
+ List<Invoker<T>> groupInvokers = <span class="hljs-keyword">new</span> ArrayList<Invoker<T>>();
+ <span class="hljs-keyword">for</span> (List<Invoker<T>> groupList : groupMap.values()) {
+ <span class="hljs-comment">// 通过集群类合并每个分组对应的 Invoker 列表</span>
+ groupInvokers.add(cluster.join(<span class="hljs-keyword">new</span> StaticDirectory<T>(groupList)));
+ }
+ <span class="hljs-comment">// 缓存结果</span>
+ result.put(method, groupInvokers);
+ } <span class="hljs-keyword">else</span> {
+ result.put(method, invokers);
+ }
+ }
+ <span class="hljs-keyword">return</span> result;
+}
+</code></pre>
+<p>上面方法首先是生成 group 到 Invoker 类比的映射关系表,若关系表中的映射关系数量大于1,表示有多组服务。此时通过集群类合并每组 Invoker,并将合并结果存储到 groupInvokers 中。之后将方法名与 groupInvokers 存到到 result 中,并返回,整个逻辑结束。</p>
+<p>接下来我们再来看一下 Invoker 列表刷新逻辑的最后一个动作 — 删除无用 Invoker。如下:</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">destroyUnusedInvokers</span><span class="hljs-params">(Map<String, Invoker<T>> oldUrlInvokerMap, Map<String, Invoker<T>> newUrlInvokerMap)</span> </span>{
+ <span class="hljs-keyword">if</span> (newUrlInvokerMap == <span class="hljs-keyword">null</span> || newUrlInvokerMap.size() == <span class="hljs-number">0</span>) {
+ destroyAllInvokers();
+ <span class="hljs-keyword">return</span>;
+ }
+
+ List<String> deleted = <span class="hljs-keyword">null</span>;
+ <span class="hljs-keyword">if</span> (oldUrlInvokerMap != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 获取新生成的 Invoker 列表</span>
+ Collection<Invoker<T>> newInvokers = newUrlInvokerMap.values();
+ <span class="hljs-comment">// 遍历老的 <url, Invoker> 映射表</span>
+ <span class="hljs-keyword">for</span> (Map.Entry<String, Invoker<T>> entry : oldUrlInvokerMap.entrySet()) {
+ <span class="hljs-comment">// 检测 newInvokers 中是否包含老的 Invoker</span>
+ <span class="hljs-keyword">if</span> (!newInvokers.contains(entry.getValue())) {
+ <span class="hljs-keyword">if</span> (deleted == <span class="hljs-keyword">null</span>) {
+ deleted = <span class="hljs-keyword">new</span> ArrayList<String>();
+ }
+ <span class="hljs-comment">// 若不包含,则将老的 Invoker 对应的 url 存入 deleted 列表中</span>
+ deleted.add(entry.getKey());
+ }
+ }
+ }
+
+ <span class="hljs-keyword">if</span> (deleted != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 遍历 deleted 集合,并到老的 <url, Invoker> 映射关系表查出 Invoker,销毁之</span>
+ <span class="hljs-keyword">for</span> (String url : deleted) {
+ <span class="hljs-keyword">if</span> (url != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 从 oldUrlInvokerMap 中移除 url 对应的 Invoker</span>
+ Invoker<T> invoker = oldUrlInvokerMap.remove(url);
+ <span class="hljs-keyword">if</span> (invoker != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-comment">// 销毁 Invoker</span>
+ invoker.destroy();
+ } <span class="hljs-keyword">catch</span> (Exception e) {
+ logger.warn(<span class="hljs-string">"destroy invoker..."</span>);
+ }
+ }
+ }
+ }
+ }
+}
+</code></pre>
+<p>destroyUnusedInvokers 方法的主要逻辑是通过 newUrlInvokerMap 找出待删除 Invoker 对应的 url,并将 url 存入到 deleted 列表中。然后再遍历 deleted 列表,并从 oldUrlInvokerMap 中移除相应的 Invoker,销毁之。整个逻辑大致如此,不是很难理解。</p>
+<p>到此关于 Invoker 列表的刷新逻辑就分析了,这里对整个过程进行简单总结。如下:</p>
+<ol>
+<li>检测入参是否仅包含一个 url,且 url 协议头为 empty</li>
+<li>若第一步检测结果为 true,表示禁用所有服务,此时销毁所有的 Invoker</li>
+<li>若第一步检测结果为 false,此时将入参转为 Invoker 列表</li>
+<li>对将上一步逻辑生成的结果进行进一步处理,得到方法名到 Invoker 的映射关系表</li>
+<li>合并多组 Invoker</li>
+<li>销毁无用 Invoker</li>
+</ol>
+<p>Invoker 的刷新逻辑还是比较复杂的,大家在看的过程中多写点 demo 进行调试,以加深理解。</p>
+<h2>4. 总结</h2>
+<p>本篇文章对 Dubbo 服务目录进行了较为详细的分析,篇幅主要集中在 RegistryDirectory 的源码分析上。从代码量上可以看出,想让本地服务目录和注册中心保持一致还是需要做很多事情的,并不简单。服务目录是 Dubbo 集群容错的一部分,也是比较基础的部分,所以大家应尽量搞懂。</p>
+</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
+ <script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+ <script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+ <script>
+ window.rootPath = '';
+ </script>
+ <script src="/build/documentation.js"></script>
+ <!-- Global site tag (gtag.js) - Google Analytics -->
+ <script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+ <script>
+ window.dataLayer = window.dataLayer || [];
+ function gtag(){dataLayer.push(arguments);}
+ gtag('js', new Date());
+
+ gtag('config', 'UA-112489517-1');
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/zh-cn/docs/source_code_guide/directory.json b/zh-cn/docs/source_code_guide/directory.json
new file mode 100644
index 0000000..473572d
--- /dev/null
+++ b/zh-cn/docs/source_code_guide/directory.json
@@ -0,0 +1,10 @@
+{
+ "filename": "directory.md",
+ "__html": "<h2>1. 简介</h2>\n<p>本篇文章,将开始分析 Dubbo 集群容错方面的源码。集群容错源码包含四个部分,分别是服务目录 Directory、服务路由 Router、集群 Cluster 和负载均衡 LoadBalance。这几个部分的源码逻辑相对比较独立,我们将会分四篇文章进行分析。本篇文章作为集群容错的开篇文章,将和大家一起分析服务目录相关的源码。在进行深入分析之前,我们先来了解一下服务目录是什么。服务目录中存储了一些和服务提供者有关的信息,通过服务目录,服务消费者可获取到服务提供者的信息,比如 ip、端口、服务协议等。通过这些信息,服务消费者就可通过 Netty 等客户端进行远程调用。在一个服务集群中,服务提供者数量并不是一成不变的,如果集群中新增了一台机器,相应地在服务目录中就要新增一条服务提供者记录。或者,如果服务提供者
的配置修改了,服务目录中的记录也要做相应的更新。如果这样说,服务目录和注册中心的功能不就雷同了吗?确实如此,这里这么说是为了方便大家理解。实际上服务目录在获取注册中心的服务配置信息后,会为每条配置信息生成一 [...]
+ "link": "/zh-cn/docs/source_code_guide/directory.html",
+ "meta": {
+ "title": "服务目录",
+ "keywords": "Dubbo, Directory",
+ "description": "本文介绍了服务目录的原理和实现细节"
+ }
+}
\ No newline at end of file
diff --git a/zh-cn/docs/source_code_guide/dubbo-spi.html b/zh-cn/docs/source_code_guide/dubbo-spi.html
new file mode 100644
index 0000000..6dd9532
--- /dev/null
+++ b/zh-cn/docs/source_code_guide/dubbo-spi.html
@@ -0,0 +1,393 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <meta name="keywords" content="Dubbo, SPI" />
+ <meta name="description" content="本文介绍了 Dubbo SPI 的原理和实现细节" />
+ <!-- 网页标签标题 -->
+ <title>Dubbo SPI</title>
+ <link rel="shortcut icon" href="/img/dubbo.ico"/>
+ <link rel="stylesheet" href="/build/documentation.css" />
+</head>
+<body>
+ <div id="root"><div class="documentation-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a [...]
+<p>SPI 全称为 Service Provider Interface,是一种服务发现机制。SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口替换实现类。正因此特性,我们可以很容易的通过 SPI 机制为我们的程序提供拓展功能。SPI 机制在第三方框架中也有所应用,比如 Dubbo 就是通过 SPI 机制加载所有的组件。不过,Dubbo 并未使用 Java 原生的 SPI 机制,而是对其进行了增强,使其能够更好的满足需求。在 Dubbo 中,SPI 是一个非常重要的模块。基于 SPI,我们可以很容易的对 Dubbo 进行拓展。如果大家想要学习 Dubbo 的源码,SPI 机制务必弄懂。接下来,我们先来了解一下 Java SPI 与 Dubbo SPI 的用法,然后再来分析 Dubbo SPI 的源码。</p>
+<h2>2.SPI 示例</h2>
+<h3>2.1 Java SPI 示例</h3>
+<p>前面简单介绍了 SPI 机制的原理,本节通过一个示例演示 Java SPI 的使用方法。首先,我们定义一个接口,名称为 Robot。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Robot</span> </span>{
+ <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">sayHello</span><span class="hljs-params">()</span></span>;
+}
+</code></pre>
+<p>接下来定义两个实现类,分别为 OptimusPrime 和 Bumblebee。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">OptimusPrime</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Robot</span> </span>{
+
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">sayHello</span><span class="hljs-params">()</span> </span>{
+ System.out.println(<span class="hljs-string">"Hello, I am Optimus Prime."</span>);
+ }
+}
+
+<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Bumblebee</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Robot</span> </span>{
+
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">sayHello</span><span class="hljs-params">()</span> </span>{
+ System.out.println(<span class="hljs-string">"Hello, I am Bumblebee."</span>);
+ }
+}
+</code></pre>
+<p>接下来 META-INF/services 文件夹下创建一个文件,名称为 Robot 的全限定名 org.apache.spi.Robot。文件内容为实现类的全限定的类名,如下:</p>
+<pre><code>org.apache.spi.OptimusPrime
+org.apache.spi.Bumblebee
+</code></pre>
+<p>做好所需的准备工作,接下来编写代码进行测试。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">JavaSPITest</span> </span>{
+
+ <span class="hljs-meta">@Test</span>
+ <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">sayHello</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception </span>{
+ ServiceLoader<Robot> serviceLoader = ServiceLoader.load(Robot.class);
+ System.out.println(<span class="hljs-string">"Java SPI"</span>);
+ serviceLoader.forEach(Robot::sayHello);
+ }
+}
+</code></pre>
+<p>最后来看一下测试结果,如下:</p>
+<p><img src="./sources/images/java-spi-result.jpg" alt=""></p>
+<p>从测试结果可以看出,我们的两个实现类被成功的加载,并输出了相应的内容。关于 Java SPI 的演示先到这里,接下来演示 Dubbo SPI。</p>
+<h3>2.2 Dubbo SPI 示例</h3>
+<p>Dubbo 并未使用 Java SPI,而是重新实现了一套功能更强的 SPI 机制。Dubbo SPI 的相关逻辑被封装在了 ExtensionLoader 类中,通过 ExtensionLoader,我们可以加载指定的实现类。Dubbo SPI 所需的配置文件需放置在 META-INF/dubbo 路径下,配置内容如下。</p>
+<pre><code>optimusPrime = org.apache.spi.OptimusPrime
+bumblebee = org.apache.spi.Bumblebee
+</code></pre>
+<p>与 Java SPI 实现类配置不同,Dubbo SPI 是通过键值对的方式进行配置,这样我们可以按需加载指定的实现类。另外,在测试 Dubbo SPI 时,需要在 Robot 接口上标注 @SPI 注解。下面来演示 Dubbo SPI 的用法:</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DubboSPITest</span> </span>{
+
+ <span class="hljs-meta">@Test</span>
+ <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">sayHello</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception </span>{
+ ExtensionLoader<Robot> extensionLoader =
+ ExtensionLoader.getExtensionLoader(Robot.class);
+ Robot optimusPrime = extensionLoader.getExtension(<span class="hljs-string">"optimusPrime"</span>);
+ optimusPrime.sayHello();
+ Robot bumblebee = extensionLoader.getExtension(<span class="hljs-string">"bumblebee"</span>);
+ bumblebee.sayHello();
+ }
+}
+</code></pre>
+<p>测试结果如下:</p>
+<p><img src="./sources/images/dubbo-spi-result.jpg" alt=""></p>
+<p>Dubbo SPI 除了支持按需加载接口实现类,还增加了 IOC 和 AOP 等特性,这些特性将会在接下来的源码分析章节中一一进行介绍。</p>
+<h2>3. Dubbo SPI 源码分析</h2>
+<p>上一章简单演示了 Dubbo SPI 的使用方法。我们首先通过 ExtensionLoader 的 getExtensionLoader 方法获取一个 ExtensionLoader 实例,然后再通过 ExtensionLoader 的 getExtension 方法获取拓展类对象。这其中,getExtensionLoader 方法用于从缓存中获取与拓展类对应的 ExtensionLoader,若缓存未命中,则创建一个新的实例。该方法的逻辑比较简单,本章就不就行分析了。下面我们从 ExtensionLoader 的 getExtension 方法作为入口,对拓展类对象的获取过程进行详细的分析。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">public</span> T <span class="hljs-title">getExtension</span><span class="hljs-params">(String name)</span> </span>{
+ <span class="hljs-keyword">if</span> (name == <span class="hljs-keyword">null</span> || name.length() == <span class="hljs-number">0</span>)
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"Extension name == null"</span>);
+ <span class="hljs-keyword">if</span> (<span class="hljs-string">"true"</span>.equals(name)) {
+ <span class="hljs-comment">// 获取默认的拓展实现类</span>
+ <span class="hljs-keyword">return</span> getDefaultExtension();
+ }
+ <span class="hljs-comment">// Holder,顾名思义,用于持有目标对象</span>
+ Holder<Object> holder = cachedInstances.get(name);
+ <span class="hljs-keyword">if</span> (holder == <span class="hljs-keyword">null</span>) {
+ cachedInstances.putIfAbsent(name, <span class="hljs-keyword">new</span> Holder<Object>());
+ holder = cachedInstances.get(name);
+ }
+ Object instance = holder.get();
+ <span class="hljs-comment">// 双重检查</span>
+ <span class="hljs-keyword">if</span> (instance == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">synchronized</span> (holder) {
+ instance = holder.get();
+ <span class="hljs-keyword">if</span> (instance == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 创建拓展实例</span>
+ instance = createExtension(name);
+ <span class="hljs-comment">// 设置实例到 holder 中</span>
+ holder.set(instance);
+ }
+ }
+ }
+ <span class="hljs-keyword">return</span> (T) instance;
+}
+</code></pre>
+<p>上面代码的逻辑比较简单,首先检查缓存,缓存未命中则创建拓展对象。下面我们来看一下创建拓展对象的过程是怎样的。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">private</span> T <span class="hljs-title">createExtension</span><span class="hljs-params">(String name)</span> </span>{
+ <span class="hljs-comment">// 从配置文件中加载所有的拓展类,可得到“配置项名称”到“配置类”的映射关系表</span>
+ Class<?> clazz = getExtensionClasses().get(name);
+ <span class="hljs-keyword">if</span> (clazz == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">throw</span> findException(name);
+ }
+ <span class="hljs-keyword">try</span> {
+ T instance = (T) EXTENSION_INSTANCES.get(clazz);
+ <span class="hljs-keyword">if</span> (instance == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 通过反射创建实例</span>
+ EXTENSION_INSTANCES.putIfAbsent(clazz, clazz.newInstance());
+ instance = (T) EXTENSION_INSTANCES.get(clazz);
+ }
+ <span class="hljs-comment">// 向实例中注入依赖</span>
+ injectExtension(instance);
+ Set<Class<?>> wrapperClasses = cachedWrapperClasses;
+ <span class="hljs-keyword">if</span> (wrapperClasses != <span class="hljs-keyword">null</span> && !wrapperClasses.isEmpty()) {
+ <span class="hljs-comment">// 循环创建 Wrapper 实例</span>
+ <span class="hljs-keyword">for</span> (Class<?> wrapperClass : wrapperClasses) {
+ <span class="hljs-comment">// 将当前 instance 作为参数传给 Wrapper 的构造方法,并通过反射创建 Wrapper 实例。</span>
+ <span class="hljs-comment">// 然后向 Wrapper 实例中注入依赖,最后将 Wrapper 实例再次赋值给 instance 变量</span>
+ instance = injectExtension(
+ (T) wrapperClass.getConstructor(type).newInstance(instance));
+ }
+ }
+ <span class="hljs-keyword">return</span> instance;
+ } <span class="hljs-keyword">catch</span> (Throwable t) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"..."</span>);
+ }
+}
+</code></pre>
+<p>createExtension 方法的逻辑稍复杂一下,包含了如下的步骤:</p>
+<ol>
+<li>通过 getExtensionClasses 获取所有的拓展类</li>
+<li>通过反射创建拓展对象</li>
+<li>向拓展对象中注入依赖</li>
+<li>将拓展对象包裹在相应的 Wrapper 对象中</li>
+</ol>
+<p>以上步骤中,第一个步骤是加载拓展类的关键,第三和第四个步骤是 Dubbo IOC 与 AOP 的具体实现。在接下来的章节中,将会重点分析 getExtensionClasses 方法的逻辑,以及简单介绍 Dubbo IOC 的具体实现。</p>
+<h3>3.1 获取所有的拓展类</h3>
+<p>我们在通过名称获取拓展类之前,首先需要根据配置文件解析出拓展项名称到拓展类的映射关系表(Map<名称, 拓展类>),之后再根据拓展项名称从映射关系表中取出相应的拓展类即可。相关过程的代码分析如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">private</span> Map<String, Class<?>> getExtensionClasses() {
+ <span class="hljs-comment">// 从缓存中获取已加载的拓展类</span>
+ Map<String, Class<?>> classes = cachedClasses.get();
+ <span class="hljs-comment">// 双重检查</span>
+ <span class="hljs-keyword">if</span> (classes == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">synchronized</span> (cachedClasses) {
+ classes = cachedClasses.get();
+ <span class="hljs-keyword">if</span> (classes == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 加载拓展类</span>
+ classes = loadExtensionClasses();
+ cachedClasses.set(classes);
+ }
+ }
+ }
+ <span class="hljs-keyword">return</span> classes;
+}
+</code></pre>
+<p>这里也是先检查缓存,若缓存未命中,则通过 synchronized 加锁。加锁后再次检查缓存,并判空。此时如果 classes 仍为 null,则通过 loadExtensionClasses 加载拓展类。下面分析 loadExtensionClasses 方法的逻辑。</p>
+<pre><code class="language-java"><span class="hljs-keyword">private</span> Map<String, Class<?>> loadExtensionClasses() {
+ <span class="hljs-comment">// 获取 SPI 注解,这里的 type 变量是在调用 getExtensionLoader 方法时传入的</span>
+ <span class="hljs-keyword">final</span> SPI defaultAnnotation = type.getAnnotation(SPI.class);
+ <span class="hljs-keyword">if</span> (defaultAnnotation != <span class="hljs-keyword">null</span>) {
+ String value = defaultAnnotation.value();
+ <span class="hljs-keyword">if</span> ((value = value.trim()).length() > <span class="hljs-number">0</span>) {
+ <span class="hljs-comment">// 对 SPI 注解内容进行切分</span>
+ String[] names = NAME_SEPARATOR.split(value);
+ <span class="hljs-comment">// 检测 SPI 注解内容是否合法,不合法则抛出异常</span>
+ <span class="hljs-keyword">if</span> (names.length > <span class="hljs-number">1</span>) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"more than 1 default extension name on extension..."</span>);
+ }
+
+ <span class="hljs-comment">// 设置默认名称,参考 getDefaultExtension 方法</span>
+ <span class="hljs-keyword">if</span> (names.length == <span class="hljs-number">1</span>) {
+ cachedDefaultName = names[<span class="hljs-number">0</span>];
+ }
+ }
+ }
+
+ Map<String, Class<?>> extensionClasses = <span class="hljs-keyword">new</span> HashMap<String, Class<?>>();
+ <span class="hljs-comment">// 加载指定文件夹下的配置文件</span>
+ loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY);
+ loadDirectory(extensionClasses, DUBBO_DIRECTORY);
+ loadDirectory(extensionClasses, SERVICES_DIRECTORY);
+ <span class="hljs-keyword">return</span> extensionClasses;
+}
+</code></pre>
+<p>loadExtensionClasses 方法总共做了两件事情,一是对 SPI 注解进行解析,二是调用 loadDirectory 方法加载指定文件夹配置文件。SPI 注解解析过程比较简单,无需多说。下面我们来看一下 loadDirectory 做了哪些事情。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">loadDirectory</span><span class="hljs-params">(Map<String, Class<?>> extensionClasses, String dir)</span> </span>{
+ <span class="hljs-comment">// fileName = 文件夹路径 + type 全限定名 </span>
+ String fileName = dir + type.getName();
+ <span class="hljs-keyword">try</span> {
+ Enumeration<java.net.URL> urls;
+ ClassLoader classLoader = findClassLoader();
+ <span class="hljs-comment">// 根据文件名加载所有的同名文件</span>
+ <span class="hljs-keyword">if</span> (classLoader != <span class="hljs-keyword">null</span>) {
+ urls = classLoader.getResources(fileName);
+ } <span class="hljs-keyword">else</span> {
+ urls = ClassLoader.getSystemResources(fileName);
+ }
+ <span class="hljs-keyword">if</span> (urls != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">while</span> (urls.hasMoreElements()) {
+ java.net.URL resourceURL = urls.nextElement();
+ <span class="hljs-comment">// 加载资源</span>
+ loadResource(extensionClasses, classLoader, resourceURL);
+ }
+ }
+ } <span class="hljs-keyword">catch</span> (Throwable t) {
+ logger.error(<span class="hljs-string">"..."</span>);
+ }
+}
+</code></pre>
+<p>loadDirectory 方法先通过 classLoader 获取所有资源链接,然后再通过 loadResource 方法加载资源。我们继续跟下去,看一下 loadResource 方法的实现。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">loadResource</span><span class="hljs-params">(Map<String, Class<?>> extensionClasses,
+ ClassLoader classLoader, java.net.URL resourceURL)</span> </span>{
+ <span class="hljs-keyword">try</span> {
+ BufferedReader reader = <span class="hljs-keyword">new</span> BufferedReader(
+ <span class="hljs-keyword">new</span> InputStreamReader(resourceURL.openStream(), <span class="hljs-string">"utf-8"</span>));
+ <span class="hljs-keyword">try</span> {
+ String line;
+ <span class="hljs-comment">// 按行读取配置内容</span>
+ <span class="hljs-keyword">while</span> ((line = reader.readLine()) != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 定位 # 字符</span>
+ <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> ci = line.indexOf(<span class="hljs-string">'#'</span>);
+ <span class="hljs-keyword">if</span> (ci >= <span class="hljs-number">0</span>) {
+ <span class="hljs-comment">// 截取 # 之前的字符串,# 之后的内容为注释,需要忽略</span>
+ line = line.substring(<span class="hljs-number">0</span>, ci);
+ }
+ line = line.trim();
+ <span class="hljs-keyword">if</span> (line.length() > <span class="hljs-number">0</span>) {
+ <span class="hljs-keyword">try</span> {
+ String name = <span class="hljs-keyword">null</span>;
+ <span class="hljs-keyword">int</span> i = line.indexOf(<span class="hljs-string">'='</span>);
+ <span class="hljs-keyword">if</span> (i > <span class="hljs-number">0</span>) {
+ <span class="hljs-comment">// 以等于号 = 为界,截取键与值</span>
+ name = line.substring(<span class="hljs-number">0</span>, i).trim();
+ line = line.substring(i + <span class="hljs-number">1</span>).trim();
+ }
+ <span class="hljs-keyword">if</span> (line.length() > <span class="hljs-number">0</span>) {
+ <span class="hljs-comment">// 加载类,并通过 loadClass 方法对类进行缓存</span>
+ loadClass(extensionClasses, resourceURL,
+ Class.forName(line, <span class="hljs-keyword">true</span>, classLoader), name);
+ }
+ } <span class="hljs-keyword">catch</span> (Throwable t) {
+ IllegalStateException e = <span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"Failed to load extension class..."</span>);
+ }
+ }
+ }
+ } <span class="hljs-keyword">finally</span> {
+ reader.close();
+ }
+ } <span class="hljs-keyword">catch</span> (Throwable t) {
+ logger.error(<span class="hljs-string">"Exception when load extension class..."</span>);
+ }
+}
+</code></pre>
+<p>loadResource 方法用于读取和解析配置文件,并通过反射加载类,最后调用 loadClass 方法进行其他操作。loadClass 方法用于主要用于操作缓存,该方法的逻辑如下:</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">loadClass</span><span class="hljs-params">(Map<String, Class<?>> extensionClasses, java.net.URL resourceURL,
+ Class<?> clazz, String name)</span> <span class="hljs-keyword">throws</span> NoSuchMethodException </span>{
+
+ <span class="hljs-keyword">if</span> (!type.isAssignableFrom(clazz)) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"..."</span>);
+ }
+
+ <span class="hljs-comment">// 检测目标类上是否有 Adaptive 注解</span>
+ <span class="hljs-keyword">if</span> (clazz.isAnnotationPresent(Adaptive.class)) {
+ <span class="hljs-keyword">if</span> (cachedAdaptiveClass == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 设置 cachedAdaptiveClass缓存</span>
+ cachedAdaptiveClass = clazz;
+ } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (!cachedAdaptiveClass.equals(clazz)) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"..."</span>);
+ }
+
+ <span class="hljs-comment">// 检测 clazz 是否是 Wrapper 类型</span>
+ } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (isWrapperClass(clazz)) {
+ Set<Class<?>> wrappers = cachedWrapperClasses;
+ <span class="hljs-keyword">if</span> (wrappers == <span class="hljs-keyword">null</span>) {
+ cachedWrapperClasses = <span class="hljs-keyword">new</span> ConcurrentHashSet<Class<?>>();
+ wrappers = cachedWrapperClasses;
+ }
+ <span class="hljs-comment">// 存储 clazz 到 cachedWrapperClasses 缓存中</span>
+ wrappers.add(clazz);
+
+ <span class="hljs-comment">// 程序进入此分支,表明 clazz 是一个普通的拓展类</span>
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-comment">// 检测 clazz 是否有默认的构造方法,如果没有,则抛出异常</span>
+ clazz.getConstructor();
+ <span class="hljs-keyword">if</span> (name == <span class="hljs-keyword">null</span> || name.length() == <span class="hljs-number">0</span>) {
+ <span class="hljs-comment">// 如果 name 为空,则尝试从 Extension 注解中获取 name,或使用小写的类名作为 name</span>
+ name = findAnnotationName(clazz);
+ <span class="hljs-keyword">if</span> (name.length() == <span class="hljs-number">0</span>) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"..."</span>);
+ }
+ }
+ <span class="hljs-comment">// 切分 name</span>
+ String[] names = NAME_SEPARATOR.split(name);
+ <span class="hljs-keyword">if</span> (names != <span class="hljs-keyword">null</span> && names.length > <span class="hljs-number">0</span>) {
+ Activate activate = clazz.getAnnotation(Activate.class);
+ <span class="hljs-keyword">if</span> (activate != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 如果类上有 Activate 注解,则使用 names 数组的第一个元素作为键,</span>
+ <span class="hljs-comment">// 存储 name 到 Activate 注解对象的映射关系</span>
+ cachedActivates.put(names[<span class="hljs-number">0</span>], activate);
+ }
+ <span class="hljs-keyword">for</span> (String n : names) {
+ <span class="hljs-keyword">if</span> (!cachedNames.containsKey(clazz)) {
+ <span class="hljs-comment">// 存储 Class 到名称的映射关系</span>
+ cachedNames.put(clazz, n);
+ }
+ Class<?> c = extensionClasses.get(n);
+ <span class="hljs-keyword">if</span> (c == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 存储名称到 Class 的映射关系</span>
+ extensionClasses.put(n, clazz);
+ } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (c != clazz) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"..."</span>);
+ }
+ }
+ }
+ }
+}
+</code></pre>
+<p>如上,loadClass 方法操作了不同的缓存,比如 cachedAdaptiveClass、cachedWrapperClasses 和 cachedNames 等等。除此之外,该方法没有其他什么逻辑了。</p>
+<p>到此,关于缓存类加载的过程就分析完了。整个过程没什么特别复杂的地方,大家按部就班的分析即可,不懂的地方可以调试一下。接下来,我们来聊聊 Dubbo IOC 方面的内容。</p>
+<h3>3.2 Dubbo IOC</h3>
+<p>Dubbo IOC 是通过 setter 方法注入依赖。Dubbo 首先会通过反射获取到实例的所有方法,然后再遍历方法列表,检测方法名是否具有 setter 方法特征。若有,则通过 ObjectFactory 获取依赖对象,最后通过反射调用 setter 方法将依赖设置到目标对象中。整个过程对应的代码如下:</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">private</span> T <span class="hljs-title">injectExtension</span><span class="hljs-params">(T instance)</span> </span>{
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-keyword">if</span> (objectFactory != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 遍历目标类的所有方法</span>
+ <span class="hljs-keyword">for</span> (Method method : instance.getClass().getMethods()) {
+ <span class="hljs-comment">// 检测方法是否以 set 开头,且方法仅有一个参数,且方法访问级别为 public</span>
+ <span class="hljs-keyword">if</span> (method.getName().startsWith(<span class="hljs-string">"set"</span>)
+ && method.getParameterTypes().length == <span class="hljs-number">1</span>
+ && Modifier.isPublic(method.getModifiers())) {
+ <span class="hljs-comment">// 获取 setter 方法参数类型</span>
+ Class<?> pt = method.getParameterTypes()[<span class="hljs-number">0</span>];
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-comment">// 获取属性名,比如 setName 方法对应属性名 name</span>
+ String property = method.getName().length() > <span class="hljs-number">3</span> ?
+ method.getName().substring(<span class="hljs-number">3</span>, <span class="hljs-number">4</span>).toLowerCase() +
+ method.getName().substring(<span class="hljs-number">4</span>) : <span class="hljs-string">""</span>;
+ <span class="hljs-comment">// 从 ObjectFactory 中获取依赖对象</span>
+ Object object = objectFactory.getExtension(pt, property);
+ <span class="hljs-keyword">if</span> (object != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 通过反射调用 setter 方法设置依赖</span>
+ method.invoke(instance, object);
+ }
+ } <span class="hljs-keyword">catch</span> (Exception e) {
+ logger.error(<span class="hljs-string">"fail to inject via method..."</span>);
+ }
+ }
+ }
+ }
+ } <span class="hljs-keyword">catch</span> (Exception e) {
+ logger.error(e.getMessage(), e);
+ }
+ <span class="hljs-keyword">return</span> instance;
+}
+</code></pre>
+<p>在上面代码中,objectFactory 变量的类型为 AdaptiveExtensionFactory,AdaptiveExtensionFactory 内部维护了一个 ExtensionFactory 列表,用于存储其他类型的 ExtensionFactory。Dubbo 目前提供了两种 ExtensionFactory,分别是 SpiExtensionFactory 和 SpringExtensionFactory。前者用于创建自适应的拓展,后者是用于从 Spring 的 IOC 容器中获取所需的拓展。这两个类的类的代码不是很复杂,这里就不一一分析了。</p>
+<p>Dubbo IOC 目前仅支持 setter 方式注入,总的来说,逻辑比较简单易懂。</p>
+<h2>4.总结</h2>
+<p>本篇文章简单分别介绍了 Java SPI 与 Dubbo SPI 用法,并对 Dubbo SPI 的加载拓展类的过程进行了分析。另外,在 Dubbo SPI 中还有一块重要的逻辑这里没有进行分析,即 Dubbo SPI 的扩展点自适应机制。该机制的逻辑较为复杂,我们将会在下一篇文章中进行详细的分析。</p>
+<p>好了,本篇文件就先到这里了。如果文章中有错误不妥之处,欢迎大家提 issue 进行反馈,或者提 pull request 进行修正。让我们携手共建 Dubbo 社区。</p>
+</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
+ <script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+ <script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+ <script>
+ window.rootPath = '';
+ </script>
+ <script src="/build/documentation.js"></script>
+ <!-- Global site tag (gtag.js) - Google Analytics -->
+ <script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+ <script>
+ window.dataLayer = window.dataLayer || [];
+ function gtag(){dataLayer.push(arguments);}
+ gtag('js', new Date());
+
+ gtag('config', 'UA-112489517-1');
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/zh-cn/docs/source_code_guide/dubbo-spi.json b/zh-cn/docs/source_code_guide/dubbo-spi.json
new file mode 100644
index 0000000..f645d22
--- /dev/null
+++ b/zh-cn/docs/source_code_guide/dubbo-spi.json
@@ -0,0 +1,10 @@
+{
+ "filename": "dubbo-spi.md",
+ "__html": "<h2>1.简介</h2>\n<p>SPI 全称为 Service Provider Interface,是一种服务发现机制。SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口替换实现类。正因此特性,我们可以很容易的通过 SPI 机制为我们的程序提供拓展功能。SPI 机制在第三方框架中也有所应用,比如 Dubbo 就是通过 SPI 机制加载所有的组件。不过,Dubbo 并未使用 Java 原生的 SPI 机制,而是对其进行了增强,使其能够更好的满足需求。在 Dubbo 中,SPI 是一个非常重要的模块。基于 SPI,我们可以很容易的对 Dubbo 进行拓展。如果大家想要学习 Dubbo 的源码,SPI 机制务必弄懂。接下来,我们先来了解一下 Java SPI 与 Dubbo SPI 的用法,然后再来分析 Dubbo SPI 的源码。</p>\n<h2>2.SPI 示例</h2>\n<h3>2.1 Java SPI 示例</h3>\n<p>前面简�
�介绍了 SPI 机制的原理, [...]
+ "link": "/zh-cn/docs/source_code_guide/dubbo-spi.html",
+ "meta": {
+ "title": "Dubbo SPI",
+ "keywords": "Dubbo, SPI",
+ "description": "本文介绍了 Dubbo SPI 的原理和实现细节"
+ }
+}
\ No newline at end of file
diff --git a/zh-cn/docs/source_code_guide/export-service.html b/zh-cn/docs/source_code_guide/export-service.html
new file mode 100644
index 0000000..75ca811
--- /dev/null
+++ b/zh-cn/docs/source_code_guide/export-service.html
@@ -0,0 +1,1387 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <meta name="keywords" content="Dubbo, service, export" />
+ <meta name="description" content="本文介绍了 Dubbo 服务导出的过程和实现细节" />
+ <!-- 网页标签标题 -->
+ <title>服务导出</title>
+ <link rel="shortcut icon" href="/img/dubbo.ico"/>
+ <link rel="stylesheet" href="/build/documentation.css" />
+</head>
+<body>
+ <div id="root"><div class="documentation-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a [...]
+<p>本篇文章,我们来研究一下 Dubbo 导出服务的过程。Dubbo 服务导出过程始于 Spring 容器发布刷新事件,Dubbo 在接收到事件后,会立即执行服务导出逻辑。整个逻辑大致可分为三个部分,第一部分是前置工作,主要用于检查参数,组装 URL。第二部分是导出服务,包含导出服务到本地 (JVM),和导出服务到远程两个过程。第三部分是向注册中心注册服务,用于服务发现。本篇文章将会对这三个部分代码进行详细的分析。</p>
+<h2>2.源码分析</h2>
+<p>服务导出的入口方法是 ServiceBean 的 onApplicationEvent。onApplicationEvent 是一个事件响应方法,该方法会在收到 Spring 上下文刷新事件后执行服务导出操作。方法代码如下:</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onApplicationEvent</span><span class="hljs-params">(ContextRefreshedEvent event)</span> </span>{
+ <span class="hljs-comment">// 是否有延迟导出 && 是否已导出 && 是不是已被取消导出</span>
+ <span class="hljs-keyword">if</span> (isDelay() && !isExported() && !isUnexported()) {
+ <span class="hljs-comment">// 导出服务</span>
+ export();
+ }
+}
+</code></pre>
+<p>这个方法首先会根据条件决定是否导出服务,比如有些服务设置了延时导出,那么此时就不应该在此处导出。还有一些服务已经被导出了,或者当前服务被取消导出了,此时也不能再次导出相关服务。注意这里的 isDelay 方法,这个方法字面意思是“是否延迟导出服务”,返回 true 表示延迟导出,false 表示不延迟导出。但是该方法真实意思却并非如此,当方法返回 true 时,表示无需延迟导出。返回 false 时,表示需要延迟导出。与字面意思恰恰相反,这个需要大家注意一下。下面我们来看一下这个方法的逻辑。</p>
+<pre><code class="language-java"><span class="hljs-comment">// -☆- ServiceBean</span>
+<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">isDelay</span><span class="hljs-params">()</span> </span>{
+ <span class="hljs-comment">// 获取 delay</span>
+ Integer delay = getDelay();
+ ProviderConfig provider = getProvider();
+ <span class="hljs-keyword">if</span> (delay == <span class="hljs-keyword">null</span> && provider != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 如果前面获取的 delay 为空,这里继续获取</span>
+ delay = provider.getDelay();
+ }
+ <span class="hljs-comment">// 判断 delay 是否为空,或者等于 -1</span>
+ <span class="hljs-keyword">return</span> supportedApplicationListener && (delay == <span class="hljs-keyword">null</span> || delay == -<span class="hljs-number">1</span>);
+}
+</code></pre>
+<p>暂时忽略 supportedApplicationListener 这个条件,当 delay 为空,或者等于-1时,该方法返回 true,而不是 false。这个方法的返回值让人有点困惑。该方法目前已被重构,详细请参考 <a href="https://github.com/apache/incubator-dubbo/pull/2686">incubator-dubbo #2686</a>。</p>
+<p>现在解释一下 supportedApplicationListener 变量含义,该变量用于表示当前的 Spring 容器是否支持 ApplicationListener,这个值初始为 false。在 Spring 容器将自己设置到 ServiceBean 中时,ServiceBean 的 setApplicationContext 方法会检测 Spring 容器是否支持 ApplicationListener。若支持,则将 supportedApplicationListener 置为 true。ServiceBean 是 Dubbo 与 Spring 框架进行整合的关键,可以看做是两个框架之间的桥梁。具有同样作用的类还有 ReferenceBean。</p>
+<p>现在我们知道了 Dubbo 服务导出过程的起点,接下来对服务导出的前置逻辑进行分析。</p>
+<h3>2.1 前置工作</h3>
+<p>前置工作主要包含两个部分,分别是配置检查,以及 URL 装配。在导出服务之前,Dubbo 需要检查用户的配置是否合理,或者为用户补充缺省配置。配置检查完成后,接下来需要根据这些配置组装 URL。在 Dubbo 中,URL 的作用十分重要。Dubbo 使用 URL 作为配置载体,所有的拓展点都是通过 URL 获取配置。这一点,官方文档中有所说明。</p>
+<blockquote>
+<p>采用 URL 作为配置信息的统一格式,所有扩展点都通过传递 URL 携带配置信息。</p>
+</blockquote>
+<p>接下来,我们先来分析配置检查部分的源码,随后再来分析 URL 组装部分的源码。</p>
+<h4>2.1.1 检查配置</h4>
+<p>本节我们接着前面的源码向下分析,前面说过 onApplicationEvent 方法在经过一些判断后,会决定是否调用 export 方法导出服务。那么下面我们从 export 方法开始进行分析,如下:</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">synchronized</span> <span class="hljs-keyword">void</span> <span class="hljs-title">export</span><span class="hljs-params">()</span> </span>{
+ <span class="hljs-keyword">if</span> (provider != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 获取 export 和 delay 配置</span>
+ <span class="hljs-keyword">if</span> (export == <span class="hljs-keyword">null</span>) {
+ export = provider.getExport();
+ }
+ <span class="hljs-keyword">if</span> (delay == <span class="hljs-keyword">null</span>) {
+ delay = provider.getDelay();
+ }
+ }
+ <span class="hljs-comment">// 如果 export 为 false,则不导出服务</span>
+ <span class="hljs-keyword">if</span> (export != <span class="hljs-keyword">null</span> && !export) {
+ <span class="hljs-keyword">return</span>;
+ }
+
+ <span class="hljs-comment">// delay > 0,延时导出服务</span>
+ <span class="hljs-keyword">if</span> (delay != <span class="hljs-keyword">null</span> && delay > <span class="hljs-number">0</span>) {
+ delayExportExecutor.schedule(<span class="hljs-keyword">new</span> Runnable() {
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span><span class="hljs-params">()</span> </span>{
+ doExport();
+ }
+ }, delay, TimeUnit.MILLISECONDS);
+
+ <span class="hljs-comment">// 立即导出服务</span>
+ } <span class="hljs-keyword">else</span> {
+ doExport();
+ }
+}
+</code></pre>
+<p>export 方法对两项配置进行了检查,并根据配置执行相应的动作。首先是 export 配置,这个配置决定了是否导出服务。有时候我们只是想本地启动服务进行一些调试工作,我们并不希望把本地启动的服务暴露出去给别人调用。此时,我们可通过配置 export 禁止服务导出,比如:</p>
+<pre><code class="language-xml"><span class="hljs-tag"><<span class="hljs-name">dubbo:provider</span> <span class="hljs-attr">export</span>=<span class="hljs-string">"false"</span> /></span>
+</code></pre>
+<p>delay 配置顾名思义,用于延迟导出服务,这个就不分析了。下面,我们继续分析源码,这次要分析的是 doExport 方法。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">synchronized</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doExport</span><span class="hljs-params">()</span> </span>{
+ <span class="hljs-keyword">if</span> (unexported) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"Already unexported!"</span>);
+ }
+ <span class="hljs-keyword">if</span> (exported) {
+ <span class="hljs-keyword">return</span>;
+ }
+ exported = <span class="hljs-keyword">true</span>;
+ <span class="hljs-comment">// 检测 interfaceName 是否合法</span>
+ <span class="hljs-keyword">if</span> (interfaceName == <span class="hljs-keyword">null</span> || interfaceName.length() == <span class="hljs-number">0</span>) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"interface not allow null!"</span>);
+ }
+ <span class="hljs-comment">// 检测 provider 是否为空,为空则新建一个,并通过系统变量为其初始化</span>
+ checkDefault();
+
+ <span class="hljs-comment">// 下面几个 if 语句用于检测 provider、application 等核心配置类对象是否为空,</span>
+ <span class="hljs-comment">// 若为空,则尝试从其他配置类对象中获取相应的实例。</span>
+ <span class="hljs-keyword">if</span> (provider != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">if</span> (application == <span class="hljs-keyword">null</span>) {
+ application = provider.getApplication();
+ }
+ <span class="hljs-keyword">if</span> (<span class="hljs-keyword">module</span> == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">module</span> = provider.getModule();
+ }
+ <span class="hljs-keyword">if</span> (registries == <span class="hljs-keyword">null</span>) {...}
+ <span class="hljs-keyword">if</span> (monitor == <span class="hljs-keyword">null</span>) {...}
+ <span class="hljs-keyword">if</span> (protocols == <span class="hljs-keyword">null</span>) {...}
+ }
+ <span class="hljs-keyword">if</span> (<span class="hljs-keyword">module</span> != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">if</span> (registries == <span class="hljs-keyword">null</span>) {
+ registries = <span class="hljs-keyword">module</span>.getRegistries();
+ }
+ <span class="hljs-keyword">if</span> (monitor == <span class="hljs-keyword">null</span>) {...}
+ }
+ <span class="hljs-keyword">if</span> (application != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">if</span> (registries == <span class="hljs-keyword">null</span>) {
+ registries = application.getRegistries();
+ }
+ <span class="hljs-keyword">if</span> (monitor == <span class="hljs-keyword">null</span>) {...}
+ }
+
+ <span class="hljs-comment">// 检测 ref 是否为泛化服务类型</span>
+ <span class="hljs-keyword">if</span> (ref <span class="hljs-keyword">instanceof</span> GenericService) {
+ <span class="hljs-comment">// 设置 interfaceClass 为 GenericService.class</span>
+ interfaceClass = GenericService.class;
+ <span class="hljs-keyword">if</span> (StringUtils.isEmpty(generic)) {
+ <span class="hljs-comment">// 设置 generic = "true"</span>
+ generic = Boolean.TRUE.toString();
+ }
+
+ <span class="hljs-comment">// ref 非 GenericService 类型</span>
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-keyword">try</span> {
+ interfaceClass = Class.forName(interfaceName, <span class="hljs-keyword">true</span>, Thread.currentThread()
+ .getContextClassLoader());
+ } <span class="hljs-keyword">catch</span> (ClassNotFoundException e) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(e.getMessage(), e);
+ }
+ <span class="hljs-comment">// 对 interfaceClass,以及 <dubbo:method> 标签中的必要字段进行检查</span>
+ checkInterfaceAndMethods(interfaceClass, methods);
+ <span class="hljs-comment">// 对 ref 合法性进行检测</span>
+ checkRef();
+ <span class="hljs-comment">// 设置 generic = "false"</span>
+ generic = Boolean.FALSE.toString();
+ }
+
+ <span class="hljs-comment">// local 和 stub 在功能应该是一致的,用于配置本地存根</span>
+ <span class="hljs-keyword">if</span> (local != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">if</span> (<span class="hljs-string">"true"</span>.equals(local)) {
+ local = interfaceName + <span class="hljs-string">"Local"</span>;
+ }
+ Class<?> localClass;
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-comment">// 获取本地存根类</span>
+ localClass = ClassHelper.forNameWithThreadContextClassLoader(local);
+ } <span class="hljs-keyword">catch</span> (ClassNotFoundException e) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(e.getMessage(), e);
+ }
+ <span class="hljs-comment">// 检测本地存根类是否可赋值给接口类,若不可赋值则会抛出异常,提醒使用者本地存根类类型不合法</span>
+ <span class="hljs-keyword">if</span> (!interfaceClass.isAssignableFrom(localClass)) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"The local implementation class "</span> + localClass.getName() + <span class="hljs-string">" not implement interface "</span> + interfaceName);
+ }
+ }
+
+ <span class="hljs-keyword">if</span> (stub != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 此处的代码和上一个 if 分支的代码基本一致,这里省略</span>
+ }
+
+ <span class="hljs-comment">// 检测各种对象是否为空,为空则新建,或者抛出异常</span>
+ checkApplication();
+ checkRegistry();
+ checkProtocol();
+ appendProperties(<span class="hljs-keyword">this</span>);
+ checkStubAndMock(interfaceClass);
+ <span class="hljs-keyword">if</span> (path == <span class="hljs-keyword">null</span> || path.length() == <span class="hljs-number">0</span>) {
+ path = interfaceName;
+ }
+
+ <span class="hljs-comment">// 导出服务</span>
+ doExportUrls();
+
+ <span class="hljs-comment">// ProviderModel 表示服务提供者模型,此对象中存储了与服务提供者相关的信息。</span>
+ <span class="hljs-comment">// 比如服务的配置信息,服务实例等。每个被导出的服务对应一个 ProviderModel。</span>
+ <span class="hljs-comment">// ApplicationModel 持有所有的 ProviderModel。</span>
+ ProviderModel providerModel = <span class="hljs-keyword">new</span> ProviderModel(getUniqueServiceName(), <span class="hljs-keyword">this</span>, ref);
+ ApplicationModel.initProviderModel(getUniqueServiceName(), providerModel);
+}
+</code></pre>
+<p>以上就是配置检查的相关分析,代码比较多,需要大家耐心看一下。下面对配置检查的逻辑进行简单的总结,如下:</p>
+<ol>
+<li>检测 <dubbo:service> 标签的 interface 属性合法性,不合法则抛出异常</li>
+<li>检测 ProviderConfig、ApplicationConfig 等核心配置类对象是否为空,若为空,则尝试从其他配置类对象中获取相应的实例。</li>
+<li>检测并处理泛化服务和普通服务类</li>
+<li>检测本地存根配置,并进行相应的处理</li>
+<li>对 ApplicationConfig、RegistryConfig 等配置类进行检测,为空则尝试创建,若无法创建则抛出异常</li>
+</ol>
+<p>配置检查并非本文重点,因此这里不打算对 doExport 方法所调用的方法进行分析(doExportUrls 方法除外)。在这些方法中,除了 appendProperties 方法稍微复杂一些,其他方法逻辑不是很复杂。因此,大家可自行分析。</p>
+<h4>2.1.2 多协议多注册中心导出服务</h4>
+<p>Dubbo 允许我们使用不同的协议导出服务,也允许我们向多个注册中心注册服务。Dubbo 在 doExportUrls 方法中对多协议,多注册中心进行了支持。相关代码如下:</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doExportUrls</span><span class="hljs-params">()</span> </span>{
+ <span class="hljs-comment">// 加载注册中心链接</span>
+ List<URL> registryURLs = loadRegistries(<span class="hljs-keyword">true</span>);
+ <span class="hljs-comment">// 遍历 protocols,并在每个协议下导出服务</span>
+ <span class="hljs-keyword">for</span> (ProtocolConfig protocolConfig : protocols) {
+ doExportUrlsFor1Protocol(protocolConfig, registryURLs);
+ }
+}
+</code></pre>
+<p>上面代码首先是通过 loadRegistries 加载注册中心链接,然后再遍历 ProtocolConfig 集合导出每个服务。并在导出服务的过程中,将服务注册到注册中心。下面,我们先来看一下 loadRegistries 方法的逻辑。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">protected</span> List<URL> <span class="hljs-title">loadRegistries</span><span class="hljs-params">(<span class="hljs-keyword">boolean</span> provider)</span> </span>{
+ <span class="hljs-comment">// 检测是否存在注册中心配置类,不存在则抛出异常</span>
+ checkRegistry();
+ List<URL> registryList = <span class="hljs-keyword">new</span> ArrayList<URL>();
+ <span class="hljs-keyword">if</span> (registries != <span class="hljs-keyword">null</span> && !registries.isEmpty()) {
+ <span class="hljs-keyword">for</span> (RegistryConfig config : registries) {
+ String address = config.getAddress();
+ <span class="hljs-keyword">if</span> (address == <span class="hljs-keyword">null</span> || address.length() == <span class="hljs-number">0</span>) {
+ <span class="hljs-comment">// 若 address 为空,则将其设为 0.0.0.0</span>
+ address = Constants.ANYHOST_VALUE;
+ }
+
+ <span class="hljs-comment">// 从系统属性中加载注册中心地址</span>
+ String sysaddress = System.getProperty(<span class="hljs-string">"dubbo.registry.address"</span>);
+ <span class="hljs-keyword">if</span> (sysaddress != <span class="hljs-keyword">null</span> && sysaddress.length() > <span class="hljs-number">0</span>) {
+ address = sysaddress;
+ }
+ <span class="hljs-comment">// 检测 address 是否合法</span>
+ <span class="hljs-keyword">if</span> (address.length() > <span class="hljs-number">0</span> && !RegistryConfig.NO_AVAILABLE.equalsIgnoreCase(address)) {
+ Map<String, String> map = <span class="hljs-keyword">new</span> HashMap<String, String>();
+ <span class="hljs-comment">// 添加 ApplicationConfig 中的字段信息到 map 中</span>
+ appendParameters(map, application);
+ <span class="hljs-comment">// 添加 RegistryConfig 字段信息到 map 中</span>
+ appendParameters(map, config);
+
+ <span class="hljs-comment">// 添加 path、pid,protocol 等信息到 map 中</span>
+ map.put(<span class="hljs-string">"path"</span>, RegistryService.class.getName());
+ map.put(<span class="hljs-string">"dubbo"</span>, Version.getProtocolVersion());
+ map.put(Constants.TIMESTAMP_KEY, String.valueOf(System.currentTimeMillis()));
+ <span class="hljs-keyword">if</span> (ConfigUtils.getPid() > <span class="hljs-number">0</span>) {
+ map.put(Constants.PID_KEY, String.valueOf(ConfigUtils.getPid()));
+ }
+ <span class="hljs-keyword">if</span> (!map.containsKey(<span class="hljs-string">"protocol"</span>)) {
+ <span class="hljs-keyword">if</span> (ExtensionLoader.getExtensionLoader(RegistryFactory.class).hasExtension(<span class="hljs-string">"remote"</span>)) {
+ map.put(<span class="hljs-string">"protocol"</span>, <span class="hljs-string">"remote"</span>);
+ } <span class="hljs-keyword">else</span> {
+ map.put(<span class="hljs-string">"protocol"</span>, <span class="hljs-string">"dubbo"</span>);
+ }
+ }
+
+ <span class="hljs-comment">// 解析得到 URL 列表,address 可能包含多个注册中心 ip,</span>
+ <span class="hljs-comment">// 因此解析得到的是一个 URL 列表</span>
+ List<URL> urls = UrlUtils.parseURLs(address, map);
+ <span class="hljs-keyword">for</span> (URL url : urls) {
+ url = url.addParameter(Constants.REGISTRY_KEY, url.getProtocol());
+ <span class="hljs-comment">// 将 URL 协议头设置为 registry</span>
+ url = url.setProtocol(Constants.REGISTRY_PROTOCOL);
+ <span class="hljs-comment">// 通过判断条件,决定是否添加 url 到 registryList 中,条件如下:</span>
+ <span class="hljs-comment">// (服务提供者 && register = true 或 null) </span>
+ <span class="hljs-comment">// || (非服务提供者 && subscribe = true 或 null)</span>
+ <span class="hljs-keyword">if</span> ((provider && url.getParameter(Constants.REGISTER_KEY, <span class="hljs-keyword">true</span>))
+ || (!provider && url.getParameter(Constants.SUBSCRIBE_KEY, <span class="hljs-keyword">true</span>))) {
+ registryList.add(url);
+ }
+ }
+ }
+ }
+ }
+ <span class="hljs-keyword">return</span> registryList;
+}
+</code></pre>
+<p>loadRegistries 方法主要包含如下的逻辑:</p>
+<ol>
+<li>检测是否存在注册中心配置类,不存在则抛出异常</li>
+<li>构建参数映射集合,也就是 map</li>
+<li>构建注册中心链接列表</li>
+<li>遍历链接列表,并根据条件决定是否将其添加到 registryList 中</li>
+</ol>
+<p>关于多协议多注册中心导出服务就先分析到这,代码不是很多,接下来分析 URL 组装过程。</p>
+<h4>2.1.3 组装 URL</h4>
+<p>配置检查完毕后,紧接着要做的事情是根据配置,以及其他一些信息组装 URL。前面说过,URL 是 Dubbo 配置的载体,通过 URL 可让 Dubbo 的各种配置在各个模块之间传递。URL 之于 Dubbo,犹如水之于鱼,非常重要。大家在阅读 Dubbo 服务导出相关源码的过程中,要注意 URL 内容的变化。既然 URL 如此重要,那么下面我们来了解一下 URL 组装的过程。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doExportUrlsFor1Protocol</span><span class="hljs-params">(ProtocolConfig protocolConfig, List<URL> registryURLs)</span> </span>{
+ String name = protocolConfig.getName();
+ <span class="hljs-comment">// 如果协议名为空,或空串,则将协议名变量设置为 dubbo</span>
+ <span class="hljs-keyword">if</span> (name == <span class="hljs-keyword">null</span> || name.length() == <span class="hljs-number">0</span>) {
+ name = <span class="hljs-string">"dubbo"</span>;
+ }
+
+ Map<String, String> map = <span class="hljs-keyword">new</span> HashMap<String, String>();
+ <span class="hljs-comment">// 添加 side、版本、时间戳以及进程号等信息到 map 中</span>
+ map.put(Constants.SIDE_KEY, Constants.PROVIDER_SIDE);
+ map.put(Constants.DUBBO_VERSION_KEY, Version.getProtocolVersion());
+ map.put(Constants.TIMESTAMP_KEY, String.valueOf(System.currentTimeMillis()));
+ <span class="hljs-keyword">if</span> (ConfigUtils.getPid() > <span class="hljs-number">0</span>) {
+ map.put(Constants.PID_KEY, String.valueOf(ConfigUtils.getPid()));
+ }
+
+ <span class="hljs-comment">// 通过反射将对象的字段信息添加到 map 中</span>
+ appendParameters(map, application);
+ appendParameters(map, <span class="hljs-keyword">module</span>);
+ appendParameters(map, provider, Constants.DEFAULT_KEY);
+ appendParameters(map, protocolConfig);
+ appendParameters(map, <span class="hljs-keyword">this</span>);
+
+ <span class="hljs-comment">// methods 为 MethodConfig 集合,MethodConfig 中存储了 <dubbo:method> 标签的配置信息</span>
+ <span class="hljs-keyword">if</span> (methods != <span class="hljs-keyword">null</span> && !methods.isEmpty()) {
+ <span class="hljs-comment">// 这段代码用于添加 Callback 配置到 map 中,代码太长,待会单独分析</span>
+ }
+
+ <span class="hljs-comment">// 检测 generic 是否为 "true",并根据检测结果向 map 中添加不同的信息</span>
+ <span class="hljs-keyword">if</span> (ProtocolUtils.isGeneric(generic)) {
+ map.put(Constants.GENERIC_KEY, generic);
+ map.put(Constants.METHODS_KEY, Constants.ANY_VALUE);
+ } <span class="hljs-keyword">else</span> {
+ String revision = Version.getVersion(interfaceClass, version);
+ <span class="hljs-keyword">if</span> (revision != <span class="hljs-keyword">null</span> && revision.length() > <span class="hljs-number">0</span>) {
+ map.put(<span class="hljs-string">"revision"</span>, revision);
+ }
+
+ <span class="hljs-comment">// 为接口生成包裹类 Wrapper,Wrapper 中包含了接口的详细信息,比如接口方法名数组,字段信息等</span>
+ String[] methods = Wrapper.getWrapper(interfaceClass).getMethodNames();
+ <span class="hljs-comment">// 添加方法名到 map 中,如果包含多个方法名,则用逗号隔开,比如 method = init,destroy</span>
+ <span class="hljs-keyword">if</span> (methods.length == <span class="hljs-number">0</span>) {
+ logger.warn(<span class="hljs-string">"NO method found in service interface ..."</span>);
+ map.put(Constants.METHODS_KEY, Constants.ANY_VALUE);
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-comment">// 将逗号作为分隔符连接方法名,并将连接后的字符串放入 map 中</span>
+ map.put(Constants.METHODS_KEY, StringUtils.join(<span class="hljs-keyword">new</span> HashSet<String>(Arrays.asList(methods)), <span class="hljs-string">","</span>));
+ }
+ }
+
+ <span class="hljs-comment">// 添加 token 到 map 中</span>
+ <span class="hljs-keyword">if</span> (!ConfigUtils.isEmpty(token)) {
+ <span class="hljs-keyword">if</span> (ConfigUtils.isDefault(token)) {
+ <span class="hljs-comment">// 随机生成 token</span>
+ map.put(Constants.TOKEN_KEY, UUID.randomUUID().toString());
+ } <span class="hljs-keyword">else</span> {
+ map.put(Constants.TOKEN_KEY, token);
+ }
+ }
+ <span class="hljs-comment">// 判断协议名是否为 injvm</span>
+ <span class="hljs-keyword">if</span> (Constants.LOCAL_PROTOCOL.equals(protocolConfig.getName())) {
+ protocolConfig.setRegister(<span class="hljs-keyword">false</span>);
+ map.put(<span class="hljs-string">"notify"</span>, <span class="hljs-string">"false"</span>);
+ }
+
+ <span class="hljs-comment">// 获取上下文路径</span>
+ String contextPath = protocolConfig.getContextpath();
+ <span class="hljs-keyword">if</span> ((contextPath == <span class="hljs-keyword">null</span> || contextPath.length() == <span class="hljs-number">0</span>) && provider != <span class="hljs-keyword">null</span>) {
+ contextPath = provider.getContextpath();
+ }
+
+ <span class="hljs-comment">// 获取 host 和 port</span>
+ String host = <span class="hljs-keyword">this</span>.findConfigedHosts(protocolConfig, registryURLs, map);
+ Integer port = <span class="hljs-keyword">this</span>.findConfigedPorts(protocolConfig, name, map);
+ <span class="hljs-comment">// 组装 URL</span>
+ URL url = <span class="hljs-keyword">new</span> URL(name, host, port, (contextPath == <span class="hljs-keyword">null</span> || contextPath.length() == <span class="hljs-number">0</span> ? <span class="hljs-string">""</span> : contextPath + <span class="hljs-string">"/"</span>) + path, map);
+
+ <span class="hljs-comment">// 省略无关代码</span>
+}
+</code></pre>
+<p>上面的代码首先是将一些信息,比如版本、时间戳、方法名以及各种配置对象的字段信息放入到 map 中,map 中的内容将作为 URL 的查询字符串。构建好 map 后,紧接着是获取上下文路径、主机名以及端口号等信息。最后将 map 和主机名等数据传给 URL 构造方法创建 URL 对象。需要注意的是,这里出现的 URL 并非 java.net.URL,而是 com.alibaba.dubbo.common.URL。</p>
+<p>上面省略了一段代码,这里简单分析一下。这段代码用于检测 <dubbo:argument> 标签中的配置信息,并将相关配置添加到 map 中。代码如下:</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doExportUrlsFor1Protocol</span><span class="hljs-params">(ProtocolConfig protocolConfig, List<URL> registryURLs)</span> </span>{
+ <span class="hljs-comment">// ...</span>
+
+ <span class="hljs-comment">// methods 为 MethodConfig 集合,MethodConfig 中存储了 <dubbo:method> 标签的配置信息</span>
+ <span class="hljs-keyword">if</span> (methods != <span class="hljs-keyword">null</span> && !methods.isEmpty()) {
+ <span class="hljs-keyword">for</span> (MethodConfig method : methods) {
+ <span class="hljs-comment">// 添加 MethodConfig 对象的字段信息到 map 中,键 = 方法名.属性名。</span>
+ <span class="hljs-comment">// 比如存储 <dubbo:method name="sayHello" retries="2"> 对应的 MethodConfig,</span>
+ <span class="hljs-comment">// 键 = sayHello.retries,map = {"sayHello.retries": 2, "xxx": "yyy"}</span>
+ appendParameters(map, method, method.getName());
+
+ String retryKey = method.getName() + <span class="hljs-string">".retry"</span>;
+ <span class="hljs-keyword">if</span> (map.containsKey(retryKey)) {
+ String retryValue = map.remove(retryKey);
+ <span class="hljs-comment">// 检测 MethodConfig retry 是否为 false,若是,则设置重试次数为0</span>
+ <span class="hljs-keyword">if</span> (<span class="hljs-string">"false"</span>.equals(retryValue)) {
+ map.put(method.getName() + <span class="hljs-string">".retries"</span>, <span class="hljs-string">"0"</span>);
+ }
+ }
+
+ <span class="hljs-comment">// 获取 ArgumentConfig 列表</span>
+ List<ArgumentConfig> arguments = method.getArguments();
+ <span class="hljs-keyword">if</span> (arguments != <span class="hljs-keyword">null</span> && !arguments.isEmpty()) {
+ <span class="hljs-keyword">for</span> (ArgumentConfig argument : arguments) {
+ <span class="hljs-comment">// 检测 type 属性是否为空,或者空串(分支1 ⭐️)</span>
+ <span class="hljs-keyword">if</span> (argument.getType() != <span class="hljs-keyword">null</span> && argument.getType().length() > <span class="hljs-number">0</span>) {
+ Method[] methods = interfaceClass.getMethods();
+ <span class="hljs-keyword">if</span> (methods != <span class="hljs-keyword">null</span> && methods.length > <span class="hljs-number">0</span>) {
+ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < methods.length; i++) {
+ String methodName = methods[i].getName();
+ <span class="hljs-comment">// 比对方法名,查找目标方法</span>
+ <span class="hljs-keyword">if</span> (methodName.equals(method.getName())) {
+ Class<?>[] argtypes = methods[i].getParameterTypes();
+ <span class="hljs-keyword">if</span> (argument.getIndex() != -<span class="hljs-number">1</span>) {
+ <span class="hljs-comment">// 检测 ArgumentConfig 中的 type 属性与方法参数列表</span>
+ <span class="hljs-comment">// 中的参数名称是否一致,不一致则抛出异常(分支2 ⭐️)</span>
+ <span class="hljs-keyword">if</span> (argtypes[argument.getIndex()].getName().equals(argument.getType())) {
+ <span class="hljs-comment">// 添加 ArgumentConfig 字段信息到 map 中,</span>
+ <span class="hljs-comment">// 键前缀 = 方法名.index,比如:</span>
+ <span class="hljs-comment">// map = {"sayHello.3": true}</span>
+ appendParameters(map, argument, method.getName() + <span class="hljs-string">"."</span> + argument.getIndex());
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"argument config error: ..."</span>);
+ }
+ } <span class="hljs-keyword">else</span> { <span class="hljs-comment">// 分支3 ⭐️</span>
+ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> j = <span class="hljs-number">0</span>; j < argtypes.length; j++) {
+ Class<?> argclazz = argtypes[j];
+ <span class="hljs-comment">// 从参数类型列表中查找类型名称为 argument.type 的参数</span>
+ <span class="hljs-keyword">if</span> (argclazz.getName().equals(argument.getType())) {
+ appendParameters(map, argument, method.getName() + <span class="hljs-string">"."</span> + j);
+ <span class="hljs-keyword">if</span> (argument.getIndex() != -<span class="hljs-number">1</span> && argument.getIndex() != j) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"argument config error: ..."</span>);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ <span class="hljs-comment">// 用户未配置 type 属性,但配置了 index 属性,且 index != -1</span>
+ } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (argument.getIndex() != -<span class="hljs-number">1</span>) { <span class="hljs-comment">// 分支4 ⭐️</span>
+ <span class="hljs-comment">// 添加 ArgumentConfig 字段信息到 map 中</span>
+ appendParameters(map, argument, method.getName() + <span class="hljs-string">"."</span> + argument.getIndex());
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"argument config must set index or type"</span>);
+ }
+ }
+ }
+ }
+ }
+
+ <span class="hljs-comment">// ...</span>
+}
+</code></pre>
+<p>上面这段代码 for 循环和 if else 分支嵌套太多,导致层次太深,不利于阅读,需要耐心看一下。大家在看这段代码时,注意把几个重要的条件分支找出来。只要理解了这几个分支的意图,就可以弄懂这段代码。请注意上面代码中⭐️符号,这几个符号标识出了4个重要的分支,下面用伪代码解释一下这几个分支的含义。</p>
+<pre><code class="language-java"><span class="hljs-comment">// 获取 ArgumentConfig 列表</span>
+<span class="hljs-keyword">for</span> (遍历 ArgumentConfig 列表) {
+ <span class="hljs-keyword">if</span> (type 不为 <span class="hljs-keyword">null</span>,也不为空串) { <span class="hljs-comment">// 分支1</span>
+ <span class="hljs-number">1</span>. 通过反射获取 interfaceClass 的方法列表
+ <span class="hljs-keyword">for</span> (遍历方法列表) {
+ <span class="hljs-number">1</span>. 比对方法名,查找目标方法
+ <span class="hljs-number">2</span>. 通过反射获取目标方法的参数类型数组 <span class="hljs-function">argtypes
+ <span class="hljs-title">if</span> <span class="hljs-params">(index != <span class="hljs-number">-1</span>)</span> </span>{ <span class="hljs-comment">// 分支2</span>
+ <span class="hljs-number">1</span>. 从 argtypes 数组中获取下标 index 处的元素 argType
+ <span class="hljs-number">2</span>. 检测 argType 的名称与 ArgumentConfig 中的 type 属性是否一致
+ <span class="hljs-number">3</span>. 添加 ArgumentConfig 字段信息到 map 中,或抛出异常
+ } <span class="hljs-keyword">else</span> { <span class="hljs-comment">// 分支3</span>
+ <span class="hljs-number">1</span>. 遍历参数类型数组 argtypes,查找 argument.type 类型的参数
+ <span class="hljs-number">2</span>. 添加 ArgumentConfig 字段信息到 map 中
+ }
+ }
+ } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (index != -<span class="hljs-number">1</span>) { <span class="hljs-comment">// 分支4</span>
+ <span class="hljs-number">1</span>. 添加 ArgumentConfig 字段信息到 map 中
+ }
+}
+</code></pre>
+<p>在本节分析的源码中,appendParameters 这个方法出现的次数比较多,该方法用于将对象字段信息添加到 map 中。实现上则是通过反射获取目标对象的 getter 方法,并调用该方法获取属性值。然后再通过 getter 方法名解析出属性名,比如从方法名 getName 中可解析出属性 name。如果用户传入了属性名前缀,此时需要将属性名加入前缀内容。最后将 <属性名,属性值> 键值对存入到 map 中就行了。限于篇幅原因,这里就不分析 appendParameters 方法的源码了,大家请自行分析。</p>
+<h3>2.2 导出 Dubbo 服务</h3>
+<p>前置工作做完,接下来就可以进行服务导出了。服务导出分为导出到本地 (JVM),和导出到远程。在深入分析服务导出的源码前,我们先来从宏观层面上看一下服务导出逻辑。如下:</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doExportUrlsFor1Protocol</span><span class="hljs-params">(ProtocolConfig protocolConfig, List<URL> registryURLs)</span> </span>{
+
+ <span class="hljs-comment">// 省略无关代码</span>
+
+ <span class="hljs-keyword">if</span> (ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class)
+ .hasExtension(url.getProtocol())) {
+ <span class="hljs-comment">// 加载 ConfiguratorFactory,并生成 Configurator 实例,然后通过实例配置 url</span>
+ url = ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class)
+ .getExtension(url.getProtocol()).getConfigurator(url).configure(url);
+ }
+
+ String scope = url.getParameter(Constants.SCOPE_KEY);
+ <span class="hljs-comment">// 如果 scope = none,则什么都不做</span>
+ <span class="hljs-keyword">if</span> (!Constants.SCOPE_NONE.toString().equalsIgnoreCase(scope)) {
+ <span class="hljs-comment">// scope != remote,导出到本地</span>
+ <span class="hljs-keyword">if</span> (!Constants.SCOPE_REMOTE.toString().equalsIgnoreCase(scope)) {
+ exportLocal(url);
+ }
+
+ <span class="hljs-comment">// scope != local,导出到远程</span>
+ <span class="hljs-keyword">if</span> (!Constants.SCOPE_LOCAL.toString().equalsIgnoreCase(scope)) {
+ <span class="hljs-keyword">if</span> (registryURLs != <span class="hljs-keyword">null</span> && !registryURLs.isEmpty()) {
+ <span class="hljs-keyword">for</span> (URL registryURL : registryURLs) {
+ url = url.addParameterIfAbsent(Constants.DYNAMIC_KEY, registryURL.getParameter(Constants.DYNAMIC_KEY));
+ <span class="hljs-comment">// 加载监视器链接</span>
+ URL monitorUrl = loadMonitor(registryURL);
+ <span class="hljs-keyword">if</span> (monitorUrl != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 将监视器链接作为参数添加到 url 中</span>
+ url = url.addParameterAndEncoded(Constants.MONITOR_KEY, monitorUrl.toFullString());
+ }
+
+ String proxy = url.getParameter(Constants.PROXY_KEY);
+ <span class="hljs-keyword">if</span> (StringUtils.isNotEmpty(proxy)) {
+ registryURL = registryURL.addParameter(Constants.PROXY_KEY, proxy);
+ }
+
+ <span class="hljs-comment">// 为服务提供类(ref)生成 Invoker</span>
+ Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(Constants.EXPORT_KEY, url.toFullString()));
+ <span class="hljs-comment">// DelegateProviderMetaDataInvoker 用于持有 Invoker 和 ServiceConfig</span>
+ DelegateProviderMetaDataInvoker wrapperInvoker = <span class="hljs-keyword">new</span> DelegateProviderMetaDataInvoker(invoker, <span class="hljs-keyword">this</span>);
+
+ <span class="hljs-comment">// 导出服务,并生成 Exporter</span>
+ Exporter<?> exporter = protocol.export(wrapperInvoker);
+ exporters.add(exporter);
+ }
+
+ <span class="hljs-comment">// 不存在注册中心,仅导出服务</span>
+ } <span class="hljs-keyword">else</span> {
+ Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, url);
+ DelegateProviderMetaDataInvoker wrapperInvoker = <span class="hljs-keyword">new</span> DelegateProviderMetaDataInvoker(invoker, <span class="hljs-keyword">this</span>);
+
+ Exporter<?> exporter = protocol.export(wrapperInvoker);
+ exporters.add(exporter);
+ }
+ }
+ }
+ <span class="hljs-keyword">this</span>.urls.add(url);
+}
+</code></pre>
+<p>上面代码根据 url 中的 scope 参数决定服务导出方式,分别如下:</p>
+<ul>
+<li>scope = none,不导出服务</li>
+<li>scope != remote,导出到本地</li>
+<li>scope != local,导出到远程</li>
+</ul>
+<p>不管是导出到本地,还是远程。进行服务导出之前,均需要先创建 Invoker,这是一个很重要的步骤。因此下面先来分析 Invoker 的创建过程。</p>
+<h3>2.2.1 Invoker 创建过程</h3>
+<p>在 Dubbo 中,Invoker 是一个非常重要的模型。在服务提供端,以及服务引用端均会出现 Invoker。Dubbo 官方文档中对 Invoker 进行了说明,这里引用一下。</p>
+<blockquote>
+<p>Invoker 是实体域,它是 Dubbo 的核心模型,其它模型都向它靠扰,或转换成它,它代表一个可执行体,可向它发起 invoke 调用,它有可能是一个本地的实现,也可能是一个远程的实现,也可能一个集群实现。</p>
+</blockquote>
+<p>既然 Invoker 如此重要,那么我们很有必要搞清楚 Invoker 的用途。Invoker 是由 ProxyFactory 创建而来,Dubbo 默认的 ProxyFactory 实现类是 JavassistProxyFactory。下面我们到 JavassistProxyFactory 代码中,探索 Invoker 的创建过程。如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <T> <span class="hljs-function">Invoker<T> <span class="hljs-title">getInvoker</span><span class="hljs-params">(T proxy, Class<T> type, URL url)</span> </span>{
+ <span class="hljs-comment">// 为目标类创建 Wrapper</span>
+ <span class="hljs-keyword">final</span> Wrapper wrapper = Wrapper.getWrapper(proxy.getClass().getName().indexOf(<span class="hljs-string">'$'</span>) < <span class="hljs-number">0</span> ? proxy.getClass() : type);
+ <span class="hljs-comment">// 创建匿名 Invoker 类对象,并实现 doInvoke 方法。</span>
+ <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> AbstractProxyInvoker<T>(proxy, type, url) {
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-function"><span class="hljs-keyword">protected</span> Object <span class="hljs-title">doInvoke</span><span class="hljs-params">(T proxy, String methodName,
+ Class<?>[] parameterTypes,
+ Object[] arguments)</span> <span class="hljs-keyword">throws</span> Throwable </span>{
+ <span class="hljs-comment">// 调用 Wrapper 的 invokeMethod 方法,invokeMethod 最终会调用目标方法</span>
+ <span class="hljs-keyword">return</span> wrapper.invokeMethod(proxy, methodName, parameterTypes, arguments);
+ }
+ };
+}
+</code></pre>
+<p>如上,JavassistProxyFactory 创建了一个继承自 AbstractProxyInvoker 类的匿名对象,并覆写了抽象方法 doInvoke。覆写后的 doInvoke 逻辑比较简单,仅是将调用请求转发给了 Wrapper 类的 invokeMethod 方法。Wrapper 用于“包裹”目标类,Wrapper 是一个抽象类,仅可通过 getWrapper(Class) 方法创建子类。在创建 Wrapper 子类的过程中,子类代码生成逻辑会对 getWrapper 方法传入的 Class 对象进行解析,拿到诸如类方法,类成员变量等信息。以及生成 invokeMethod 方法代码和其他一些方法代码。代码生成完毕后,通过 Javassist 生成 Class 对象,最后再通过反射创建 Wrapper 实例。相关的代码如下:</p>
+<pre><code class="language-java"> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Wrapper <span class="hljs-title">getWrapper</span><span class="hljs-params">(Class<?> c)</span> </span>{
+ <span class="hljs-keyword">while</span> (ClassGenerator.isDynamicClass(c))
+ c = c.getSuperclass();
+
+ <span class="hljs-keyword">if</span> (c == Object.class)
+ <span class="hljs-keyword">return</span> OBJECT_WRAPPER;
+
+ <span class="hljs-comment">// 从缓存中获取 Wrapper 实例</span>
+ Wrapper ret = WRAPPER_MAP.get(c);
+ <span class="hljs-keyword">if</span> (ret == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 缓存未命中,创建 Wrapper</span>
+ ret = makeWrapper(c);
+ <span class="hljs-comment">// 写入缓存</span>
+ WRAPPER_MAP.put(c, ret);
+ }
+ <span class="hljs-keyword">return</span> ret;
+}
+</code></pre>
+<p>getWrapper 方法仅包含一些缓存操作逻辑,不难理解。下面我们看一下 makeWrapper 方法。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> Wrapper <span class="hljs-title">makeWrapper</span><span class="hljs-params">(Class<?> c)</span> </span>{
+ <span class="hljs-comment">// 检测 c 是否为私有类型,若是则抛出异常</span>
+ <span class="hljs-keyword">if</span> (c.isPrimitive())
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"Can not create wrapper for primitive type: "</span> + c);
+
+ String name = c.getName();
+ ClassLoader cl = ClassHelper.getClassLoader(c);
+
+ <span class="hljs-comment">// c1 用于存储 setPropertyValue 方法代码</span>
+ StringBuilder c1 = <span class="hljs-keyword">new</span> StringBuilder(<span class="hljs-string">"public void setPropertyValue(Object o, String n, Object v){ "</span>);
+ <span class="hljs-comment">// c2 用于存储 getPropertyValue 方法代码</span>
+ StringBuilder c2 = <span class="hljs-keyword">new</span> StringBuilder(<span class="hljs-string">"public Object getPropertyValue(Object o, String n){ "</span>);
+ <span class="hljs-comment">// c3 用于存储 invokeMethod 方法代码</span>
+ StringBuilder c3 = <span class="hljs-keyword">new</span> StringBuilder(<span class="hljs-string">"public Object invokeMethod(Object o, String n, Class[] p, Object[] v) throws "</span> + InvocationTargetException.class.getName() + <span class="hljs-string">"{ "</span>);
+
+ <span class="hljs-comment">// 生成类型转换代码及异常捕捉代码,比如:</span>
+ <span class="hljs-comment">// DemoService w; try { w = ((DemoServcie) $1); }}catch(Throwable e){ throw new IllegalArgumentException(e); }</span>
+ c1.append(name).append(<span class="hljs-string">" w; try{ w = (("</span>).append(name).append(<span class="hljs-string">")$1); }catch(Throwable e){ throw new IllegalArgumentException(e); }"</span>);
+ c2.append(name).append(<span class="hljs-string">" w; try{ w = (("</span>).append(name).append(<span class="hljs-string">")$1); }catch(Throwable e){ throw new IllegalArgumentException(e); }"</span>);
+ c3.append(name).append(<span class="hljs-string">" w; try{ w = (("</span>).append(name).append(<span class="hljs-string">")$1); }catch(Throwable e){ throw new IllegalArgumentException(e); }"</span>);
+
+ <span class="hljs-comment">// pts 用于存储成员变量名和类型</span>
+ Map<String, Class<?>> pts = <span class="hljs-keyword">new</span> HashMap<String, Class<?>>();
+ <span class="hljs-comment">// ms 用于存储方法描述信息(可理解为方法签名)及 Method 实例</span>
+ Map<String, Method> ms = <span class="hljs-keyword">new</span> LinkedHashMap<String, Method>();
+ <span class="hljs-comment">// mns 为方法名列表</span>
+ List<String> mns = <span class="hljs-keyword">new</span> ArrayList<String>();
+ <span class="hljs-comment">// dmns 用于存储“定义在当前类中的方法”的名称</span>
+ List<String> dmns = <span class="hljs-keyword">new</span> ArrayList<String>();
+
+ <span class="hljs-comment">// --------------------------------✨ 分割线1 ✨-------------------------------------</span>
+
+ <span class="hljs-comment">// 获取 public 访问级别的字段,并为所有字段生成条件判断语句</span>
+ <span class="hljs-keyword">for</span> (Field f : c.getFields()) {
+ String fn = f.getName();
+ Class<?> ft = f.getType();
+ <span class="hljs-keyword">if</span> (Modifier.isStatic(f.getModifiers()) || Modifier.isTransient(f.getModifiers()))
+ <span class="hljs-comment">// 忽略关键字 static 或 transient 修饰的变量</span>
+ <span class="hljs-keyword">continue</span>;
+
+ <span class="hljs-comment">// 生成条件判断及赋值语句,比如:</span>
+ <span class="hljs-comment">// if( $2.equals("name") ) { w.name = (java.lang.String) $3; return;}</span>
+ <span class="hljs-comment">// if( $2.equals("age") ) { w.age = ((Number) $3).intValue(); return;}</span>
+ c1.append(<span class="hljs-string">" if( $2.equals(\""</span>).append(fn).append(<span class="hljs-string">"\") ){ w."</span>).append(fn).append(<span class="hljs-string">"="</span>).append(arg(ft, <span class="hljs-string">"$3"</span>)).append(<span class="hljs-string">"; return; }"</span>);
+
+ <span class="hljs-comment">// 生成条件判断及返回语句,比如:</span>
+ <span class="hljs-comment">// if( $2.equals("name") ) { return ($w)w.name; }</span>
+ c2.append(<span class="hljs-string">" if( $2.equals(\""</span>).append(fn).append(<span class="hljs-string">"\") ){ return ($w)w."</span>).append(fn).append(<span class="hljs-string">"; }"</span>);
+
+ <span class="hljs-comment">// 存储 <字段名, 字段类型> 键值对到 pts 中</span>
+ pts.put(fn, ft);
+ }
+
+ <span class="hljs-comment">// --------------------------------✨ 分割线2 ✨-------------------------------------</span>
+
+ Method[] methods = c.getMethods();
+ <span class="hljs-comment">// 检测 c 中是否包含在当前类中声明的方法</span>
+ <span class="hljs-keyword">boolean</span> hasMethod = hasMethods(methods);
+ <span class="hljs-keyword">if</span> (hasMethod) {
+ c3.append(<span class="hljs-string">" try{"</span>);
+ }
+ <span class="hljs-keyword">for</span> (Method m : methods) {
+ <span class="hljs-keyword">if</span> (m.getDeclaringClass() == Object.class)
+ <span class="hljs-comment">// 忽略 Object 中定义的方法</span>
+ <span class="hljs-keyword">continue</span>;
+
+ String mn = m.getName();
+ <span class="hljs-comment">// 生成方法名判断语句,比如:</span>
+ <span class="hljs-comment">// if ( "sayHello".equals( $2 )</span>
+ c3.append(<span class="hljs-string">" if( \""</span>).append(mn).append(<span class="hljs-string">"\".equals( $2 ) "</span>);
+ <span class="hljs-keyword">int</span> len = m.getParameterTypes().length;
+ <span class="hljs-comment">// 生成“运行时传入的参数数量与方法参数列表长度”判断语句,比如:</span>
+ <span class="hljs-comment">// && $3.length == 2</span>
+ c3.append(<span class="hljs-string">" && "</span>).append(<span class="hljs-string">" $3.length == "</span>).append(len);
+
+ <span class="hljs-keyword">boolean</span> override = <span class="hljs-keyword">false</span>;
+ <span class="hljs-keyword">for</span> (Method m2 : methods) {
+ <span class="hljs-comment">// 检测方法是否存在重载情况,条件为:方法对象不同 && 方法名相同</span>
+ <span class="hljs-keyword">if</span> (m != m2 && m.getName().equals(m2.getName())) {
+ override = <span class="hljs-keyword">true</span>;
+ <span class="hljs-keyword">break</span>;
+ }
+ }
+ <span class="hljs-comment">// 对重载方法进行处理,考虑下面的方法:</span>
+ <span class="hljs-comment">// 1. void sayHello(Integer, String)</span>
+ <span class="hljs-comment">// 2. void sayHello(Integer, Integer)</span>
+ <span class="hljs-comment">// 方法名相同,参数列表长度也相同,因此不能仅通过这两项判断两个方法是否相等。</span>
+ <span class="hljs-comment">// 需要进一步判断方法的参数类型</span>
+ <span class="hljs-keyword">if</span> (override) {
+ <span class="hljs-keyword">if</span> (len > <span class="hljs-number">0</span>) {
+ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> l = <span class="hljs-number">0</span>; l < len; l++) {
+ <span class="hljs-comment">// 生成参数类型进行检测代码,比如:</span>
+ <span class="hljs-comment">// && $3[0].getName().equals("java.lang.Integer") </span>
+ <span class="hljs-comment">// && $3[1].getName().equals("java.lang.String")</span>
+ c3.append(<span class="hljs-string">" && "</span>).append(<span class="hljs-string">" $3["</span>).append(l).append(<span class="hljs-string">"].getName().equals(\""</span>)
+ .append(m.getParameterTypes()[l].getName()).append(<span class="hljs-string">"\")"</span>);
+ }
+ }
+ }
+
+ <span class="hljs-comment">// 添加 ) {,完成方法判断语句,此时生成的代码可能如下(已格式化):</span>
+ <span class="hljs-comment">// if ("sayHello".equals($2) </span>
+ <span class="hljs-comment">// && $3.length == 2</span>
+ <span class="hljs-comment">// && $3[0].getName().equals("java.lang.Integer") </span>
+ <span class="hljs-comment">// && $3[1].getName().equals("java.lang.String")) {</span>
+ c3.append(<span class="hljs-string">" ) { "</span>);
+
+ <span class="hljs-comment">// 根据返回值类型生成目标方法调用语句</span>
+ <span class="hljs-keyword">if</span> (m.getReturnType() == Void.TYPE)
+ <span class="hljs-comment">// w.sayHello((java.lang.Integer)$4[0], (java.lang.String)$4[1]); return null;</span>
+ c3.append(<span class="hljs-string">" w."</span>).append(mn).append(<span class="hljs-string">'('</span>).append(args(m.getParameterTypes(), <span class="hljs-string">"$4"</span>)).append(<span class="hljs-string">");"</span>).append(<span class="hljs-string">" return null;"</span>);
+ <span class="hljs-keyword">else</span>
+ <span class="hljs-comment">// return w.sayHello((java.lang.Integer)$4[0], (java.lang.String)$4[1]);</span>
+ c3.append(<span class="hljs-string">" return ($w)w."</span>).append(mn).append(<span class="hljs-string">'('</span>).append(args(m.getParameterTypes(), <span class="hljs-string">"$4"</span>)).append(<span class="hljs-string">");"</span>);
+
+ <span class="hljs-comment">// 添加 }, 生成的代码形如(已格式化):</span>
+ <span class="hljs-comment">// if ("sayHello".equals($2) </span>
+ <span class="hljs-comment">// && $3.length == 2</span>
+ <span class="hljs-comment">// && $3[0].getName().equals("java.lang.Integer") </span>
+ <span class="hljs-comment">// && $3[1].getName().equals("java.lang.String")) {</span>
+ <span class="hljs-comment">//</span>
+ <span class="hljs-comment">// w.sayHello((java.lang.Integer)$4[0], (java.lang.String)$4[1]); </span>
+ <span class="hljs-comment">// return null;</span>
+ <span class="hljs-comment">// }</span>
+ c3.append(<span class="hljs-string">" }"</span>);
+
+ <span class="hljs-comment">// 添加方法名到 mns 集合中</span>
+ mns.add(mn);
+ <span class="hljs-comment">// 检测当前方法是否在 c 中被声明的</span>
+ <span class="hljs-keyword">if</span> (m.getDeclaringClass() == c)
+ <span class="hljs-comment">// 若是,则将当前方法名添加到 dmns 中</span>
+ dmns.add(mn);
+ ms.put(ReflectUtils.getDesc(m), m);
+ }
+ <span class="hljs-keyword">if</span> (hasMethod) {
+ <span class="hljs-comment">// 添加异常捕捉语句</span>
+ c3.append(<span class="hljs-string">" } catch(Throwable e) { "</span>);
+ c3.append(<span class="hljs-string">" throw new java.lang.reflect.InvocationTargetException(e); "</span>);
+ c3.append(<span class="hljs-string">" }"</span>);
+ }
+
+ <span class="hljs-comment">// 添加 NoSuchMethodException 异常抛出代码</span>
+ c3.append(<span class="hljs-string">" throw new "</span> + NoSuchMethodException.class.getName() + <span class="hljs-string">"(\"Not found method \\\"\"+$2+\"\\\" in class "</span> + c.getName() + <span class="hljs-string">".\"); }"</span>);
+
+ <span class="hljs-comment">// --------------------------------✨ 分割线3 ✨-------------------------------------</span>
+
+ Matcher matcher;
+ <span class="hljs-comment">// 处理 get/set 方法</span>
+ <span class="hljs-keyword">for</span> (Map.Entry<String, Method> entry : ms.entrySet()) {
+ String md = entry.getKey();
+ Method method = (Method) entry.getValue();
+ <span class="hljs-comment">// 匹配以 get 开头的方法</span>
+ <span class="hljs-keyword">if</span> ((matcher = ReflectUtils.GETTER_METHOD_DESC_PATTERN.matcher(md)).matches()) {
+ <span class="hljs-comment">// 获取属性名</span>
+ String pn = propertyName(matcher.group(<span class="hljs-number">1</span>));
+ <span class="hljs-comment">// 生成属性判断以及返回语句,示例如下:</span>
+ <span class="hljs-comment">// if( $2.equals("name") ) { return ($w).w.getName(); }</span>
+ c2.append(<span class="hljs-string">" if( $2.equals(\""</span>).append(pn).append(<span class="hljs-string">"\") ){ return ($w)w."</span>).append(method.getName()).append(<span class="hljs-string">"(); }"</span>);
+ pts.put(pn, method.getReturnType());
+
+ <span class="hljs-comment">// 匹配以 is/has/can 开头的方法</span>
+ } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ((matcher = ReflectUtils.IS_HAS_CAN_METHOD_DESC_PATTERN.matcher(md)).matches()) {
+ String pn = propertyName(matcher.group(<span class="hljs-number">1</span>));
+ <span class="hljs-comment">// 生成属性判断以及返回语句,示例如下:</span>
+ <span class="hljs-comment">// if( $2.equals("dream") ) { return ($w).w.hasDream(); }</span>
+ c2.append(<span class="hljs-string">" if( $2.equals(\""</span>).append(pn).append(<span class="hljs-string">"\") ){ return ($w)w."</span>).append(method.getName()).append(<span class="hljs-string">"(); }"</span>);
+ pts.put(pn, method.getReturnType());
+
+ <span class="hljs-comment">// 匹配以 set 开头的方法</span>
+ } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ((matcher = ReflectUtils.SETTER_METHOD_DESC_PATTERN.matcher(md)).matches()) {
+ Class<?> pt = method.getParameterTypes()[<span class="hljs-number">0</span>];
+ String pn = propertyName(matcher.group(<span class="hljs-number">1</span>));
+ <span class="hljs-comment">// 生成属性判断以及 setter 调用语句,示例如下:</span>
+ <span class="hljs-comment">// if( $2.equals("name") ) { w.setName((java.lang.String)$3); return; }</span>
+ c1.append(<span class="hljs-string">" if( $2.equals(\""</span>).append(pn).append(<span class="hljs-string">"\") ){ w."</span>).append(method.getName()).append(<span class="hljs-string">"("</span>).append(arg(pt, <span class="hljs-string">"$3"</span>)).append(<span class="hljs-string">"); return; }"</span>);
+ pts.put(pn, pt);
+ }
+ }
+
+ <span class="hljs-comment">// 添加 NoSuchPropertyException 异常抛出代码</span>
+ c1.append(<span class="hljs-string">" throw new "</span> + NoSuchPropertyException.class.getName() + <span class="hljs-string">"(\"Not found property \\\"\"+$2+\"\\\" filed or setter method in class "</span> + c.getName() + <span class="hljs-string">".\"); }"</span>);
+ c2.append(<span class="hljs-string">" throw new "</span> + NoSuchPropertyException.class.getName() + <span class="hljs-string">"(\"Not found property \\\"\"+$2+\"\\\" filed or setter method in class "</span> + c.getName() + <span class="hljs-string">".\"); }"</span>);
+
+ <span class="hljs-comment">// --------------------------------✨ 分割线4 ✨-------------------------------------</span>
+
+ <span class="hljs-keyword">long</span> id = WRAPPER_CLASS_COUNTER.getAndIncrement();
+ <span class="hljs-comment">// 创建类生成器</span>
+ ClassGenerator cc = ClassGenerator.newInstance(cl);
+ <span class="hljs-comment">// 设置类名及超类</span>
+ cc.setClassName((Modifier.isPublic(c.getModifiers()) ? Wrapper.class.getName() : c.getName() + <span class="hljs-string">"$sw"</span>) + id);
+ cc.setSuperClass(Wrapper.class);
+
+ <span class="hljs-comment">// 添加默认构造方法</span>
+ cc.addDefaultConstructor();
+
+ <span class="hljs-comment">// 添加字段</span>
+ cc.addField(<span class="hljs-string">"public static String[] pns;"</span>);
+ cc.addField(<span class="hljs-string">"public static "</span> + Map.class.getName() + <span class="hljs-string">" pts;"</span>);
+ cc.addField(<span class="hljs-string">"public static String[] mns;"</span>);
+ cc.addField(<span class="hljs-string">"public static String[] dmns;"</span>);
+ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>, len = ms.size(); i < len; i++)
+ cc.addField(<span class="hljs-string">"public static Class[] mts"</span> + i + <span class="hljs-string">";"</span>);
+
+ <span class="hljs-comment">// 添加方法代码</span>
+ cc.addMethod(<span class="hljs-string">"public String[] getPropertyNames(){ return pns; }"</span>);
+ cc.addMethod(<span class="hljs-string">"public boolean hasProperty(String n){ return pts.containsKey($1); }"</span>);
+ cc.addMethod(<span class="hljs-string">"public Class getPropertyType(String n){ return (Class)pts.get($1); }"</span>);
+ cc.addMethod(<span class="hljs-string">"public String[] getMethodNames(){ return mns; }"</span>);
+ cc.addMethod(<span class="hljs-string">"public String[] getDeclaredMethodNames(){ return dmns; }"</span>);
+ cc.addMethod(c1.toString());
+ cc.addMethod(c2.toString());
+ cc.addMethod(c3.toString());
+
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-comment">// 生成类</span>
+ Class<?> wc = cc.toClass();
+
+ <span class="hljs-comment">// 设置字段值</span>
+ wc.getField(<span class="hljs-string">"pts"</span>).set(<span class="hljs-keyword">null</span>, pts);
+ wc.getField(<span class="hljs-string">"pns"</span>).set(<span class="hljs-keyword">null</span>, pts.keySet().toArray(<span class="hljs-keyword">new</span> String[<span class="hljs-number">0</span>]));
+ wc.getField(<span class="hljs-string">"mns"</span>).set(<span class="hljs-keyword">null</span>, mns.toArray(<span class="hljs-keyword">new</span> String[<span class="hljs-number">0</span>]));
+ wc.getField(<span class="hljs-string">"dmns"</span>).set(<span class="hljs-keyword">null</span>, dmns.toArray(<span class="hljs-keyword">new</span> String[<span class="hljs-number">0</span>]));
+ <span class="hljs-keyword">int</span> ix = <span class="hljs-number">0</span>;
+ <span class="hljs-keyword">for</span> (Method m : ms.values())
+ wc.getField(<span class="hljs-string">"mts"</span> + ix++).set(<span class="hljs-keyword">null</span>, m.getParameterTypes());
+
+ <span class="hljs-comment">// 创建 Wrapper 实例</span>
+ <span class="hljs-keyword">return</span> (Wrapper) wc.newInstance();
+ } <span class="hljs-keyword">catch</span> (RuntimeException e) {
+ <span class="hljs-keyword">throw</span> e;
+ } <span class="hljs-keyword">catch</span> (Throwable e) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RuntimeException(e.getMessage(), e);
+ } <span class="hljs-keyword">finally</span> {
+ cc.release();
+ ms.clear();
+ mns.clear();
+ dmns.clear();
+ }
+}
+</code></pre>
+<p>上面代码很长,大家耐心看一下。我们在上面代码中做了大量的注释,并按功能对代码进行了分块,以帮助大家理解代码逻辑。下面对这段代码进行讲解。首先我们把目光移到分割线1之上的代码,这段代码主要用于进行一些初始化操作。比如创建 c1、c2、c3 以及 pts、ms、mns 等变量,以及向 c1、c2、c3 中添加方法定义和类型转换代码。接下来是分割线1到分割线2之间的代码,这段代码用于为 public 级别的字段生成条件判断取值与赋值代码。这段代码不是很难看懂,就不多说了。继续向下看,分割线2和分隔线3之间的代码用于为定义在当前类中的方法生成判断语句,和方法调用语句。因为需要对方法重载进行校验,因此到这这段代码看起来有点复杂。不过耐心开一下,也不是很难理解。接下来是分割线3和分隔线4之间的代码,这段代码用于处理 getter
、setter 以及以 is/has/can 开头的方法。处理方式是通过正则表达式获取方法类型(get/set/is/...),以及属性名。之后为属性名生成判断语句,然后为方法生成调用语句。最后我们再来看一下分隔线4以下的代码,这段代码通过 Clas [...]
+<p>阅读 Wrapper 类代码需要对 javassist 框架有所了解。关于 javassist,大家如果不熟悉,请自行查阅资料,本节不打算介绍 javassist 相关内容。</p>
+<p>好了,关于 Wrapper 类生成过程就分析到这。如果大家看的不是很明白,可以单独为 Wrapper 创建单元测试,然后单步调试。并将生成的代码拷贝出来,格式化后再进行观察和理解。</p>
+<h3>2.2.2 导出服务到本地</h3>
+<p>本节我们来看一下服务导出相关的代码,按照代码执行顺序,本节先来分析导出服务到本地的过程。相关代码如下:</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">exportLocal</span><span class="hljs-params">(URL url)</span> </span>{
+ <span class="hljs-comment">// 如果 URL 的协议头等于 injvm,说明已经导出到本地了,无需再次导出</span>
+ <span class="hljs-keyword">if</span> (!Constants.LOCAL_PROTOCOL.equalsIgnoreCase(url.getProtocol())) {
+ URL local = URL.valueOf(url.toFullString())
+ .setProtocol(Constants.LOCAL_PROTOCOL) <span class="hljs-comment">// 设置协议头为 injvm</span>
+ .setHost(LOCALHOST)
+ .setPort(<span class="hljs-number">0</span>);
+ ServiceClassHolder.getInstance().pushServiceClass(getServiceClass(ref));
+ <span class="hljs-comment">// 创建 Invoker,并导出服务,这里的 protocol 会在运行时调用 InjvmProtocol 的 export 方法</span>
+ Exporter<?> exporter = protocol.export(
+ proxyFactory.getInvoker(ref, (Class) interfaceClass, local));
+ exporters.add(exporter);
+ }
+}
+</code></pre>
+<p>exportLocal 方法比较简单,首先根据 URL 协议头决定是否导出服务。若需导出,则创建一个新的 URL 并将协议头、主机名以及端口设置成新的值。然后创建 Invoker,并调用 InjvmProtocol 的 export 方法导出服务。下面我们来看一下 InjvmProtocol 的 export 方法都做了哪些事情。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <T> <span class="hljs-function">Exporter<T> <span class="hljs-title">export</span><span class="hljs-params">(Invoker<T> invoker)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
+ <span class="hljs-comment">// 创建 InjvmExporter</span>
+ <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> InjvmExporter<T>(invoker, invoker.getUrl().getServiceKey(), exporterMap);
+}
+</code></pre>
+<p>如上,InjvmProtocol 的 export 方法仅创建了一个 InjvmExporter,无其他逻辑。到此导出服务到本地就分析完了,接下来,我们继续分析导出服务到远程的过程。</p>
+<h3>2.2.3 导出服务到远程</h3>
+<p>与导出服务到本地相比,导出服务到远程的过程要复杂不少,其包含了服务导出与服务注册两个过程。这两个过程涉及到了大量的调用,比较复杂。按照代码执行顺序,本节先来分析服务导出逻辑,服务注册逻辑将在下一节进行分析。下面开始分析,我们把目光移动到 RegistryProtocol 的 export 方法上。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <T> <span class="hljs-function">Exporter<T> <span class="hljs-title">export</span><span class="hljs-params">(<span class="hljs-keyword">final</span> Invoker<T> originInvoker)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
+ <span class="hljs-comment">// 导出服务</span>
+ <span class="hljs-keyword">final</span> ExporterChangeableWrapper<T> exporter = doLocalExport(originInvoker);
+
+ <span class="hljs-comment">// 获取注册中心 URL,以 zookeeper 注册中心为例,得到的示例 URL 如下:</span>
+ <span class="hljs-comment">// zookeeper://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-provider&dubbo=2.0.2&export=dubbo%3A%2F%2F172.17.48.52%3A20880%2Fcom.alibaba.dubbo.demo.DemoService%3Fanyhost%3Dtrue%26application%3Ddemo-provider</span>
+ URL registryUrl = getRegistryUrl(originInvoker);
+
+ <span class="hljs-comment">// 根据 URL 加载 Registry 实现类,比如 ZookeeperRegistry</span>
+ <span class="hljs-keyword">final</span> Registry registry = getRegistry(originInvoker);
+
+ <span class="hljs-comment">// 获取已注册的服务提供者 URL,比如:</span>
+ <span class="hljs-comment">// dubbo://172.17.48.52:20880/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&dubbo=2.0.2&generic=false&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello</span>
+ <span class="hljs-keyword">final</span> URL registeredProviderUrl = getRegisteredProviderUrl(originInvoker);
+
+ <span class="hljs-comment">// 获取 register 参数</span>
+ <span class="hljs-keyword">boolean</span> register = registeredProviderUrl.getParameter(<span class="hljs-string">"register"</span>, <span class="hljs-keyword">true</span>);
+
+ <span class="hljs-comment">// 向服务提供者与消费者注册表中注册服务提供者</span>
+ ProviderConsumerRegTable.registerProvider(originInvoker, registryUrl, registeredProviderUrl);
+
+ <span class="hljs-comment">// 根据 register 的值决定是否注册服务</span>
+ <span class="hljs-keyword">if</span> (register) {
+ <span class="hljs-comment">// 向注册中心注册服务</span>
+ register(registryUrl, registeredProviderUrl);
+ ProviderConsumerRegTable.getProviderWrapper(originInvoker).setReg(<span class="hljs-keyword">true</span>);
+ }
+
+ <span class="hljs-comment">// 获取订阅 URL,比如:</span>
+ <span class="hljs-comment">// provider://172.17.48.52:20880/com.alibaba.dubbo.demo.DemoService?category=configurators&check=false&anyhost=true&application=demo-provider&dubbo=2.0.2&generic=false&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello</span>
+ <span class="hljs-keyword">final</span> URL overrideSubscribeUrl = getSubscribedOverrideUrl(registeredProviderUrl);
+ <span class="hljs-comment">// 创建监听器</span>
+ <span class="hljs-keyword">final</span> OverrideListener overrideSubscribeListener = <span class="hljs-keyword">new</span> OverrideListener(overrideSubscribeUrl, originInvoker);
+ overrideListeners.put(overrideSubscribeUrl, overrideSubscribeListener);
+ <span class="hljs-comment">// 向注册中心进行订阅 override 数据</span>
+ registry.subscribe(overrideSubscribeUrl, overrideSubscribeListener);
+ <span class="hljs-comment">// 创建并返回 DestroyableExporter</span>
+ <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> DestroyableExporter<T>(exporter, originInvoker, overrideSubscribeUrl, registeredProviderUrl);
+}
+</code></pre>
+<p>上面代码看起来比较复杂,主要做如下一些操作:</p>
+<ol>
+<li>调用 doLocalExport 导出服务</li>
+<li>向注册中心注册服务</li>
+<li>向注册中心进行订阅 override 数据</li>
+<li>创建并返回 DestroyableExporter</li>
+</ol>
+<p>在以上操作中,除了创建并返回 DestroyableExporter 没什么难度外,其他几步操作都不是很简单。这其中,导出服务和注册服务是本章要重点分析的逻辑。 订阅 override 数据并非本文重点内容,后面会简单介绍一下。下面先来分析 doLocalExport 方法的逻辑,如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">private</span> <T> <span class="hljs-function">ExporterChangeableWrapper<T> <span class="hljs-title">doLocalExport</span><span class="hljs-params">(<span class="hljs-keyword">final</span> Invoker<T> originInvoker)</span> </span>{
+ String key = getCacheKey(originInvoker);
+ <span class="hljs-comment">// 访问缓存</span>
+ ExporterChangeableWrapper<T> exporter = (ExporterChangeableWrapper<T>) bounds.get(key);
+ <span class="hljs-keyword">if</span> (exporter == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">synchronized</span> (bounds) {
+ exporter = (ExporterChangeableWrapper<T>) bounds.get(key);
+ <span class="hljs-keyword">if</span> (exporter == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 创建 Invoker 为委托类对象</span>
+ <span class="hljs-keyword">final</span> Invoker<?> invokerDelegete = <span class="hljs-keyword">new</span> InvokerDelegete<T>(originInvoker, getProviderUrl(originInvoker));
+ <span class="hljs-comment">// 调用 protocol 的 export 方法导出服务</span>
+ exporter = <span class="hljs-keyword">new</span> ExporterChangeableWrapper<T>((Exporter<T>) protocol.export(invokerDelegete), originInvoker);
+
+ <span class="hljs-comment">// 写缓存</span>
+ bounds.put(key, exporter);
+ }
+ }
+ }
+ <span class="hljs-keyword">return</span> exporter;
+}
+</code></pre>
+<p>上面的代码是典型的双重检查锁,大家在阅读 Dubbo 的源码中,会多次见到。接下来,我们把重点放在 Protocol 的 export 方法上。假设运行时协议为 dubbo,此处的 protocol 变量会在运行时加载 DubboProtocol,并调用 DubboProtocol 的 export 方法。所以,接下来我们目光转移到 DubboProtocol 的 export 方法上,相关分析如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <T> <span class="hljs-function">Exporter<T> <span class="hljs-title">export</span><span class="hljs-params">(Invoker<T> invoker)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
+ URL url = invoker.getUrl();
+
+ <span class="hljs-comment">// 获取服务标识,理解成服务坐标也行。由服务组名,服务名,服务版本号以及端口组成。比如:</span>
+ <span class="hljs-comment">// demoGroup/com.alibaba.dubbo.demo.DemoService:1.0.1:20880</span>
+ String key = serviceKey(url);
+ <span class="hljs-comment">// 创建 DubboExporter</span>
+ DubboExporter<T> exporter = <span class="hljs-keyword">new</span> DubboExporter<T>(invoker, key, exporterMap);
+ <span class="hljs-comment">// 将 <key, exporter> 键值对放入缓存中</span>
+ exporterMap.put(key, exporter);
+
+ <span class="hljs-comment">// 本地存根相关代码</span>
+ Boolean isStubSupportEvent = url.getParameter(Constants.STUB_EVENT_KEY, Constants.DEFAULT_STUB_EVENT);
+ Boolean isCallbackservice = url.getParameter(Constants.IS_CALLBACK_SERVICE, <span class="hljs-keyword">false</span>);
+ <span class="hljs-keyword">if</span> (isStubSupportEvent && !isCallbackservice) {
+ String stubServiceMethods = url.getParameter(Constants.STUB_EVENT_METHODS_KEY);
+ <span class="hljs-keyword">if</span> (stubServiceMethods == <span class="hljs-keyword">null</span> || stubServiceMethods.length() == <span class="hljs-number">0</span>) {
+ <span class="hljs-comment">// 省略日志打印代码</span>
+ } <span class="hljs-keyword">else</span> {
+ stubServiceMethodsMap.put(url.getServiceKey(), stubServiceMethods);
+ }
+ }
+
+ <span class="hljs-comment">// 启动服务器</span>
+ openServer(url);
+ <span class="hljs-comment">// 优化序列化</span>
+ optimizeSerialization(url);
+ <span class="hljs-keyword">return</span> exporter;
+}
+</code></pre>
+<p>如上,我们重点关注 DubboExporter 的创建以及 openServer 方法,其他逻辑看不懂也没关系,不影响理解服务导出过程。另外,DubboExporter 的代码比较简单,就不分析了。下面分析 openServer 方法。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">openServer</span><span class="hljs-params">(URL url)</span> </span>{
+ <span class="hljs-comment">// 获取 host:port,并将其作为服务器实例的 key,用于标识当前的服务器实例</span>
+ String key = url.getAddress();
+ <span class="hljs-keyword">boolean</span> isServer = url.getParameter(Constants.IS_SERVER_KEY, <span class="hljs-keyword">true</span>);
+ <span class="hljs-keyword">if</span> (isServer) {
+ <span class="hljs-comment">// 访问缓存</span>
+ ExchangeServer server = serverMap.get(key);
+ <span class="hljs-keyword">if</span> (server == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 创建服务器实例</span>
+ serverMap.put(key, createServer(url));
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-comment">// 服务器已创建,则根据 url 中的配置重置服务器</span>
+ server.reset(url);
+ }
+ }
+}
+</code></pre>
+<p>如上,在同一台机器上(单网卡),同一个端口上仅允许启动一个服务器实例。若某个端口上已有服务器实例,此时则调用 reset 方法重置服务器的一些配置。考虑到篇幅问题,关于服务器实例重置的代码就不分析了。接下来分析服务器实例的创建过程。如下:</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">private</span> ExchangeServer <span class="hljs-title">createServer</span><span class="hljs-params">(URL url)</span> </span>{
+ url = url.addParameterIfAbsent(Constants.CHANNEL_READONLYEVENT_SENT_KEY,
+ <span class="hljs-comment">// 添加心跳检测配置到 url 中</span>
+ url = url.addParameterIfAbsent(Constants.HEARTBEAT_KEY, String.valueOf(Constants.DEFAULT_HEARTBEAT));
+ <span class="hljs-comment">// 获取 server 参数,默认为 netty</span>
+ String str = url.getParameter(Constants.SERVER_KEY, Constants.DEFAULT_REMOTING_SERVER);
+
+ <span class="hljs-comment">// 通过 SPI 检测是否存在 server 参数所代表的 Transporter 拓展,不存在则抛出异常</span>
+ <span class="hljs-keyword">if</span> (str != <span class="hljs-keyword">null</span> && str.length() > <span class="hljs-number">0</span> && !ExtensionLoader.getExtensionLoader(Transporter.class).hasExtension(str))
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RpcException(<span class="hljs-string">"Unsupported server type: "</span> + str + <span class="hljs-string">", url: "</span> + url);
+
+ <span class="hljs-comment">// 添加编码解码器参数</span>
+ url = url.addParameter(Constants.CODEC_KEY, DubboCodec.NAME);
+ ExchangeServer server;
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-comment">// 创建 ExchangeServer</span>
+ server = Exchangers.bind(url, requestHandler);
+ } <span class="hljs-keyword">catch</span> (RemotingException e) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RpcException(<span class="hljs-string">"Fail to start server..."</span>);
+ }
+
+ <span class="hljs-comment">// 获取 client 参数,可指定 netty,mina</span>
+ str = url.getParameter(Constants.CLIENT_KEY);
+ <span class="hljs-keyword">if</span> (str != <span class="hljs-keyword">null</span> && str.length() > <span class="hljs-number">0</span>) {
+ <span class="hljs-comment">// 获取所有的 Transporter 实现类名称集合,比如 supportedTypes = [netty, mina]</span>
+ Set<String> supportedTypes = ExtensionLoader.getExtensionLoader(Transporter.class).getSupportedExtensions();
+ <span class="hljs-comment">// 检测当前 Dubbo 所支持的 Transporter 实现类名称列表中,</span>
+ <span class="hljs-comment">// 是否包含 client 所表示的 Transporter,若不包含,则抛出异常</span>
+ <span class="hljs-keyword">if</span> (!supportedTypes.contains(str)) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RpcException(<span class="hljs-string">"Unsupported client type..."</span>);
+ }
+ }
+ <span class="hljs-keyword">return</span> server;
+}
+</code></pre>
+<p>如上,createServer 包含三个核心的逻辑。第一是检测是否存在 server 参数所代表的 Transporter 拓展,不存在则抛出异常。第二是创建服务器实例。第三是检测是否支持 client 参数所表示的 Transporter 拓展,不存在也是抛出异常。两次检测操作所对应的代码比较直白了,无需多说。但创建服务器的操作目前还不是很清晰,我们继续往下看。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> ExchangeServer <span class="hljs-title">bind</span><span class="hljs-params">(URL url, ExchangeHandler handler)</span> <span class="hljs-keyword">throws</span> RemotingException </span>{
+ <span class="hljs-keyword">if</span> (url == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"url == null"</span>);
+ }
+ <span class="hljs-keyword">if</span> (handler == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"handler == null"</span>);
+ }
+ url = url.addParameterIfAbsent(Constants.CODEC_KEY, <span class="hljs-string">"exchange"</span>);
+ <span class="hljs-comment">// 获取 Exchanger,默认为 HeaderExchanger。</span>
+ <span class="hljs-comment">// 紧接着调用 HeaderExchanger 的 bind 方法创建 ExchangeServer 实例</span>
+ <span class="hljs-keyword">return</span> getExchanger(url).bind(url, handler);
+}
+</code></pre>
+<p>上面代码比较简单,就不多说了。下面看一下 HeaderExchanger 的 bind 方法。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">public</span> ExchangeServer <span class="hljs-title">bind</span><span class="hljs-params">(URL url, ExchangeHandler handler)</span> <span class="hljs-keyword">throws</span> RemotingException </span>{
+ <span class="hljs-comment">// 创建 HeaderExchangeServer 实例,该方法包含了多个逻辑,分别如下:</span>
+ <span class="hljs-comment">// 1. new HeaderExchangeHandler(handler)</span>
+ <span class="hljs-comment">// 2. new DecodeHandler(new HeaderExchangeHandler(handler))</span>
+ <span class="hljs-comment">// 3. Transporters.bind(url, new DecodeHandler(new HeaderExchangeHandler(handler)))</span>
+ <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> HeaderExchangeServer(Transporters.bind(url, <span class="hljs-keyword">new</span> DecodeHandler(<span class="hljs-keyword">new</span> HeaderExchangeHandler(handler))));
+}
+</code></pre>
+<p>HeaderExchanger 的 bind 方法包含的逻辑比较多,但目前我们仅需关心 Transporters 的 bind 方法逻辑即可。该方法的代码如下:</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Server <span class="hljs-title">bind</span><span class="hljs-params">(URL url, ChannelHandler... handlers)</span> <span class="hljs-keyword">throws</span> RemotingException </span>{
+ <span class="hljs-keyword">if</span> (url == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"url == null"</span>);
+ }
+ <span class="hljs-keyword">if</span> (handlers == <span class="hljs-keyword">null</span> || handlers.length == <span class="hljs-number">0</span>) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"handlers == null"</span>);
+ }
+ ChannelHandler handler;
+ <span class="hljs-keyword">if</span> (handlers.length == <span class="hljs-number">1</span>) {
+ handler = handlers[<span class="hljs-number">0</span>];
+ } <span class="hljs-keyword">else</span> {
+ <span class="hljs-comment">// 如果 handlers 元素数量大于1,则创建 ChannelHandler 分发器</span>
+ handler = <span class="hljs-keyword">new</span> ChannelHandlerDispatcher(handlers);
+ }
+ <span class="hljs-comment">// 获取自适应 Transporter 实例,并调用实例方法</span>
+ <span class="hljs-keyword">return</span> getTransporter().bind(url, handler);
+}
+</code></pre>
+<p>如上,getTransporter() 方法获取的 Transporter 是在运行时动态创建的,类名为 TransporterAdaptive,也就是自适应拓展类。TransporterAdaptive 会在运行时根据传入的 URL 参数决定加载什么类型的 Transporter,默认为 NettyTransporter。下面我们继续跟下去,这次分析的是 NettyTransporter 的 bind 方法。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">public</span> Server <span class="hljs-title">bind</span><span class="hljs-params">(URL url, ChannelHandler listener)</span> <span class="hljs-keyword">throws</span> RemotingException </span>{
+ <span class="hljs-comment">// 创建 NettyServer</span>
+ <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> NettyServer(url, listener);
+}
+</code></pre>
+<p>这里仅有一句创建 NettyServer 的代码,无需多说,我们继续向下看。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">NettyServer</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractServer</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Server</span> </span>{
+ <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">NettyServer</span><span class="hljs-params">(URL url, ChannelHandler handler)</span> <span class="hljs-keyword">throws</span> RemotingException </span>{
+ <span class="hljs-comment">// 调用父类构造方法</span>
+ <span class="hljs-keyword">super</span>(url, ChannelHandlers.wrap(handler, ExecutorUtil.setThreadName(url, SERVER_THREAD_POOL_NAME)));
+ }
+}
+
+
+<span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AbstractServer</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractEndpoint</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Server</span> </span>{
+ <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">AbstractServer</span><span class="hljs-params">(URL url, ChannelHandler handler)</span> <span class="hljs-keyword">throws</span> RemotingException </span>{
+ <span class="hljs-comment">// 调用父类构造方法,这里就不用跟进去了,没什么复杂逻辑</span>
+ <span class="hljs-keyword">super</span>(url, handler);
+ localAddress = getUrl().toInetSocketAddress();
+
+ <span class="hljs-comment">// 获取 ip 和端口</span>
+ String bindIp = getUrl().getParameter(Constants.BIND_IP_KEY, getUrl().getHost());
+ <span class="hljs-keyword">int</span> bindPort = getUrl().getParameter(Constants.BIND_PORT_KEY, getUrl().getPort());
+ <span class="hljs-keyword">if</span> (url.getParameter(Constants.ANYHOST_KEY, <span class="hljs-keyword">false</span>) || NetUtils.isInvalidLocalHost(bindIp)) {
+ <span class="hljs-comment">// 设置 ip 为 0.0.0.0</span>
+ bindIp = NetUtils.ANYHOST;
+ }
+ bindAddress = <span class="hljs-keyword">new</span> InetSocketAddress(bindIp, bindPort);
+ <span class="hljs-comment">// 获取最大可接受连接数</span>
+ <span class="hljs-keyword">this</span>.accepts = url.getParameter(Constants.ACCEPTS_KEY, Constants.DEFAULT_ACCEPTS);
+ <span class="hljs-keyword">this</span>.idleTimeout = url.getParameter(Constants.IDLE_TIMEOUT_KEY, Constants.DEFAULT_IDLE_TIMEOUT);
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-comment">// 调用模板方法 doOpen 启动服务器</span>
+ doOpen();
+ } <span class="hljs-keyword">catch</span> (Throwable t) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RemotingException(<span class="hljs-string">"Failed to bind "</span>);
+ }
+
+ DataStore dataStore = ExtensionLoader.getExtensionLoader(DataStore.class).getDefaultExtension();
+ executor = (ExecutorService) dataStore.get(Constants.EXECUTOR_SERVICE_COMPONENT_KEY, Integer.toString(url.getPort()));
+ }
+
+ <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doOpen</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Throwable</span>;
+
+ <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doClose</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Throwable</span>;
+}
+</code></pre>
+<p>上面代码多为赋值代码,不需要多讲。我们重点关注 doOpen 抽象方法,该方法需要子类实现。下面回到 NettyServer 中。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doOpen</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Throwable </span>{
+ NettyHelper.setNettyLoggerFactory();
+ <span class="hljs-comment">// 创建 boss 和 worker 线程池</span>
+ ExecutorService boss = Executors.newCachedThreadPool(<span class="hljs-keyword">new</span> NamedThreadFactory(<span class="hljs-string">"NettyServerBoss"</span>, <span class="hljs-keyword">true</span>));
+ ExecutorService worker = Executors.newCachedThreadPool(<span class="hljs-keyword">new</span> NamedThreadFactory(<span class="hljs-string">"NettyServerWorker"</span>, <span class="hljs-keyword">true</span>));
+ ChannelFactory channelFactory = <span class="hljs-keyword">new</span> NioServerSocketChannelFactory(boss, worker, getUrl().getPositiveParameter(Constants.IO_THREADS_KEY, Constants.DEFAULT_IO_THREADS));
+
+ <span class="hljs-comment">// 创建 ServerBootstrap</span>
+ bootstrap = <span class="hljs-keyword">new</span> ServerBootstrap(channelFactory);
+
+ <span class="hljs-keyword">final</span> NettyHandler nettyHandler = <span class="hljs-keyword">new</span> NettyHandler(getUrl(), <span class="hljs-keyword">this</span>);
+ channels = nettyHandler.getChannels();
+ bootstrap.setOption(<span class="hljs-string">"child.tcpNoDelay"</span>, <span class="hljs-keyword">true</span>);
+ <span class="hljs-comment">// 设置 PipelineFactory</span>
+ bootstrap.setPipelineFactory(<span class="hljs-keyword">new</span> ChannelPipelineFactory() {
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-function"><span class="hljs-keyword">public</span> ChannelPipeline <span class="hljs-title">getPipeline</span><span class="hljs-params">()</span> </span>{
+ NettyCodecAdapter adapter = <span class="hljs-keyword">new</span> NettyCodecAdapter(getCodec(), getUrl(), NettyServer.<span class="hljs-keyword">this</span>);
+ ChannelPipeline pipeline = Channels.pipeline();
+ pipeline.addLast(<span class="hljs-string">"decoder"</span>, adapter.getDecoder());
+ pipeline.addLast(<span class="hljs-string">"encoder"</span>, adapter.getEncoder());
+ pipeline.addLast(<span class="hljs-string">"handler"</span>, nettyHandler);
+ <span class="hljs-keyword">return</span> pipeline;
+ }
+ });
+ <span class="hljs-comment">// 绑定到指定的 ip 和端口上</span>
+ channel = bootstrap.bind(getBindAddress());
+}
+</code></pre>
+<p>以上就是 NettyServer 创建的过程,dubbo 默认使用的 NettyServer 是基于 netty 3.x 版本实现的,比较老了。因此 Dubbo 另外提供了 netty 4.x 版本的 NettyServer,大家可在使用 Dubbo 的过程中按需进行配置。</p>
+<p>到此,关于服务导出的过程就分析完了。整个过程比较复杂,大家在分析的过程中耐心一些。并且多写 Demo 进行进行调试,以便能够更好的理解代码逻辑。</p>
+<p>本节内容先到这里,接下来分析服务导出的另一块逻辑 — 服务注册。</p>
+<h3>2.2.4 服务注册</h3>
+<p>本节我们来分析服务注册过程,服务注册操作对于 Dubbo 来说不是必需的,通过服务直连的方式就可以绕过注册中心。但通常我们不会这么做,直连方式不利于服务治理,仅推荐在测试服务时使用。对于 Dubbo 来说,注册中心虽不是必需,但却是必要的。因此,关于注册中心以及服务注册相关逻辑,我们也需要搞懂。</p>
+<p>本节内容以 Zookeeper 注册中心作为分析目标,其他类型注册中心大家可自行分析。下面从服务注册的入口方法开始分析,我们把目光再次移到 RegistryProtocol 的 export 方法上。如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <T> <span class="hljs-function">Exporter<T> <span class="hljs-title">export</span><span class="hljs-params">(<span class="hljs-keyword">final</span> Invoker<T> originInvoker)</span> <span class="hljs-keyword">throws</span> RpcException </span>{
+
+ <span class="hljs-comment">// ${导出服务}</span>
+
+ <span class="hljs-comment">// 省略其他代码</span>
+
+ <span class="hljs-keyword">boolean</span> register = registeredProviderUrl.getParameter(<span class="hljs-string">"register"</span>, <span class="hljs-keyword">true</span>);
+ <span class="hljs-keyword">if</span> (register) {
+ <span class="hljs-comment">// 注册服务</span>
+ register(registryUrl, registeredProviderUrl);
+ ProviderConsumerRegTable.getProviderWrapper(originInvoker).setReg(<span class="hljs-keyword">true</span>);
+ }
+
+ <span class="hljs-keyword">final</span> URL overrideSubscribeUrl = getSubscribedOverrideUrl(registeredProviderUrl);
+ <span class="hljs-keyword">final</span> OverrideListener overrideSubscribeListener = <span class="hljs-keyword">new</span> OverrideListener(overrideSubscribeUrl, originInvoker);
+ overrideListeners.put(overrideSubscribeUrl, overrideSubscribeListener);
+ <span class="hljs-comment">// 订阅 override 数据</span>
+ registry.subscribe(overrideSubscribeUrl, overrideSubscribeListener);
+
+ <span class="hljs-comment">// 省略部分代码</span>
+}
+</code></pre>
+<p>RegistryProtocol 的 export 方法包含了服务导出,注册,以及数据订阅等逻辑。其中服务导出逻辑上一节已经分析过了,本节将分析服务注册逻辑,相关代码如下:</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">register</span><span class="hljs-params">(URL registryUrl, URL registedProviderUrl)</span> </span>{
+ <span class="hljs-comment">// 获取 Registry</span>
+ Registry registry = registryFactory.getRegistry(registryUrl);
+ <span class="hljs-comment">// 注册服务</span>
+ registry.register(registedProviderUrl);
+}
+</code></pre>
+<p>register 方法包含两步操作,第一步是获取注册中心实例,第二步是向注册中心注册服务。接下来分两节内容对这两步操作进行分析。</p>
+<h4>2.2.4.1 创建注册中心</h4>
+<p>本节内容以 Zookeeper 注册中心为例进行分析。下面先来看一下 getRegistry 方法的源码,这个方法由 AbstractRegistryFactory 实现。如下:</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">public</span> Registry <span class="hljs-title">getRegistry</span><span class="hljs-params">(URL url)</span> </span>{
+ url = url.setPath(RegistryService.class.getName())
+ .addParameter(Constants.INTERFACE_KEY, RegistryService.class.getName())
+ .removeParameters(Constants.EXPORT_KEY, Constants.REFER_KEY);
+ String key = url.toServiceString();
+ LOCK.lock();
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-comment">// 访问缓存</span>
+ Registry registry = REGISTRIES.get(key);
+ <span class="hljs-keyword">if</span> (registry != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">return</span> registry;
+ }
+
+ <span class="hljs-comment">// 缓存未命中,创建 Registry 实例</span>
+ registry = createRegistry(url);
+ <span class="hljs-keyword">if</span> (registry == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"Can not create registry..."</span>);
+ }
+
+ <span class="hljs-comment">// 写入缓存</span>
+ REGISTRIES.put(key, registry);
+ <span class="hljs-keyword">return</span> registry;
+ } <span class="hljs-keyword">finally</span> {
+ LOCK.unlock();
+ }
+}
+
+<span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">abstract</span> Registry <span class="hljs-title">createRegistry</span><span class="hljs-params">(URL url)</span></span>;
+</code></pre>
+<p>如上,getRegistry 方法先访问缓存,缓存未命中则调用 createRegistry 创建 Registry,然后写入缓存。这里的 createRegistry 是一个模板方法,由具体的子类实现。因此,下面我们到 ZookeeperRegistryFactory 中探究一番。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ZookeeperRegistryFactory</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractRegistryFactory</span> </span>{
+
+ <span class="hljs-comment">// zookeeperTransporter 由 SPI 在运行时注入,类型为 ZookeeperTransporter$Adaptive</span>
+ <span class="hljs-keyword">private</span> ZookeeperTransporter zookeeperTransporter;
+
+ <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setZookeeperTransporter</span><span class="hljs-params">(ZookeeperTransporter zookeeperTransporter)</span> </span>{
+ <span class="hljs-keyword">this</span>.zookeeperTransporter = zookeeperTransporter;
+ }
+
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-function"><span class="hljs-keyword">public</span> Registry <span class="hljs-title">createRegistry</span><span class="hljs-params">(URL url)</span> </span>{
+ <span class="hljs-comment">// 创建 ZookeeperRegistry</span>
+ <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> ZookeeperRegistry(url, zookeeperTransporter);
+ }
+}
+</code></pre>
+<p>ZookeeperRegistryFactory 的 createRegistry 方法仅包含一句代码,无需解释,继续跟下去。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">ZookeeperRegistry</span><span class="hljs-params">(URL url, ZookeeperTransporter zookeeperTransporter)</span> </span>{
+ <span class="hljs-keyword">super</span>(url);
+ <span class="hljs-keyword">if</span> (url.isAnyHost()) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"registry address == null"</span>);
+ }
+
+ <span class="hljs-comment">// 获取组名,默认为 dubbo</span>
+ String group = url.getParameter(Constants.GROUP_KEY, DEFAULT_ROOT);
+ <span class="hljs-keyword">if</span> (!group.startsWith(Constants.PATH_SEPARATOR)) {
+ <span class="hljs-comment">// group = "/" + group</span>
+ group = Constants.PATH_SEPARATOR + group;
+ }
+ <span class="hljs-keyword">this</span>.root = group;
+ <span class="hljs-comment">// 创建 Zookeeper 客户端,默认为 CuratorZookeeperTransporter</span>
+ zkClient = zookeeperTransporter.connect(url);
+ <span class="hljs-comment">// 添加状态监听器</span>
+ zkClient.addStateListener(<span class="hljs-keyword">new</span> StateListener() {
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">stateChanged</span><span class="hljs-params">(<span class="hljs-keyword">int</span> state)</span> </span>{
+ <span class="hljs-keyword">if</span> (state == RECONNECTED) {
+ <span class="hljs-keyword">try</span> {
+ recover();
+ } <span class="hljs-keyword">catch</span> (Exception e) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+ }
+ });
+}
+</code></pre>
+<p>在上面的代码代码中,我们重点关注 ZookeeperTransporter 的 connect 方法调用,这个方法用于创建 Zookeeper 客户端。创建好 Zookeeper 客户端,意味着注册中心的创建过程就结束了。接下来,再来分析一下 Zookeeper 客户端的创建过程。</p>
+<p>前面说过,这里的 zookeeperTransporter 类型为自适应拓展类,因此 connect 方法会在被调用时决定加载什么类型的 ZookeeperTransporter 拓展,默认为 CuratorZookeeperTransporter。下面我们到 CuratorZookeeperTransporter 中看一看。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">public</span> ZookeeperClient <span class="hljs-title">connect</span><span class="hljs-params">(URL url)</span> </span>{
+ <span class="hljs-comment">// 创建 CuratorZookeeperClient</span>
+ <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> CuratorZookeeperClient(url);
+}
+</code></pre>
+<p>继续向下看。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CuratorZookeeperClient</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractZookeeperClient</span><<span class="hljs-title">CuratorWatcher</span>> </span>{
+
+ <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> CuratorFramework client;
+
+ <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">CuratorZookeeperClient</span><span class="hljs-params">(URL url)</span> </span>{
+ <span class="hljs-keyword">super</span>(url);
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-comment">// 创建 CuratorFramework 构造器</span>
+ CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder()
+ .connectString(url.getBackupAddress())
+ .retryPolicy(<span class="hljs-keyword">new</span> RetryNTimes(<span class="hljs-number">1</span>, <span class="hljs-number">1000</span>))
+ .connectionTimeoutMs(<span class="hljs-number">5000</span>);
+ String authority = url.getAuthority();
+ <span class="hljs-keyword">if</span> (authority != <span class="hljs-keyword">null</span> && authority.length() > <span class="hljs-number">0</span>) {
+ builder = builder.authorization(<span class="hljs-string">"digest"</span>, authority.getBytes());
+ }
+ <span class="hljs-comment">// 构建 CuratorFramework 实例</span>
+ client = builder.build();
+ <span class="hljs-comment">// 添加监听器</span>
+ client.getConnectionStateListenable().addListener(<span class="hljs-keyword">new</span> ConnectionStateListener() {
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">stateChanged</span><span class="hljs-params">(CuratorFramework client, ConnectionState state)</span> </span>{
+ <span class="hljs-keyword">if</span> (state == ConnectionState.LOST) {
+ CuratorZookeeperClient.<span class="hljs-keyword">this</span>.stateChanged(StateListener.DISCONNECTED);
+ } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (state == ConnectionState.CONNECTED) {
+ CuratorZookeeperClient.<span class="hljs-keyword">this</span>.stateChanged(StateListener.CONNECTED);
+ } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (state == ConnectionState.RECONNECTED) {
+ CuratorZookeeperClient.<span class="hljs-keyword">this</span>.stateChanged(StateListener.RECONNECTED);
+ }
+ }
+ });
+
+ <span class="hljs-comment">// 启动客户端</span>
+ client.start();
+ } <span class="hljs-keyword">catch</span> (Exception e) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(e.getMessage(), e);
+ }
+ }
+}
+</code></pre>
+<p>CuratorZookeeperClient 构造方法主要用于创建和启动 CuratorFramework 实例。以上基本上都是 Curator 框架的代码,大家如果对 Curator 框架不是很了解,可以参考 Curator 官方文档。</p>
+<p>本节分析了 ZookeeperRegistry 实例的创建过程,整个过程并不是很复杂。大家在看完分析后,可以自行调试,以加深理解。现在注册中心实例创建好了,接下来要做的事情是向注册中心注册服务,我们继续往下看。</p>
+<h4>2.2.4.2 节点创建</h4>
+<p>以 Zookeeper 为例,所谓的服务注册,本质上是将服务配置数据写入到 Zookeeper 的某个路径的节点下。为了让大家有一个直观的了解,下面我们将 Dubbo 的 demo 跑起来,然后通过 Zookeeper 可视化客户端 <a href="https://github.com/apache/zookeeper/tree/b79af153d0f98a4f3f3516910ed47234d7b3d74e/src/contrib/zooinspector">ZooInspector</a> 查看节点数据。如下:</p>
+<p><img src="./sources/images/service-registry.png" alt=""></p>
+<p>从上图中可以看到 com.alibaba.dubbo.demo.DemoService 这个服务对应的配置信息(存储在 URL 中)最终被注册到了 /dubbo/com.alibaba.dubbo.demo.DemoService/providers/ 节点下。搞懂了服务注册的本质,那么接下来我们就可以去阅读服务注册的代码了。服务注册的接口为 register(URL),这个方法定义在 FailbackRegistry 抽象类中。代码如下:</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">register</span><span class="hljs-params">(URL url)</span> </span>{
+ <span class="hljs-keyword">super</span>.register(url);
+ failedRegistered.remove(url);
+ failedUnregistered.remove(url);
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-comment">// 模板方法,由子类实现</span>
+ doRegister(url);
+ } <span class="hljs-keyword">catch</span> (Exception e) {
+ Throwable t = e;
+
+ <span class="hljs-comment">// 获取 check 参数,若 check = true 将会直接抛出异常</span>
+ <span class="hljs-keyword">boolean</span> check = getUrl().getParameter(Constants.CHECK_KEY, <span class="hljs-keyword">true</span>)
+ && url.getParameter(Constants.CHECK_KEY, <span class="hljs-keyword">true</span>)
+ && !Constants.CONSUMER_PROTOCOL.equals(url.getProtocol());
+ <span class="hljs-keyword">boolean</span> skipFailback = t <span class="hljs-keyword">instanceof</span> SkipFailbackWrapperException;
+ <span class="hljs-keyword">if</span> (check || skipFailback) {
+ <span class="hljs-keyword">if</span> (skipFailback) {
+ t = t.getCause();
+ }
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"Failed to register"</span>);
+ } <span class="hljs-keyword">else</span> {
+ logger.error(<span class="hljs-string">"Failed to register"</span>);
+ }
+
+ <span class="hljs-comment">// 记录注册失败的链接</span>
+ failedRegistered.add(url);
+ }
+}
+
+<span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doRegister</span><span class="hljs-params">(URL url)</span></span>;
+</code></pre>
+<p>如上,我们重点关注 doRegister 方法调用即可,其他的代码先忽略。doRegister 方法是一个模板方法,因此我们到 FailbackRegistry 子类 ZookeeperRegistry 中进行分析。如下:</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doRegister</span><span class="hljs-params">(URL url)</span> </span>{
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-comment">// 通过 Zookeeper 客户端创建节点,节点路径由 toUrlPath 方法生成,路径格式如下:</span>
+ <span class="hljs-comment">// /${group}/${serviceInterface}/providers/${url}</span>
+ <span class="hljs-comment">// 比如</span>
+ <span class="hljs-comment">// /dubbo/org.apache.dubbo.DemoService/providers/dubbo%3A%2F%2F127.0.0.1......</span>
+ zkClient.create(toUrlPath(url), url.getParameter(Constants.DYNAMIC_KEY, <span class="hljs-keyword">true</span>));
+ } <span class="hljs-keyword">catch</span> (Throwable e) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RpcException(<span class="hljs-string">"Failed to register..."</span>);
+ }
+}
+</code></pre>
+<p>如上,ZookeeperRegistry 在 doRegister 中调用了 Zookeeper 客户端创建服务节点。节点路径由 toUrlPath 方法生成,该方法逻辑不难理解,就不分析了。接下来分析 create 方法,如下:</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">create</span><span class="hljs-params">(String path, <span class="hljs-keyword">boolean</span> ephemeral)</span> </span>{
+ <span class="hljs-keyword">if</span> (!ephemeral) {
+ <span class="hljs-comment">// 如果要创建的节点类型非临时节点,那么这里要检测节点是否存在</span>
+ <span class="hljs-keyword">if</span> (checkExists(path)) {
+ <span class="hljs-keyword">return</span>;
+ }
+ }
+ <span class="hljs-keyword">int</span> i = path.lastIndexOf(<span class="hljs-string">'/'</span>);
+ <span class="hljs-keyword">if</span> (i > <span class="hljs-number">0</span>) {
+ <span class="hljs-comment">// 递归创建上一级路径</span>
+ create(path.substring(<span class="hljs-number">0</span>, i), <span class="hljs-keyword">false</span>);
+ }
+
+ <span class="hljs-comment">// 根据 ephemeral 的值创建临时或持久节点</span>
+ <span class="hljs-keyword">if</span> (ephemeral) {
+ createEphemeral(path);
+ } <span class="hljs-keyword">else</span> {
+ createPersistent(path);
+ }
+}
+</code></pre>
+<p>上面方法先是通过递归创建当前节点的上一级路径,然后再根据 ephemeral 的值决定创建临时还是持久节点。createEphemeral 和 createPersistent 这两个方法都比较简单,这里简单分析其中的一个。如下:</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">createEphemeral</span><span class="hljs-params">(String path)</span> </span>{
+ <span class="hljs-keyword">try</span> {
+ <span class="hljs-comment">// 通过 Curator 框架创建节点</span>
+ client.create().withMode(CreateMode.EPHEMERAL).forPath(path);
+ } <span class="hljs-keyword">catch</span> (NodeExistsException e) {
+ } <span class="hljs-keyword">catch</span> (Exception e) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(e.getMessage(), e);
+ }
+}
+</code></pre>
+<p>好了,到此关于服务注册的过程就分析完了。整个过程可简单总结为:先创建注册中心实例,之后再通过注册中心实例注册服务。本节先到这,接下来分析数据订阅过程。</p>
+<h3>2.2.5 订阅 override 数据</h3>
+<p>// 待补充</p>
+<h2>3.总结</h2>
+<p>本篇文章详细分析了 Dubbo 服务导出过程,包括配置检测,URL 组装,Invoker 创建过程、导出服务以及注册服务等等。篇幅比较大,需要大家耐心阅读。本篇文章先就到这,如果文章有不妥错误之处,希望大家能够进行反馈或修正。</p>
+</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
+ <script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+ <script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+ <script>
+ window.rootPath = '';
+ </script>
+ <script src="/build/documentation.js"></script>
+ <!-- Global site tag (gtag.js) - Google Analytics -->
+ <script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+ <script>
+ window.dataLayer = window.dataLayer || [];
+ function gtag(){dataLayer.push(arguments);}
+ gtag('js', new Date());
+
+ gtag('config', 'UA-112489517-1');
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/zh-cn/docs/source_code_guide/export-service.json b/zh-cn/docs/source_code_guide/export-service.json
new file mode 100644
index 0000000..7161ef7
--- /dev/null
+++ b/zh-cn/docs/source_code_guide/export-service.json
@@ -0,0 +1,10 @@
+{
+ "filename": "export-service.md",
+ "__html": "<h2>1.简介</h2>\n<p>本篇文章,我们来研究一下 Dubbo 导出服务的过程。Dubbo 服务导出过程始于 Spring 容器发布刷新事件,Dubbo 在接收到事件后,会立即执行服务导出逻辑。整个逻辑大致可分为三个部分,第一部分是前置工作,主要用于检查参数,组装 URL。第二部分是导出服务,包含导出服务到本地 (JVM),和导出服务到远程两个过程。第三部分是向注册中心注册服务,用于服务发现。本篇文章将会对这三个部分代码进行详细的分析。</p>\n<h2>2.源码分析</h2>\n<p>服务导出的入口方法是 ServiceBean 的 onApplicationEvent。onApplicationEvent 是一个事件响应方法,该方法会在收到 Spring 上下文刷新事件后执行服务导出操作。方法代码如下:</p>\n<pre><code class=\"language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public</span> <s [...]
+ "link": "/zh-cn/docs/source_code_guide/export-service.html",
+ "meta": {
+ "title": "服务导出",
+ "keywords": "Dubbo, service, export",
+ "description": "本文介绍了 Dubbo 服务导出的过程和实现细节"
+ }
+}
\ No newline at end of file
diff --git a/zh-cn/docs/source_code_guide/loadbalance.html b/zh-cn/docs/source_code_guide/loadbalance.html
new file mode 100644
index 0000000..93fca6c
--- /dev/null
+++ b/zh-cn/docs/source_code_guide/loadbalance.html
@@ -0,0 +1,745 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <meta name="keywords" content="Dubbo, LoadBalance" />
+ <meta name="description" content="本文介绍了集群的原理和实现细节" />
+ <!-- 网页标签标题 -->
+ <title>负载均衡</title>
+ <link rel="shortcut icon" href="/img/dubbo.ico"/>
+ <link rel="stylesheet" href="/build/documentation.css" />
+</head>
+<body>
+ <div id="root"><div class="documentation-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a [...]
+<p>LoadBalance 中文意思为负载均衡,它的职责是将网络请求,或者其他形式的负载“均摊”到不同的机器上。避免集群中部分服务器压力过大,而另一些服务器比较空闲的情况。通过负载均衡,可以让每台服务器获取到适合自己处理能力的负载。在为高负载服务器分流的同时,还可以避免资源浪费,一举两得。负载均衡可分为软件负载均衡和硬件负载均衡。在我们日常开发中,一般很难接触到硬件负载均衡。但软件负载均衡还是可以接触到的,比如 Nginx。在 Dubbo 中,也有负载均衡的概念和相应的实现。Dubbo 需要对服务消费者的调用请求进行分配,避免少数服务提供者负载过大。服务提供者负载过大,会导致部分请求超时。因此将负载均衡到每个服务提供者上,是非常必要的。Dubbo 提供了4种负载均衡实现,分别是基于权重随机算法的 RandomLoadBalance�
�基于最少活跃调用数算法的 LeastActiveLoadBalance、基于 hash 一致性的 ConsistentHashLoadBalance,以及基于加权轮询算法的 RoundRobinLoadBalance。这几个负载均衡算法代码 [...]
+<p>本系列文章在编写之初是基于 Dubbo 2.6.4 的,近期,Dubbo 2.6.5 发布了,其中就有针对对负载均衡部分的优化。因此我们在分析完 2.6.4 版本后的源码后,会另外分析 2.6.5 更新的部分。其他的就不多说了,进入正题吧。</p>
+<h2>2.源码分析</h2>
+<p>在 Dubbo 中,所有负载均衡实现类均继承自 AbstractLoadBalance,该类实现了 LoadBalance 接口,并封装了一些公共的逻辑。所以在分析负载均衡实现之前,先来看一下 AbstractLoadBalance 的逻辑。首先来看一下负载均衡的入口方法 select,如下:</p>
+<pre><code class="language-java"><span class="hljs-meta">@Override</span>
+<span class="hljs-keyword">public</span> <T> <span class="hljs-function">Invoker<T> <span class="hljs-title">select</span><span class="hljs-params">(List<Invoker<T>> invokers, URL url, Invocation invocation)</span> </span>{
+ <span class="hljs-keyword">if</span> (invokers == <span class="hljs-keyword">null</span> || invokers.isEmpty())
+ <span class="hljs-keyword">return</span> <span class="hljs-keyword">null</span>;
+ <span class="hljs-comment">// 如果 invokers 列表中仅有一个 Invoker,直接返回即可,无需进行负载均衡</span>
+ <span class="hljs-keyword">if</span> (invokers.size() == <span class="hljs-number">1</span>)
+ <span class="hljs-keyword">return</span> invokers.get(<span class="hljs-number">0</span>);
+
+ <span class="hljs-comment">// 调用 doSelect 方法进行负载均衡,该方法为抽象方法,由子类实现</span>
+ <span class="hljs-keyword">return</span> doSelect(invokers, url, invocation);
+}
+
+<span class="hljs-keyword">protected</span> <span class="hljs-keyword">abstract</span> <T> <span class="hljs-function">Invoker<T> <span class="hljs-title">doSelect</span><span class="hljs-params">(List<Invoker<T>> invokers, URL url, Invocation invocation)</span></span>;
+</code></pre>
+<p>select 方法的逻辑比较简单,首先会检测 invokers 集合的合法性,然后再检测 invokers 集合元素数量。如果只包含一个 Invoker,直接返回该 Inovker 即可。如果包含多个 Invoker,此时需要通过负载均衡算法选择一个 Invoker。具体的负载均衡算法由子类实现,接下来章节会对这些子类一一进行详细分析。</p>
+<p>AbstractLoadBalance 除了实现了 LoadBalance 接口方法,还封装了一些公共逻辑,比如服务提供者权重计算逻辑。具体实现如下:</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getWeight</span><span class="hljs-params">(Invoker<?> invoker, Invocation invocation)</span> </span>{
+ <span class="hljs-comment">// 从 url 中获取权重 weight 配置值</span>
+ <span class="hljs-keyword">int</span> weight = invoker.getUrl().getMethodParameter(invocation.getMethodName(), Constants.WEIGHT_KEY, Constants.DEFAULT_WEIGHT);
+ <span class="hljs-keyword">if</span> (weight > <span class="hljs-number">0</span>) {
+ <span class="hljs-comment">// 获取服务提供者启动时间戳</span>
+ <span class="hljs-keyword">long</span> timestamp = invoker.getUrl().getParameter(Constants.REMOTE_TIMESTAMP_KEY, <span class="hljs-number">0L</span>);
+ <span class="hljs-keyword">if</span> (timestamp > <span class="hljs-number">0L</span>) {
+ <span class="hljs-comment">// 计算服务提供者运行时长</span>
+ <span class="hljs-keyword">int</span> uptime = (<span class="hljs-keyword">int</span>) (System.currentTimeMillis() - timestamp);
+ <span class="hljs-comment">// 获取服务预热时间,默认为10分钟</span>
+ <span class="hljs-keyword">int</span> warmup = invoker.getUrl().getParameter(Constants.WARMUP_KEY, Constants.DEFAULT_WARMUP);
+ <span class="hljs-comment">// 如果服务运行时间小于预热时间,则重新计算服务权重,即降权</span>
+ <span class="hljs-keyword">if</span> (uptime > <span class="hljs-number">0</span> && uptime < warmup) {
+ <span class="hljs-comment">// 重新计算服务权重</span>
+ weight = calculateWarmupWeight(uptime, warmup, weight);
+ }
+ }
+ }
+ <span class="hljs-keyword">return</span> weight;
+}
+
+<span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">int</span> <span class="hljs-title">calculateWarmupWeight</span><span class="hljs-params">(<span class="hljs-keyword">int</span> uptime, <span class="hljs-keyword">int</span> warmup, <span class="hljs-keyword">int</span> weight)</span> </span>{
+ <span class="hljs-comment">// 计算权重,下面代码逻辑上形似于 (uptime / warmup) * weight。</span>
+ <span class="hljs-comment">// 随着服务运行时间 uptime 增大,权重计算值 ww 会慢慢接近配置值 weight</span>
+ <span class="hljs-keyword">int</span> ww = (<span class="hljs-keyword">int</span>) ((<span class="hljs-keyword">float</span>) uptime / ((<span class="hljs-keyword">float</span>) warmup / (<span class="hljs-keyword">float</span>) weight));
+ <span class="hljs-keyword">return</span> ww < <span class="hljs-number">1</span> ? <span class="hljs-number">1</span> : (ww > weight ? weight : ww);
+}
+</code></pre>
+<p>上面是权重的计算过程,该过程主要用于保证当服务运行时长小于服务预热时间时,对服务进行降权,避免让服务在启动之初就处于高负载状态。服务预热是一个优化手段,与此类似的还有 JVM 预热。主要目的是让服务启动后“低功率”运行一段时间,使其效率慢慢提升至最佳状态。</p>
+<p>关于 AbstractLoadBalance 就先分析到这,接下来分析各个实现类的代码。首先,我们从 Dubbo 缺省的实现类 RandomLoadBalance 看起。</p>
+<h3>2.1 RandomLoadBalance</h3>
+<p>RandomLoadBalance 是加权随机算法的具体实现,它的算法思想很简单。假设我们有一组服务器 servers = [A, B, C],他们对应的权重为 weights = [5, 3, 2],权重总和为10。现在把这些权重值平铺在一维坐标值上,[0, 5) 区间属于服务器 A,[5, 8) 区间属于服务器 B,[8, 10) 区间属于服务器 C。接下来通过随机数生成器生成一个范围在 [0, 10) 之间的随机数,然后计算这个随机数会落到哪个区间上。比如数字3会落到服务器 A 对应的区间上,此时返回服务器 A 即可。权重越大的机器,在坐标轴上对应的区间范围就越大,因此随机数生成器生成的数字就会有更大的概率落到此区间内。只要随机数生成器产生的随机数分布性很好,在经过多次选择后,每个服务器被选中的次数比例接近其权重比例。比如,经过一万次选择后,服务器 A 被选中的次数大约为5000次,服务器 B 被�
��中的次数约为3000次,服务器 C 被选中的次数约为2000次。</p>
+<p>以上就是 RandomLoadBalance 背后的算法思想,比较简单。下面开始分析源码。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RandomLoadBalance</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractLoadBalance</span> </span>{
+
+ <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String NAME = <span class="hljs-string">"random"</span>;
+
+ <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Random random = <span class="hljs-keyword">new</span> Random();
+
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-keyword">protected</span> <T> <span class="hljs-function">Invoker<T> <span class="hljs-title">doSelect</span><span class="hljs-params">(List<Invoker<T>> invokers, URL url, Invocation invocation)</span> </span>{
+ <span class="hljs-keyword">int</span> length = invokers.size();
+ <span class="hljs-keyword">int</span> totalWeight = <span class="hljs-number">0</span>;
+ <span class="hljs-keyword">boolean</span> sameWeight = <span class="hljs-keyword">true</span>;
+ <span class="hljs-comment">// 下面这个循环有两个作用,第一是计算总权重 totalWeight,</span>
+ <span class="hljs-comment">// 第二是检测每个服务提供者的权重是否相同</span>
+ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < length; i++) {
+ <span class="hljs-keyword">int</span> weight = getWeight(invokers.get(i), invocation);
+ <span class="hljs-comment">// 累加权重</span>
+ totalWeight += weight;
+ <span class="hljs-comment">// 检测当前服务提供者的权重与上一个服务提供者的权重是否相同,</span>
+ <span class="hljs-comment">// 不相同的话,则将 sameWeight 置为 false。</span>
+ <span class="hljs-keyword">if</span> (sameWeight && i > <span class="hljs-number">0</span>
+ && weight != getWeight(invokers.get(i - <span class="hljs-number">1</span>), invocation)) {
+ sameWeight = <span class="hljs-keyword">false</span>;
+ }
+ }
+
+ <span class="hljs-comment">// 下面的 if 分支主要用于获取随机数,并计算随机数落在哪个区间上</span>
+ <span class="hljs-keyword">if</span> (totalWeight > <span class="hljs-number">0</span> && !sameWeight) {
+ <span class="hljs-comment">// 随机获取一个 [0, totalWeight) 区间内的数字</span>
+ <span class="hljs-keyword">int</span> offset = random.nextInt(totalWeight);
+ <span class="hljs-comment">// 循环让 offset 数减去服务提供者权重值,当 offset 小于0时,返回相应的 Invoker。</span>
+ <span class="hljs-comment">// 举例说明一下,我们有 servers = [A, B, C],weights = [5, 3, 2],offset = 7。</span>
+ <span class="hljs-comment">// 第一次循环,offset - 5 = 2 > 0,即 offset > 5,</span>
+ <span class="hljs-comment">// 表明其不会落在服务器 A 对应的区间上。</span>
+ <span class="hljs-comment">// 第二次循环,offset - 3 = -1 < 0,即 5 < offset < 8,</span>
+ <span class="hljs-comment">// 表明其会落在服务器 B 对应的区间上</span>
+ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < length; i++) {
+ <span class="hljs-comment">// 让随机值 offset 减去权重值</span>
+ offset -= getWeight(invokers.get(i), invocation);
+ <span class="hljs-keyword">if</span> (offset < <span class="hljs-number">0</span>) {
+ <span class="hljs-comment">// 返回相应的 Invoker</span>
+ <span class="hljs-keyword">return</span> invokers.get(i);
+ }
+ }
+ }
+
+ <span class="hljs-comment">// 如果所有服务提供者权重值相同,此时直接随机返回一个即可</span>
+ <span class="hljs-keyword">return</span> invokers.get(random.nextInt(length));
+ }
+}
+</code></pre>
+<p>RandomLoadBalance 的算法思想比较简单,在经过多次请求后,能够将调用请求按照权重值进行“均匀”分配。当然 RandomLoadBalance 也存在一定的缺点,当调用次数比较少时,Random 产生的随机数可能会比较集中,此时多数请求会落到同一台服务器上。这个缺点并不是很严重,多数情况下可以忽略。RandomLoadBalance 是一个简单,高效的负载均衡实现,因此 Dubbo 选择它作为缺省实现。</p>
+<p>关于 RandomLoadBalance 就先到这了,接下来分析 LeastActiveLoadBalance。</p>
+<h3>2.2 LeastActiveLoadBalance</h3>
+<p>LeastActiveLoadBalance 翻译过来是最小活跃数负载均衡。活跃调用数越小,表明该服务提供者效率越高,单位时间内可处理更多的请求。此时应优先将请求分配给该服务提供者。在具体实现中,每个服务提供者对应一个活跃数 active。初始情况下,所有服务提供者活跃数均为0。每收到一个请求,活跃数加1,完成请求后则将活跃数减1。在服务运行一段时间后,性能好的服务提供者处理请求的速度更快,因此活跃数下降的也越快,此时这样的服务提供者能够优先获取到新的服务请求、这就是最小活跃数负载均衡算法的基本思想。除了最小活跃数,LeastActiveLoadBalance 在实现上还引入了权重值。所以准确的来说,LeastActiveLoadBalance 是基于加权最小活跃数算法实现的。举个例子说明一下,在一个服务提供者集群中,有两个性能优异的服务提供者。某一时刻它们
的活跃数相同,此时 Dubbo 会根据它们的权重去分配请求,权重越大,获取到新请求的概率就越大。如果两个服务提供者权重相同,此时随机选择一个即可。关于 LeastActiveLoadBalance 的背景知识就 [...]
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LeastActiveLoadBalance</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractLoadBalance</span> </span>{
+
+ <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String NAME = <span class="hljs-string">"leastactive"</span>;
+
+ <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Random random = <span class="hljs-keyword">new</span> Random();
+
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-keyword">protected</span> <T> <span class="hljs-function">Invoker<T> <span class="hljs-title">doSelect</span><span class="hljs-params">(List<Invoker<T>> invokers, URL url, Invocation invocation)</span> </span>{
+ <span class="hljs-keyword">int</span> length = invokers.size();
+ <span class="hljs-comment">// 最小的活跃数</span>
+ <span class="hljs-keyword">int</span> leastActive = -<span class="hljs-number">1</span>;
+ <span class="hljs-comment">// 具有相同“最小活跃数”的服务者提供者(以下用 Invoker 代称)数量</span>
+ <span class="hljs-keyword">int</span> leastCount = <span class="hljs-number">0</span>;
+ <span class="hljs-comment">// leastIndexs 用于记录具有相同“最小活跃数”的 Invoker 在 invokers 列表中的下标信息</span>
+ <span class="hljs-keyword">int</span>[] leastIndexs = <span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[length];
+ <span class="hljs-keyword">int</span> totalWeight = <span class="hljs-number">0</span>;
+ <span class="hljs-comment">// 第一个最小活跃数的 Invoker 权重值,用于与其他具有相同最小活跃数的 Invoker 的权重进行对比,</span>
+ <span class="hljs-comment">// 以检测是否“所有具有相同最小活跃数的 Invoker 的权重”均相等</span>
+ <span class="hljs-keyword">int</span> firstWeight = <span class="hljs-number">0</span>;
+ <span class="hljs-keyword">boolean</span> sameWeight = <span class="hljs-keyword">true</span>;
+
+ <span class="hljs-comment">// 遍历 invokers 列表</span>
+ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < length; i++) {
+ Invoker<T> invoker = invokers.get(i);
+ <span class="hljs-comment">// 获取 Invoker 对应的活跃数</span>
+ <span class="hljs-keyword">int</span> active = RpcStatus.getStatus(invoker.getUrl(), invocation.getMethodName()).getActive();
+ <span class="hljs-comment">// 获取权重 - ⭐️</span>
+ <span class="hljs-keyword">int</span> weight = invoker.getUrl().getMethodParameter(invocation.getMethodName(), Constants.WEIGHT_KEY, Constants.DEFAULT_WEIGHT);
+ <span class="hljs-comment">// 发现更小的活跃数,重新开始</span>
+ <span class="hljs-keyword">if</span> (leastActive == -<span class="hljs-number">1</span> || active < leastActive) {
+ <span class="hljs-comment">// 使用当前活跃数 active 更新最小活跃数 leastActive</span>
+ leastActive = active;
+ <span class="hljs-comment">// 更新 leastCount 为 1</span>
+ leastCount = <span class="hljs-number">1</span>;
+ <span class="hljs-comment">// 记录当前下标值到 leastIndexs 中</span>
+ leastIndexs[<span class="hljs-number">0</span>] = i;
+ totalWeight = weight;
+ firstWeight = weight;
+ sameWeight = <span class="hljs-keyword">true</span>;
+
+ <span class="hljs-comment">// 当前 Invoker 的活跃数 active 与最小活跃数 leastActive 相同 </span>
+ } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (active == leastActive) {
+ <span class="hljs-comment">// 在 leastIndexs 中记录下当前 Invoker 在 invokers 集合中的下标</span>
+ leastIndexs[leastCount++] = i;
+ <span class="hljs-comment">// 累加权重</span>
+ totalWeight += weight;
+ <span class="hljs-comment">// 检测当前 Invoker 的权重与 firstWeight 是否相等,</span>
+ <span class="hljs-comment">// 不相等则将 sameWeight 置为 false</span>
+ <span class="hljs-keyword">if</span> (sameWeight && i > <span class="hljs-number">0</span>
+ && weight != firstWeight) {
+ sameWeight = <span class="hljs-keyword">false</span>;
+ }
+ }
+ }
+
+ <span class="hljs-comment">// 当只有一个 Invoker 具有最小活跃数,此时直接返回该 Invoker 即可</span>
+ <span class="hljs-keyword">if</span> (leastCount == <span class="hljs-number">1</span>) {
+ <span class="hljs-keyword">return</span> invokers.get(leastIndexs[<span class="hljs-number">0</span>]);
+ }
+
+ <span class="hljs-comment">// 有多个 Invoker 具有相同的最小活跃数,但它们之间的权重不同</span>
+ <span class="hljs-keyword">if</span> (!sameWeight && totalWeight > <span class="hljs-number">0</span>) {
+ <span class="hljs-comment">// 随机生成一个 [0, totalWeight) 之间的数字</span>
+ <span class="hljs-keyword">int</span> offsetWeight = random.nextInt(totalWeight);
+ <span class="hljs-comment">// 循环让随机数减去具有最小活跃数的 Invoker 的权重值,</span>
+ <span class="hljs-comment">// 当 offset 小于等于0时,返回相应的 Invoker</span>
+ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < leastCount; i++) {
+ <span class="hljs-keyword">int</span> leastIndex = leastIndexs[i];
+ <span class="hljs-comment">// 获取权重值,并让随机数减去权重值 - ⭐️</span>
+ offsetWeight -= getWeight(invokers.get(leastIndex), invocation);
+ <span class="hljs-keyword">if</span> (offsetWeight <= <span class="hljs-number">0</span>)
+ <span class="hljs-keyword">return</span> invokers.get(leastIndex);
+ }
+ }
+ <span class="hljs-comment">// 如果权重相同或权重为0时,随机返回一个 Invoker</span>
+ <span class="hljs-keyword">return</span> invokers.get(leastIndexs[random.nextInt(leastCount)]);
+ }
+}
+</code></pre>
+<p>上面代码的逻辑比较多,我们在代码中写了大量的注释,有帮助大家理解代码逻辑。下面简单总结一下以上代码所做的事情,如下:</p>
+<ol>
+<li>遍历 invokers 列表,寻找活跃数最小的 Invoker</li>
+<li>如果有多个 Invoker 具有相同的最小活跃数,此时记录下这些 Invoker 在 invokers 集合中的下标,并累加它们的权重,比较它们的权重值是否相等</li>
+<li>如果只有一个 Invoker 具有最小的活跃数,此时直接返回该 Invoker 即可</li>
+<li>如果有多个 Invoker 具有最小活跃数,且它们的权重不相等,此时处理方式和 RandomLoadBalance 一致</li>
+<li>如果有多个 Invoker 具有最小活跃数,但它们的权重相等,此时随机返回一个即可</li>
+</ol>
+<p>以上就是 LeastActiveLoadBalance 大致的实现逻辑,大家在阅读的源码的过程中要注意区分活跃数与权重这两个概念,不要混为一谈。</p>
+<p>以上分析是基于 Dubbo 2.6.4 版本进行的,由于近期 Dubbo 2.6.5 发布了,并对 LeastActiveLoadBalance 进行了一些修改,下面简单来介绍一下修改内容。回到上面的源码中,我们在上面的代码中标注了两个黄色的五角星⭐️。两处标记对应的代码分别如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">int</span> weight = invoker.getUrl().getMethodParameter(invocation.getMethodName(), Constants.WEIGHT_KEY, Constants.DEFAULT_WEIGHT);
+</code></pre>
+<pre><code class="language-java">offsetWeight -= getWeight(invokers.get(leastIndex), invocation);
+</code></pre>
+<p>问题出在服务预热阶段,第一行代码直接从 url 中去权重值,未被降权过。第二行代码获取到的是经过降权后的权重。第一行代码获取到的权重值最终会被累加到权重总和 totalWeight 中,这个时候会导致一个问题。offsetWeight 是一个在 [0, totalWeight) 范围内的随机数,而它所减去的是经过降权的权重。很有可能在经过 leastCount 次运算后,offsetWeight 仍然是大于0的,导致无法选中 Invoker。这个问题对应的 issue 为 <a href="https://github.com/apache/incubator-dubbo/issues/904">#904</a>,并在 pull request <a href="https://github.com/apache/incubator-dubbo/pull/2172">#2172</a> 中被修复。具体的修复逻辑是将标注一处的代码修改为:</p>
+<pre><code class="language-java"><span class="hljs-comment">// afterWarmup 等价于上面的 weight 变量,这样命名是为了强调该变量经过了 warmup 降权处理</span>
+<span class="hljs-keyword">int</span> afterWarmup = getWeight(invoker, invocation);
+</code></pre>
+<p>另外,2.6.4 版本中的 LeastActiveLoadBalance 还要一个缺陷,即当一组 Invoker 具有相同的最小活跃数,且其中一个 Invoker 的权重值为1,此时这个 Invoker 无法被选中。缺陷代码如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">int</span> offsetWeight = random.nextInt(totalWeight);
+<span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < leastCount; i++) {
+ <span class="hljs-keyword">int</span> leastIndex = leastIndexs[i];
+ offsetWeight -= getWeight(invokers.get(leastIndex), invocation);
+ <span class="hljs-keyword">if</span> (offsetWeight <= <span class="hljs-number">0</span>) <span class="hljs-comment">// ❌</span>
+ <span class="hljs-keyword">return</span> invokers.get(leastIndex);
+}
+</code></pre>
+<p>问题出在了<code>offsetWeight <= 0</code>上,举例说明,假设有一组 Invoker 的权重为 5、2、1,offsetWeight 最大值为 7。假设 offsetWeight = 7,你会发现,当 for 循环进行第二次遍历后 offsetWeight = 7 - 5 - 2 = 0,提前返回了。此时,此时权重为1的 Invoker 就没有机会被选中了。该问题在 Dubbo 2.6.5 中被修复了,修改后的代码如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">int</span> offsetWeight = random.nextInt(totalWeight) + <span class="hljs-number">1</span>;
+</code></pre>
+<p>以上就是 Dubob 2.6.5 对 LeastActiveLoadBalance 的更新,内容不是很多,先分析到这。接下来分析基于一致性 hash 思想的 ConsistentHashLoadBalance。</p>
+<h3>2.3 ConsistentHashLoadBalance</h3>
+<p>一致性 hash 算法由麻省理工学院的 Karger 及其合作者于1997年提供出的,算法提出之初是用于大规模缓存系统的负载均衡。它的工作过程是这样的,首先根据 ip 或其他的信息为缓存节点生成一个 hash,并将这个 hash 投射到 [0, 2<sup>32</sup> - 1] 的圆环上。当有查询或写入请求时,则为缓存项的 key 生成一个 hash 值。然后查找第一个大于或等于该 hash 值的缓存节点,并到这个节点中查询或写入缓存项。如果当前节点挂了,则在下一次查询或写入缓存时,为缓存项查找另一个大于其 hash 值的缓存节点即可。大致效果如下图所示,每个缓存节点在圆环上占据一个位置。如果缓存项的 key 的 hash 值小于缓存节点 hash 值,则到该缓存节点中存储或读取缓存项。比如下面绿色点对应的缓存项将会被存储到 cache-2 节点中。由于 cache-3 挂了,原本应该存到该节点中的�
�存想最终会存储到 cache-4 节点中。</p>
+<p><img src="./sources/images/consistent-hash.jpg" alt=""></p>
+<p>下面来看看一致性 hash 在 Dubbo 中的应用。我们把上图的缓存节点替换成 Dubbo 的服务提供者,于是得到了下图:</p>
+<p><img src="./sources/images/consistent-hash-invoker.jpg" alt=""></p>
+<p>这里相同颜色的节点均属于同一个服务提供者,比如 Invoker1-1,Invoker1-2,……, Invoker1-160。这样做的目的是通过引入虚拟节点,让 Invoker 在圆环上分散开来,避免数据倾斜问题。所谓数据倾斜是指,由于节点不够分散,导致大量请求落到了同一个节点上,而其他节点只会接收到了少量请求的情况。比如:</p>
+<p><img src="./sources/images/consistent-hash-data-incline.jpg" alt=""></p>
+<p>如上,由于 Invoker-1 和 Invoker-2 在圆环上分布不均,导致系统中75%的请求都会落到 Invoker-1 上,只有 25% 的请求会落到 Invoker-2 上。解决这个问题办法是引入虚拟节点,通过虚拟节点均衡各个节点的请求量。</p>
+<p>到这里背景知识就普及完了,接下来开始分析源码。我们先从 ConsistentHashLoadBalance 的 doSelect 方法开始看起,如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ConsistentHashLoadBalance</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractLoadBalance</span> </span>{
+
+ <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> ConcurrentMap<String, ConsistentHashSelector<?>> selectors =
+ <span class="hljs-keyword">new</span> ConcurrentHashMap<String, ConsistentHashSelector<?>>();
+
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-keyword">protected</span> <T> <span class="hljs-function">Invoker<T> <span class="hljs-title">doSelect</span><span class="hljs-params">(List<Invoker<T>> invokers, URL url, Invocation invocation)</span> </span>{
+ String methodName = RpcUtils.getMethodName(invocation);
+ String key = invokers.get(<span class="hljs-number">0</span>).getUrl().getServiceKey() + <span class="hljs-string">"."</span> + methodName;
+
+ <span class="hljs-comment">// 获取 invokers 原始的 hashcode</span>
+ <span class="hljs-keyword">int</span> identityHashCode = System.identityHashCode(invokers);
+ ConsistentHashSelector<T> selector = (ConsistentHashSelector<T>) selectors.get(key);
+ <span class="hljs-comment">// 如果 invokers 是一个新的 List 对象,意味着服务提供者数量发生了变化,可能新增也可能减少了。</span>
+ <span class="hljs-comment">// 此时 selector.identityHashCode != identityHashCode 条件成立</span>
+ <span class="hljs-keyword">if</span> (selector == <span class="hljs-keyword">null</span> || selector.identityHashCode != identityHashCode) {
+ <span class="hljs-comment">// 创建新的 ConsistentHashSelector</span>
+ selectors.put(key, <span class="hljs-keyword">new</span> ConsistentHashSelector<T>(invokers, methodName, identityHashCode));
+ selector = (ConsistentHashSelector<T>) selectors.get(key);
+ }
+
+ <span class="hljs-comment">// 调用 ConsistentHashSelector 的 select 方法选择 Invoker</span>
+ <span class="hljs-keyword">return</span> selector.select(invocation);
+ }
+
+ <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ConsistentHashSelector</span><<span class="hljs-title">T</span>> </span>{...}
+}
+</code></pre>
+<p>如上,doSelect 方法主要做了一些前置工作,比如检测 invokers 列表是不是变动过,以及创建 ConsistentHashSelector。这些工作做完后,接下来开始调用 ConsistentHashSelector 的 select 方法执行负载均衡逻辑。在分析 select 方法之前,我们先来看一下一致性 hash 选择器 ConsistentHashSelector 的初始化过程,如下:</p>
+<pre><code class="language-java"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ConsistentHashSelector</span><<span class="hljs-title">T</span>> </span>{
+
+ <span class="hljs-comment">// 使用 TreeMap 存储 Invoker 虚拟节点</span>
+ <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> TreeMap<Long, Invoker<T>> virtualInvokers;
+
+ <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> replicaNumber;
+
+ <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> identityHashCode;
+
+ <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span>[] argumentIndex;
+
+ ConsistentHashSelector(List<Invoker<T>> invokers, String methodName, <span class="hljs-keyword">int</span> identityHashCode) {
+ <span class="hljs-keyword">this</span>.virtualInvokers = <span class="hljs-keyword">new</span> TreeMap<Long, Invoker<T>>();
+ <span class="hljs-keyword">this</span>.identityHashCode = identityHashCode;
+ URL url = invokers.get(<span class="hljs-number">0</span>).getUrl();
+ <span class="hljs-comment">// 获取虚拟节点数,默认为160</span>
+ <span class="hljs-keyword">this</span>.replicaNumber = url.getMethodParameter(methodName, <span class="hljs-string">"hash.nodes"</span>, <span class="hljs-number">160</span>);
+ <span class="hljs-comment">// 获取参与 hash 计算的参数下标值,默认对第一个参数进行 hash 运算</span>
+ String[] index = Constants.COMMA_SPLIT_PATTERN.split(url.getMethodParameter(methodName, <span class="hljs-string">"hash.arguments"</span>, <span class="hljs-string">"0"</span>));
+ argumentIndex = <span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[index.length];
+ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < index.length; i++) {
+ argumentIndex[i] = Integer.parseInt(index[i]);
+ }
+ <span class="hljs-keyword">for</span> (Invoker<T> invoker : invokers) {
+ String address = invoker.getUrl().getAddress();
+ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < replicaNumber / <span class="hljs-number">4</span>; i++) {
+ <span class="hljs-comment">// 对 address + i 进行 md5 运算,得到一个长度为16的字节数组</span>
+ <span class="hljs-keyword">byte</span>[] digest = md5(address + i);
+ <span class="hljs-comment">// 对 digest 部分字节进行4次 hash 运算,得到四个不同的 long 型正整数</span>
+ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> h = <span class="hljs-number">0</span>; h < <span class="hljs-number">4</span>; h++) {
+ <span class="hljs-comment">// h = 0 时,取 digest 中下标为 0 ~ 3 的4个字节进行位运算</span>
+ <span class="hljs-comment">// h = 1 时,取 digest 中下标为 4 ~ 7 的4个字节进行位运算</span>
+ <span class="hljs-comment">// h = 2, h = 3 时过程同上</span>
+ <span class="hljs-keyword">long</span> m = hash(digest, h);
+ <span class="hljs-comment">// 将 hash 到 invoker 的映射关系存储到 virtualInvokers 中,</span>
+ <span class="hljs-comment">// virtualInvokers 需要提供高效的查询操作,因此选用 TreeMap 作为存储结构</span>
+ virtualInvokers.put(m, invoker);
+ }
+ }
+ }
+ }
+}
+</code></pre>
+<p>ConsistentHashSelector 的构造方法执行了一系列的初始化逻辑,比如从配置中获取虚拟节点数以及参与 hash 计算的参数下标,默认情况下只使用第一个参数进行 hash。需要特别说明的是,ConsistentHashLoadBalance 的负载均衡逻辑只受参数值影响,具有相同参数值的请求将会被分配给同一个服务提供者。ConsistentHashLoadBalance 不 关系权重,因此使用时需要注意一下。</p>
+<p>在获取虚拟节点数和参数下标配置后,接下来要做的事情是计算虚拟节点 hash 值,并将虚拟节点存储到 TreeMap 中。到此,ConsistentHashSelector 初始化工作就完成了。接下来,我们来看看 select 方法的逻辑。</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">public</span> Invoker<T> <span class="hljs-title">select</span><span class="hljs-params">(Invocation invocation)</span> </span>{
+ <span class="hljs-comment">// 将参数转为 key</span>
+ String key = toKey(invocation.getArguments());
+ <span class="hljs-comment">// 对参数 key 进行 md5 运算</span>
+ <span class="hljs-keyword">byte</span>[] digest = md5(key);
+ <span class="hljs-comment">// 取 digest 数组的前四个字节进行 hash 运算,再将 hash 值传给 selectForKey 方法,</span>
+ <span class="hljs-comment">// 寻找合适的 Invoker</span>
+ <span class="hljs-keyword">return</span> selectForKey(hash(digest, <span class="hljs-number">0</span>));
+}
+
+<span class="hljs-function"><span class="hljs-keyword">private</span> Invoker<T> <span class="hljs-title">selectForKey</span><span class="hljs-params">(<span class="hljs-keyword">long</span> hash)</span> </span>{
+ <span class="hljs-comment">// 到 TreeMap 中查找第一个节点值大于或等于当前 hash 的 Invoker</span>
+ Map.Entry<Long, Invoker<T>> entry = virtualInvokers.tailMap(hash, <span class="hljs-keyword">true</span>).firstEntry();
+ <span class="hljs-comment">// 如果 hash 大于 Invoker 在圆环上最大的位置,此时 entry = null,</span>
+ <span class="hljs-comment">// 需要将 TreeMap 的头结点赋值给 entry</span>
+ <span class="hljs-keyword">if</span> (entry == <span class="hljs-keyword">null</span>) {
+ entry = virtualInvokers.firstEntry();
+ }
+
+ <span class="hljs-comment">// 返回 Invoker</span>
+ <span class="hljs-keyword">return</span> entry.getValue();
+}
+</code></pre>
+<p>如上,选择的过程相对比较简单了。首先是对参数进行 md5 以及 hash 运算,得到一个 hash 值。然后再拿这个值到 TreeMap 中查找目标 Invoker 即可。</p>
+<p>到此关于 ConsistentHashLoadBalance 就分析完了。在阅读 ConsistentHashLoadBalance 源码之前,大家一定要先补充背景知识,不然很难看懂代码逻辑。</p>
+<h3>2.4 RoundRobinLoadBalance</h3>
+<p>本节,我们来看一下 Dubbo 中加权轮询负载均衡的实现 RoundRobinLoadBalance。在详细分析源码前,我们先来了解一下什么是加权轮询。这里从最简单的轮询开始讲起,所谓轮询是指将请求轮流分配给每台服务器。举个例子,我们有三台服务器 A、B、C。我们将第一个请求分配给服务器 A,第二个请求分配给服务器 B,第三个请求分配给服务器 C,第四个请求再次分配给服务器 A。这个过程就叫做轮询。轮询是一种无状态负载均衡算法,实现简单,适用于每台服务器性能相近的场景下。但现实情况下,我们并不能保证每台服务器性能均相近。如果我们将等量的请求分配给性能较差的服务器,这显然是不合理的。因此,这个时候我们需要对轮询过程进行加权,以调控每台服务器的负载。经过加权后,每台服务器能够得到的请求数比例,接近或等于他们的权�
�比。比如服务器 A、B、C 权重比为 5:2:1。那么在8次请求中,服务器 A 将收到其中的5次请求,服务器 B 会收到其中的2次请求,服务器 C 则收到其中的1次请求。</p>
+<p>以上就是加权轮询的算法思想,搞懂了这个思想,接下来我们就可以分析源码了。我们先来看一下 2.6.4 版本的 RoundRobinLoadBalance。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RoundRobinLoadBalance</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractLoadBalance</span> </span>{
+
+ <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String NAME = <span class="hljs-string">"roundrobin"</span>;
+
+ <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> ConcurrentMap<String, AtomicPositiveInteger> sequences =
+ <span class="hljs-keyword">new</span> ConcurrentHashMap<String, AtomicPositiveInteger>();
+
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-keyword">protected</span> <T> <span class="hljs-function">Invoker<T> <span class="hljs-title">doSelect</span><span class="hljs-params">(List<Invoker<T>> invokers, URL url, Invocation invocation)</span> </span>{
+ <span class="hljs-comment">// key = 全限定类名 + "." + 方法名,比如 com.xxx.DemoService.sayHello</span>
+ String key = invokers.get(<span class="hljs-number">0</span>).getUrl().getServiceKey() + <span class="hljs-string">"."</span> + invocation.getMethodName();
+ <span class="hljs-keyword">int</span> length = invokers.size();
+ <span class="hljs-comment">// 最大权重</span>
+ <span class="hljs-keyword">int</span> maxWeight = <span class="hljs-number">0</span>;
+ <span class="hljs-comment">// 最小权重</span>
+ <span class="hljs-keyword">int</span> minWeight = Integer.MAX_VALUE;
+ <span class="hljs-keyword">final</span> LinkedHashMap<Invoker<T>, IntegerWrapper> invokerToWeightMap = <span class="hljs-keyword">new</span> LinkedHashMap<Invoker<T>, IntegerWrapper>();
+ <span class="hljs-comment">// 权重总和</span>
+ <span class="hljs-keyword">int</span> weightSum = <span class="hljs-number">0</span>;
+
+ <span class="hljs-comment">// 下面这个循环主要用于查找最大和最小权重,计算权重总和等</span>
+ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < length; i++) {
+ <span class="hljs-keyword">int</span> weight = getWeight(invokers.get(i), invocation);
+ <span class="hljs-comment">// 获取最大和最小权重</span>
+ maxWeight = Math.max(maxWeight, weight);
+ minWeight = Math.min(minWeight, weight);
+ <span class="hljs-keyword">if</span> (weight > <span class="hljs-number">0</span>) {
+ <span class="hljs-comment">// 将 weight 封装到 IntegerWrapper 中</span>
+ invokerToWeightMap.put(invokers.get(i), <span class="hljs-keyword">new</span> IntegerWrapper(weight));
+ <span class="hljs-comment">// 累加权重</span>
+ weightSum += weight;
+ }
+ }
+
+ <span class="hljs-comment">// 查找 key 对应的对应 AtomicPositiveInteger 实例,为空则创建。</span>
+ <span class="hljs-comment">// 这里可以把 AtomicPositiveInteger 看成一个黑盒,大家只要知道</span>
+ <span class="hljs-comment">// AtomicPositiveInteger 用于记录服务的调用编号即可。至于细节,</span>
+ <span class="hljs-comment">// 大家如果感兴趣,可以自行分析</span>
+ AtomicPositiveInteger sequence = sequences.get(key);
+ <span class="hljs-keyword">if</span> (sequence == <span class="hljs-keyword">null</span>) {
+ sequences.putIfAbsent(key, <span class="hljs-keyword">new</span> AtomicPositiveInteger());
+ sequence = sequences.get(key);
+ }
+
+ <span class="hljs-comment">// 获取当前的调用编号</span>
+ <span class="hljs-keyword">int</span> currentSequence = sequence.getAndIncrement();
+ <span class="hljs-comment">// 如果最小权重小于最大权重,表明服务提供者之间的权重是不相等的</span>
+ <span class="hljs-keyword">if</span> (maxWeight > <span class="hljs-number">0</span> && minWeight < maxWeight) {
+ <span class="hljs-comment">// 使用调用编号对权重总和进行取余操作</span>
+ <span class="hljs-keyword">int</span> mod = currentSequence % weightSum;
+ <span class="hljs-comment">// 进行 maxWeight 次遍历</span>
+ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < maxWeight; i++) {
+ <span class="hljs-comment">// 遍历 invokerToWeightMap</span>
+ <span class="hljs-keyword">for</span> (Map.Entry<Invoker<T>, IntegerWrapper> each : invokerToWeightMap.entrySet()) {
+ <span class="hljs-comment">// 获取 Invoker</span>
+ <span class="hljs-keyword">final</span> Invoker<T> k = each.getKey();
+ <span class="hljs-comment">// 获取权重包装类 IntegerWrapper</span>
+ <span class="hljs-keyword">final</span> IntegerWrapper v = each.getValue();
+
+ <span class="hljs-comment">// 如果 mod = 0,且权重大于0,此时返回相应的 Invoker</span>
+ <span class="hljs-keyword">if</span> (mod == <span class="hljs-number">0</span> && v.getValue() > <span class="hljs-number">0</span>) {
+ <span class="hljs-keyword">return</span> k;
+ }
+
+ <span class="hljs-comment">// mod != 0,且权重大于0,此时对权重和 mod 分别进行自减操作</span>
+ <span class="hljs-keyword">if</span> (v.getValue() > <span class="hljs-number">0</span>) {
+ v.decrement();
+ mod--;
+ }
+ }
+ }
+ }
+
+ <span class="hljs-comment">// 服务提供者之间的权重相等,此时通过轮询选择 Invoker</span>
+ <span class="hljs-keyword">return</span> invokers.get(currentSequence % length);
+ }
+
+ <span class="hljs-comment">// IntegerWrapper 是一个 int 包装类,主要包含了一个自减方法。</span>
+ <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IntegerWrapper</span> </span>{
+ <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> value;
+
+ <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">decrement</span><span class="hljs-params">()</span> </span>{
+ <span class="hljs-keyword">this</span>.value--;
+ }
+
+ <span class="hljs-comment">// 省略部分代码</span>
+ }
+}
+</code></pre>
+<p>如上,RoundRobinLoadBalance 的每行代码都不是很难理解,但是将它们组合在一起之后,就不是很好理解了。所以下面我们举例进行说明,假设我们有三台服务器 servers = [A, B, C],对应的权重为 weights = [2, 5, 1]。接下来对上面的逻辑进行简单的模拟。</p>
+<p>mod = 0:满足条件,此时直接返回服务器 A</p>
+<p>mod = 1:需要进行一次递减操作才能满足条件,此时返回服务器 B</p>
+<p>mod = 2:需要进行两次递减操作才能满足条件,此时返回服务器 C</p>
+<p>mod = 3:需要进行三次递减操作才能满足条件,经过递减后,服务器权重为 [1, 4, 0],此时返回服务器 A</p>
+<p>mod = 4:需要进行四次递减操作才能满足条件,经过递减后,服务器权重为 [0, 4, 0],此时返回服务器 B</p>
+<p>mod = 5:需要进行五次递减操作才能满足条件,经过递减后,服务器权重为 [0, 3, 0],此时返回服务器 B</p>
+<p>mod = 6:需要进行六次递减操作才能满足条件,经过递减后,服务器权重为 [0, 2, 0],此时返回服务器 B</p>
+<p>mod = 7:需要进行七次递减操作才能满足条件,经过递减后,服务器权重为 [0, 1, 0],此时返回服务器 B</p>
+<p>经过8次调用后,我们得到的负载均衡结果为 [A, B, C, A, B, B, B, B],次数比 A:B:C = 2:5:1,等于权重比。当 sequence = 8 时,mod = 0,此时重头再来。从上面的模拟过程可以看出,当 mod >= 3 后,服务器 C 就不会被选中了,因为它的权重被减为0了。当 mod >= 4 后,服务器 A 的权重被减为0,此后 A 就不会再被选中。</p>
+<p>以上是 2.6.4 版本的 RoundRobinLoadBalance 分析过程,2.6.4 版本的 RoundRobinLoadBalance 在某些情况下存在着比较严重的性能问题,该问题最初是在 <a href="https://github.com/apache/incubator-dubbo/issues/2578">issue #2578</a> 中被反馈出来。问题出在了 Invoker 的返回时机上,RoundRobinLoadBalance 需要在<code>mod == 0 && v.getValue() > 0</code> 条件成立的情况下才会被返回相应的 Invoker。假如 mod 很大,比如 10000,50000,甚至更大时,doSelect 方法需要进行很多次计算才能将 mod 减为0。由此可知,doSelect 的效率与 mod 有关,时间复杂度为 O(mod)。mod 又受最大权重 maxWeight 的影响,因此当某个服务提供者配置了非常大的权重,此时 RoundRobinLoadBalance 会产生比较 [...]
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RoundRobinLoadBalance</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractLoadBalance</span> </span>{
+
+ <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String NAME = <span class="hljs-string">"roundrobin"</span>;
+
+ <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> ConcurrentMap<String, AtomicPositiveInteger> sequences = <span class="hljs-keyword">new</span> ConcurrentHashMap<String, AtomicPositiveInteger>();
+
+ <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> ConcurrentMap<String, AtomicPositiveInteger> indexSeqs = <span class="hljs-keyword">new</span> ConcurrentHashMap<String, AtomicPositiveInteger>();
+
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-keyword">protected</span> <T> <span class="hljs-function">Invoker<T> <span class="hljs-title">doSelect</span><span class="hljs-params">(List<Invoker<T>> invokers, URL url, Invocation invocation)</span> </span>{
+ String key = invokers.get(<span class="hljs-number">0</span>).getUrl().getServiceKey() + <span class="hljs-string">"."</span> + invocation.getMethodName();
+ <span class="hljs-keyword">int</span> length = invokers.size();
+ <span class="hljs-keyword">int</span> maxWeight = <span class="hljs-number">0</span>;
+ <span class="hljs-keyword">int</span> minWeight = Integer.MAX_VALUE;
+ <span class="hljs-keyword">final</span> List<Invoker<T>> invokerToWeightList = <span class="hljs-keyword">new</span> ArrayList<>();
+
+ <span class="hljs-comment">// 查找最大和最小权重</span>
+ <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < length; i++) {
+ <span class="hljs-keyword">int</span> weight = getWeight(invokers.get(i), invocation);
+ maxWeight = Math.max(maxWeight, weight);
+ minWeight = Math.min(minWeight, weight);
+ <span class="hljs-keyword">if</span> (weight > <span class="hljs-number">0</span>) {
+ invokerToWeightList.add(invokers.get(i));
+ }
+ }
+
+ <span class="hljs-comment">// 获取当前服务对应的调用序列对象 AtomicPositiveInteger</span>
+ AtomicPositiveInteger sequence = sequences.get(key);
+ <span class="hljs-keyword">if</span> (sequence == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 创建 AtomicPositiveInteger,默认值为0</span>
+ sequences.putIfAbsent(key, <span class="hljs-keyword">new</span> AtomicPositiveInteger());
+ sequence = sequences.get(key);
+ }
+
+ <span class="hljs-comment">// 获取下标序列对象 AtomicPositiveInteger</span>
+ AtomicPositiveInteger indexSeq = indexSeqs.get(key);
+ <span class="hljs-keyword">if</span> (indexSeq == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 创建 AtomicPositiveInteger,默认值为 -1</span>
+ indexSeqs.putIfAbsent(key, <span class="hljs-keyword">new</span> AtomicPositiveInteger(-<span class="hljs-number">1</span>));
+ indexSeq = indexSeqs.get(key);
+ }
+
+ <span class="hljs-keyword">if</span> (maxWeight > <span class="hljs-number">0</span> && minWeight < maxWeight) {
+ length = invokerToWeightList.size();
+ <span class="hljs-keyword">while</span> (<span class="hljs-keyword">true</span>) {
+ <span class="hljs-keyword">int</span> index = indexSeq.incrementAndGet() % length;
+ <span class="hljs-keyword">int</span> currentWeight = sequence.get() % maxWeight;
+
+ <span class="hljs-comment">// 每循环一轮(index = 0),重新计算 currentWeight</span>
+ <span class="hljs-keyword">if</span> (index == <span class="hljs-number">0</span>) {
+ currentWeight = sequence.incrementAndGet() % maxWeight;
+ }
+
+ <span class="hljs-comment">// 检测 Invoker 的权重是否大于 currentWeight,大于则返回</span>
+ <span class="hljs-keyword">if</span> (getWeight(invokerToWeightList.get(index), invocation) > currentWeight) {
+ <span class="hljs-keyword">return</span> invokerToWeightList.get(index);
+ }
+ }
+ }
+
+ <span class="hljs-comment">// 所有 Invoker 权重相等,此时进行普通的轮询即可</span>
+ <span class="hljs-keyword">return</span> invokers.get(sequence.incrementAndGet() % length);
+ }
+}
+</code></pre>
+<p>上面代码的逻辑是这样的,每进行一轮循环,重新计算 currentWeight。如果当前 Invoker 权重大于 currentWeight,则返回该 Invoker。下面举例说明,假设服务器 [A, B, C] 对应权重 [5, 2, 1]。</p>
+<p>第一轮循环,currentWeight = 1,可返回 A 和 B</p>
+<p>第二轮循环,currentWeight = 2,返回 A</p>
+<p>第三轮循环,currentWeight = 3,返回 A</p>
+<p>第四轮循环,currentWeight = 4,返回 A</p>
+<p>第五轮循环,currentWeight = 0,返回 A, B, C</p>
+<p>如上,这里的一轮循环是指 index 再次变为0所经历过的循环,这里可以把 index = 0 看做是一轮循环的开始。每一轮循环的次数与 Invoker 的数量有关,Invoker 数量通常不会太多,所以我们可以认为上面代码的时间复杂度为常数级。</p>
+<p>重构后的 RoundRobinLoadBalance 看起来已经很不错了,但是在代码更新不久后,很快又被重构了。这次重构原因是新的 RoundRobinLoadBalance 在某些情况下选出的服务器序列不够均匀。比如,服务器 [A, B, C] 对应权重 [5, 1, 1]。进行7次负载均衡后,选择出来的序列为 [A, A, A, A, A, B, C]。前5个请求全部都落在了服务器 A上,这将会使服务器 A 短时间内接收大量的请求,压力陡增。而 B 和 C 此时无请求,处于空闲状态。而我们期望的结果是这样的 [A, A, B, A, C, A, A],不同服务器可以穿插获取请求。为了增加负载均衡结果的平滑性,社区再次对 RoundRobinLoadBalance 的实现进行了重构,这次重构参考自 Nginx 的平滑加权轮询负载均衡。每个服务器对应两个权重,分别为 weight 和 currentWeight。其中 weight 是固定的,currentWeight 会动态调整,初始值为0。当有新的请求进来时,遍
历服务器列表,让它的 currentWeight [...]
+<p>上面描述不是很好理解,下面还是举例进行说明。这里仍然使用服务器 [A, B, C] 对应权重 [5, 1, 1] 的例子说明,现在有7个请求依次进入负载均衡逻辑,选择过程如下:</p>
+<table>
+<thead>
+<tr>
+<th>请求编号</th>
+<th>currentWeight 数组</th>
+<th>选择结果</th>
+<th>减去权重总和后的 currentWeight 数组</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>1</td>
+<td>[5, 1, 1]</td>
+<td>A</td>
+<td>[-2, 1, 1]</td>
+</tr>
+<tr>
+<td>2</td>
+<td>[3, 2, 2]</td>
+<td>A</td>
+<td>[-4, 2, 2]</td>
+</tr>
+<tr>
+<td>3</td>
+<td>[1, 3, 3]</td>
+<td>B</td>
+<td>[1, -4, 3]</td>
+</tr>
+<tr>
+<td>4</td>
+<td>[6, -3, 4]</td>
+<td>A</td>
+<td>[-1, -3, 4]</td>
+</tr>
+<tr>
+<td>5</td>
+<td>[4, -2, 5]</td>
+<td>C</td>
+<td>[4, -2, -2]</td>
+</tr>
+<tr>
+<td>6</td>
+<td>[9, -1, -1]</td>
+<td>A</td>
+<td>[2, -1, -1]</td>
+</tr>
+<tr>
+<td>7</td>
+<td>[7, 0, 0]</td>
+<td>A</td>
+<td>[0, 0, 0]</td>
+</tr>
+</tbody>
+</table>
+<p>如上,经过平滑性处理后,得到的服务器序列为 [A, A, B, A, C, A, A],相比之前的序列 [A, A, A, A, A, B, C],分布性要好一些。初始情况下 currentWeight = [0, 0, 0],第7个请求处理完后,currentWeight 再次变为 [0, 0, 0]。</p>
+<p>以上就是平滑加权轮询的计算过程,接下来,我们来看看 Dubbo-2.6.5 是如何实现上面的计算过程的。</p>
+<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RoundRobinLoadBalance</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractLoadBalance</span> </span>{
+ <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String NAME = <span class="hljs-string">"roundrobin"</span>;
+
+ <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">int</span> RECYCLE_PERIOD = <span class="hljs-number">60000</span>;
+
+ <span class="hljs-keyword">protected</span> <span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">WeightedRoundRobin</span> </span>{
+ <span class="hljs-comment">// 服务提供者权重</span>
+ <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> weight;
+ <span class="hljs-comment">// 当前权重</span>
+ <span class="hljs-keyword">private</span> AtomicLong current = <span class="hljs-keyword">new</span> AtomicLong(<span class="hljs-number">0</span>);
+ <span class="hljs-comment">// 最后一次更新时间</span>
+ <span class="hljs-keyword">private</span> <span class="hljs-keyword">long</span> lastUpdate;
+
+ <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setWeight</span><span class="hljs-params">(<span class="hljs-keyword">int</span> weight)</span> </span>{
+ <span class="hljs-keyword">this</span>.weight = weight;
+ <span class="hljs-comment">// 初始情况下,current = 0</span>
+ current.set(<span class="hljs-number">0</span>);
+ }
+ <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">long</span> <span class="hljs-title">increaseCurrent</span><span class="hljs-params">()</span> </span>{
+ <span class="hljs-comment">// current = current + weight;</span>
+ <span class="hljs-keyword">return</span> current.addAndGet(weight);
+ }
+ <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">sel</span><span class="hljs-params">(<span class="hljs-keyword">int</span> total)</span> </span>{
+ <span class="hljs-comment">// current = current - total;</span>
+ current.addAndGet(-<span class="hljs-number">1</span> * total);
+ }
+ }
+
+ <span class="hljs-comment">// 嵌套 Map 结构,存储的数据结构示例如下:</span>
+ <span class="hljs-comment">// {</span>
+ <span class="hljs-comment">// "UserService.query": {</span>
+ <span class="hljs-comment">// "url1": WeightedRoundRobin@123, </span>
+ <span class="hljs-comment">// "url2": WeightedRoundRobin@456, </span>
+ <span class="hljs-comment">// },</span>
+ <span class="hljs-comment">// "UserService.update": {</span>
+ <span class="hljs-comment">// "url1": WeightedRoundRobin@123, </span>
+ <span class="hljs-comment">// "url2": WeightedRoundRobin@456,</span>
+ <span class="hljs-comment">// }</span>
+ <span class="hljs-comment">// }</span>
+ <span class="hljs-comment">// 最外层为服务类名 + 方法名,第二层为 url 到 WeightedRoundRobin 的映射关系。</span>
+ <span class="hljs-comment">// 这里我们可以将 url 看成是服务提供者的 id</span>
+ <span class="hljs-keyword">private</span> ConcurrentMap<String, ConcurrentMap<String, WeightedRoundRobin>> methodWeightMap = <span class="hljs-keyword">new</span> ConcurrentHashMap<String, ConcurrentMap<String, WeightedRoundRobin>>();
+
+ <span class="hljs-comment">// 原子更新锁</span>
+ <span class="hljs-keyword">private</span> AtomicBoolean updateLock = <span class="hljs-keyword">new</span> AtomicBoolean();
+
+ <span class="hljs-meta">@Override</span>
+ <span class="hljs-keyword">protected</span> <T> <span class="hljs-function">Invoker<T> <span class="hljs-title">doSelect</span><span class="hljs-params">(List<Invoker<T>> invokers, URL url, Invocation invocation)</span> </span>{
+ String key = invokers.get(<span class="hljs-number">0</span>).getUrl().getServiceKey() + <span class="hljs-string">"."</span> + invocation.getMethodName();
+ <span class="hljs-comment">// 获取 url 到 WeightedRoundRobin 映射表,如果为空,则创建一个新的</span>
+ ConcurrentMap<String, WeightedRoundRobin> map = methodWeightMap.get(key);
+ <span class="hljs-keyword">if</span> (map == <span class="hljs-keyword">null</span>) {
+ methodWeightMap.putIfAbsent(key, <span class="hljs-keyword">new</span> ConcurrentHashMap<String, WeightedRoundRobin>());
+ map = methodWeightMap.get(key);
+ }
+ <span class="hljs-keyword">int</span> totalWeight = <span class="hljs-number">0</span>;
+ <span class="hljs-keyword">long</span> maxCurrent = Long.MIN_VALUE;
+
+ <span class="hljs-comment">// 获取当前时间</span>
+ <span class="hljs-keyword">long</span> now = System.currentTimeMillis();
+ Invoker<T> selectedInvoker = <span class="hljs-keyword">null</span>;
+ WeightedRoundRobin selectedWRR = <span class="hljs-keyword">null</span>;
+
+ <span class="hljs-comment">// 下面这个循环主要做了这样几件事情:</span>
+ <span class="hljs-comment">// 1. 遍历 Invoker 列表,检测当前 Invoker 是否有</span>
+ <span class="hljs-comment">// 相应的 WeightedRoundRobin,没有则创建</span>
+ <span class="hljs-comment">// 2. 检测 Invoker 权重是否发生了变化,若变化了,</span>
+ <span class="hljs-comment">// 则更新 WeightedRoundRobin 的 weight 字段</span>
+ <span class="hljs-comment">// 3. 让 current 字段加上自身权重,等价于 current += weight</span>
+ <span class="hljs-comment">// 4. 设置 lastUpdate 字段,即 lastUpdate = now</span>
+ <span class="hljs-comment">// 5. 寻找具有最大 current 的 Invoker,以及 Invoker 对应的 WeightedRoundRobin,</span>
+ <span class="hljs-comment">// 暂存起来,留作后用</span>
+ <span class="hljs-comment">// 6. 计算权重总和</span>
+ <span class="hljs-keyword">for</span> (Invoker<T> invoker : invokers) {
+ String identifyString = invoker.getUrl().toIdentityString();
+ WeightedRoundRobin weightedRoundRobin = map.get(identifyString);
+ <span class="hljs-keyword">int</span> weight = getWeight(invoker, invocation);
+ <span class="hljs-keyword">if</span> (weight < <span class="hljs-number">0</span>) {
+ weight = <span class="hljs-number">0</span>;
+ }
+
+ <span class="hljs-comment">// 检测当前 Invoker 是否有对应的 WeightedRoundRobin,没有则创建</span>
+ <span class="hljs-keyword">if</span> (weightedRoundRobin == <span class="hljs-keyword">null</span>) {
+ weightedRoundRobin = <span class="hljs-keyword">new</span> WeightedRoundRobin();
+ <span class="hljs-comment">// 设置 Invoker 权重</span>
+ weightedRoundRobin.setWeight(weight);
+ <span class="hljs-comment">// 存储 url 唯一标识 identifyString 到 weightedRoundRobin 的映射关系</span>
+ map.putIfAbsent(identifyString, weightedRoundRobin);
+ weightedRoundRobin = map.get(identifyString);
+ }
+ <span class="hljs-comment">// Invoker 权重不等于 WeightedRoundRobin 中保存的权重,说明权重变化了,此时进行更新</span>
+ <span class="hljs-keyword">if</span> (weight != weightedRoundRobin.getWeight()) {
+ weightedRoundRobin.setWeight(weight);
+ }
+
+ <span class="hljs-comment">// 让 current 加上自身权重,等价于 current += weight</span>
+ <span class="hljs-keyword">long</span> cur = weightedRoundRobin.increaseCurrent();
+ <span class="hljs-comment">// 设置 lastUpdate,表示近期更新过</span>
+ weightedRoundRobin.setLastUpdate(now);
+ <span class="hljs-comment">// 找出最大的 current </span>
+ <span class="hljs-keyword">if</span> (cur > maxCurrent) {
+ maxCurrent = cur;
+ <span class="hljs-comment">// 将具有最大 current 权重的 Invoker 赋值给 selectedInvoker</span>
+ selectedInvoker = invoker;
+ <span class="hljs-comment">// 将 Invoker 对应的 weightedRoundRobin 赋值给 selectedWRR,留作后用</span>
+ selectedWRR = weightedRoundRobin;
+ }
+
+ <span class="hljs-comment">// 计算权重总和</span>
+ totalWeight += weight;
+ }
+
+ <span class="hljs-comment">// 对 <identifyString, WeightedRoundRobin> 进行检查,过滤掉长时间未被更新的节点。</span>
+ <span class="hljs-comment">// 该节点可能挂了,invokers 中不包含该节点,所以该节点的 lastUpdate 长时间无法被更新。</span>
+ <span class="hljs-comment">// 若未更新时长超过阈值后,就会被移除掉,默认阈值为60秒。</span>
+ <span class="hljs-keyword">if</span> (!updateLock.get() && invokers.size() != map.size()) {
+ <span class="hljs-keyword">if</span> (updateLock.compareAndSet(<span class="hljs-keyword">false</span>, <span class="hljs-keyword">true</span>)) {
+ <span class="hljs-keyword">try</span> {
+ ConcurrentMap<String, WeightedRoundRobin> newMap = <span class="hljs-keyword">new</span> ConcurrentHashMap<String, WeightedRoundRobin>();
+ <span class="hljs-comment">// 拷贝</span>
+ newMap.putAll(map);
+
+ <span class="hljs-comment">// 遍历修改,即移除过期记录</span>
+ Iterator<Entry<String, WeightedRoundRobin>> it = newMap.entrySet().iterator();
+ <span class="hljs-keyword">while</span> (it.hasNext()) {
+ Entry<String, WeightedRoundRobin> item = it.next();
+ <span class="hljs-keyword">if</span> (now - item.getValue().getLastUpdate() > RECYCLE_PERIOD) {
+ it.remove();
+ }
+ }
+
+ <span class="hljs-comment">// 更新引用</span>
+ methodWeightMap.put(key, newMap);
+ } <span class="hljs-keyword">finally</span> {
+ updateLock.set(<span class="hljs-keyword">false</span>);
+ }
+ }
+ }
+
+ <span class="hljs-keyword">if</span> (selectedInvoker != <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// 让 current 减去权重总和,等价于 current -= totalWeight</span>
+ selectedWRR.sel(totalWeight);
+ <span class="hljs-comment">// 返回具有最大 current 的 Invoker</span>
+ <span class="hljs-keyword">return</span> selectedInvoker;
+ }
+
+ <span class="hljs-comment">// should not happen here</span>
+ <span class="hljs-keyword">return</span> invokers.get(<span class="hljs-number">0</span>);
+ }
+}
+</code></pre>
+<p>以上就是 Dubbo-2.6.5 版本的 RoundRobinLoadBalance,大家如果能够理解平滑加权轮询算法的计算过程,再配合代码中注释,理解上面的代码应该不难。</p>
+<h2>3.总结</h2>
+<p>本篇文章对 Dubbo 中的几种负载均衡实现进行了详细的分析,内容比较多,大家慢慢消化。理解负载均衡代码逻辑的关键之处在于对背景知识的理解,因此大家在阅读源码前,务必先了解每种负载均衡对应的背景知识。</p>
+</div></section><footer class="footer-container"><div class="footer-body"><img src="/img/dubbo_gray.png"/><img class="apache" src="/img/apache_logo.png"/><div class="cols-container"><div class="col col-12"><h3>Disclaimer</h3><p>Apache Dubbo is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making [...]
+ <script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
+ <script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
+ <script>
+ window.rootPath = '';
+ </script>
+ <script src="/build/documentation.js"></script>
+ <!-- Global site tag (gtag.js) - Google Analytics -->
+ <script async src="https://www.googletagmanager.com/gtag/js?id=UA-112489517-1"></script>
+ <script>
+ window.dataLayer = window.dataLayer || [];
+ function gtag(){dataLayer.push(arguments);}
+ gtag('js', new Date());
+
+ gtag('config', 'UA-112489517-1');
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/zh-cn/docs/source_code_guide/loadbalance.json b/zh-cn/docs/source_code_guide/loadbalance.json
new file mode 100644
index 0000000..7a0a44e
--- /dev/null
+++ b/zh-cn/docs/source_code_guide/loadbalance.json
@@ -0,0 +1,10 @@
+{
+ "filename": "loadbalance.md",
+ "__html": "<h2>1.简介</h2>\n<p>LoadBalance 中文意思为负载均衡,它的职责是将网络请求,或者其他形式的负载“均摊”到不同的机器上。避免集群中部分服务器压力过大,而另一些服务器比较空闲的情况。通过负载均衡,可以让每台服务器获取到适合自己处理能力的负载。在为高负载服务器分流的同时,还可以避免资源浪费,一举两得。负载均衡可分为软件负载均衡和硬件负载均衡。在我们日常开发中,一般很难接触到硬件负载均衡。但软件负载均衡还是可以接触到的,比如 Nginx。在 Dubbo 中,也有负载均衡的概念和相应的实现。Dubbo 需要对服务消费者的调用请求进行分配,避免少数服务提供者负载过大。服务提供者负载过大,会导致部分请求超时。因此将负载均衡到每个服务提供者上,是非常必要的。Dubbo 提供了4种负载均衡实现,分别是基于权重随
机算法的 RandomLoadBalance、基于最少活跃调用数算法的 LeastActiveLoadBalance、基于 hash 一致性的 ConsistentHashLoadBalance,以及基于加权轮询算法的 Round [...]
+ "link": "/zh-cn/docs/source_code_guide/loadbalance.html",
+ "meta": {
+ "title": "负载均衡",
+ "keywords": "Dubbo, LoadBalance",
+ "description": "本文介绍了集群的原理和实现细节"
+ }
+}
\ No newline at end of file
diff --git a/zh-cn/docs/source_code_guide/refer-service.html b/zh-cn/docs/source_code_guide/refer-service.html
new file mode 100644
index 0000000..4bb4f58
--- /dev/null
+++ b/zh-cn/docs/source_code_guide/refer-service.html
@@ -0,0 +1,856 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+ <meta name="keywords" content="Dubbo, service, refer" />
+ <meta name="description" content="本文介绍了 Dubbo 服务引用的过程和实现细节" />
+ <!-- 网页标签标题 -->
+ <title>服务引用</title>
+ <link rel="shortcut icon" href="/img/dubbo.ico"/>
+ <link rel="stylesheet" href="/build/documentation.css" />
+</head>
+<body>
+ <div id="root"><div class="documentation-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="/img/dubbo_colorful.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/img/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a [...]
+<p>上一篇文章详细分析了服务导出的过程,本篇文章我们趁热打铁,继续分析服务引用过程。在 Dubbo 中,我们可以通过两种方式引用远程服务。第一种是使用服务直联的方式引用服务,第二种方式是基于注册中心进行引用。服务直联的方式仅适合在调试或测试服务的场景下使用,不适合在线上环境使用。因此,本文我将重点分析通过注册中心引用服务的过程。从注册中心中获取服务配置只是服务引用过程中的一环,除此之外,服务消费者还需要经历 Invoker 创建、代理类创建等步骤。这些步骤,将在后续章节中一一进行分析。</p>
+<h2>2.服务引用原理</h2>
+<p>Dubbo 服务引用的时机有两个,第一个是在 Spring 容器调用 ReferenceBean 的 afterPropertiesSet 方法时引用服务,第二个是在 ReferenceBean 对应的服务被注入到其他类中时引用。这两个引用服务的时机区别在于,第一个是饿汉式的,第二个是懒汉式的。默认情况下,Dubbo 使用懒汉式引用服务。如果需要使用饿汉式,可通过配置 <dubbo:reference> 的 init 属性开启。下面我们按照 Dubbo 默认配置进行分析,整个分析过程从 ReferenceBean 的 getObject 方法开始。当我们的服务被注入到其他类中时,Spring 会第一时间调用 getObject 方法,并由该方法执行服务引用逻辑。按照惯例,在进行具体工作之前,需先进行配置检查与收集工作。接着根据收集到的信息决定服务用的方式,有三种,第一种是引用本地 (JVM) 服务,第二是通过直联方式引用远程服务,第三是通过注册中心引�
��远程服务。不管是哪种引用方式,最后都会得到一个 Invoker 实例。如果有多个注册中心,多个服务提供 [...]
+<p>以上就是服务引用的大致原理,下面我们深入到代码中,详细分析服务引用细节。</p>
+<h2>3.源码分析</h2>
+<p>服务引用的入口方法为 ReferenceBean 的 getObject 方法,该方法定义在 Spring 的 FactoryBean 接口中,ReferenceBean 实现了这个方法。实现代码如下:</p>
+<pre><code class="language-java"><span class="hljs-function"><span class="hljs-keyword">public</span> Object <span class="hljs-title">getObject</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception </span>{
+ <span class="hljs-keyword">return</span> get();
+}
+
+<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">synchronized</span> T <span class="hljs-title">get</span><span class="hljs-params">()</span> </span>{
+ <span class="hljs-keyword">if</span> (destroyed) {
+ <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalStateException(<span class="hljs-string">"Already destroyed!"</span>);
+ }
+ <span class="hljs-comment">// 检测 ref 是否为空,为空则通过 init 方法创建</span>
+ <span class="hljs-keyword">if</span> (ref == <span class="hljs-keyword">null</span>) {
+ <span class="hljs-comment">// init 方法主要用于处理配置,以及调用 createProxy 生成代理类</span>
+ init();
+ }
+ <span class="hljs-keyword">return</span> ref;
+}
+</code></pre>
+<p>以上两个方法的代码比较简短,并不难理解。这里需要特别说明一下,如果你对 2.6.4 及以下版本的 getObject 方法进行调试时,会碰到比较奇怪的的问题。这里假设你使用 IDEA,且保持了 IDEA 的默认配置。当你面调试到 get 方法的<code>if (ref == null)</code>时,你会发现 ref 不为空,导致你无法进入到 init 方法中继续调试。导致这个现象的原因是 Dubbo 框架本身有一些小问题。该问题已经在 pull request <a href="https://github.com/apache/incubator-dubbo/pull/2754">#2754</a> 修复了此问题,并跟随 2.6.5 版本发布了。如果你正在学习 2.6.4 及以下版本,可通过修改 IDEA 配置规避这个问题。首先 IDEA 配置弹窗中搜索 toString,然后取消<code>Enable 'toString' object view</code>勾选。具体如下:</p>
+<p><img src="https://blog-pictures.oss-cn-shanghai.aliyuncs.com/15417503733794.jpg" alt=""></p>
+<h3>3.1 处理配置</h3>
+<p>Dubbo 提供了丰富的配置,用于调整和优化框架行为,性能等。Dubbo 在引用或导出服务时,首先会对这些配置进行检查和处理,以保证配置到正确性。配置解析逻辑封装在 ReferenceConfig 的 init 方法中,下面进行分析。</p>
... 2426 lines suppressed ...