| <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Apache Dubbo – Dubbo SPI 扩展实现说明</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/</link><description>Recent content in Dubbo SPI 扩展实现说明 on Apache Dubbo</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><atom:link href="https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/index.xml" rel="self" type="application/rss+xml"/><item><title>Overview: 协议扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/protocol/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/protocol/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>RPC 协议扩展,封装远程调用细节。</p> |
| <p>契约:</p> |
| <ul> |
| <li>当用户调用 <code>refer()</code> 所返回的 <code>Invoker</code> 对象的 <code>invoke()</code> 方法时,协议需相应执行同 URL 远端 <code>export()</code> 传入的 <code>Invoker</code> 对象的 <code>invoke()</code> 方法。</li> |
| <li>其中,<code>refer()</code> 返回的 <code>Invoker</code> 由协议实现,协议通常需要在此 <code>Invoker</code> 中发送远程请求,<code>export()</code> 传入的 <code>Invoker</code> 由框架实现并传入,协议不需要关心。</li> |
| </ul> |
| <div class="alert alert-primary" role="alert"> |
| <h4 class="alert-heading">注意</h4> |
| <ul> |
| <li>协议不关心业务接口的透明代理,以 <code>Invoker</code> 为中心,由外层将 <code>Invoker</code> 转换为业务接口。</li> |
| <li>协议不一定要是 TCP 网络通讯,比如通过共享文件,IPC 进程间通讯等。</li> |
| </ul> |
| </div> |
| <h2 id="扩展接口">扩展接口</h2> |
| <ul> |
| <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> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">interface</span> <span style="color:#268bd2">Protocol</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">/** |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 暴露远程服务:&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 1. 协议在接收请求时,应记录请求来源方地址信息:RpcContext.getContext().setRemoteAddress();&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 2. export()必须是幂等的,也就是暴露同一个URL的Invoker两次,和暴露一次没有区别。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 3. export()传入的Invoker由框架实现并传入,协议不需要关心。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * @param &lt;T&gt; 服务的类型 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * @param invoker 服务的执行体 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * @return exporter 暴露服务的引用,用于取消暴露 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * @throws RpcException 当暴露服务出错时抛出,比如端口已占用 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> */</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> Exporter<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">export</span><span style="color:#719e07">(</span>Invoker<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> invoker<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RpcException<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">/** |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 引用远程服务:&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 1. 当用户调用refer()所返回的Invoker对象的invoke()方法时,协议需相应执行同URL远端export()传入的Invoker对象的invoke()方法。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 2. refer()返回的Invoker由协议实现,协议通常需要在此Invoker中发送远程请求。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 3. 当url中有设置check=false时,连接失败不能抛出异常,需内部自动恢复。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * @param &lt;T&gt; 服务的类型 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * @param type 服务的类型 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * @param url 远程服务的URL地址 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * @return invoker 服务的本地代理 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * @throws RpcException 当连接服务提供方失败时抛出 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> */</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> Invoker<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">refer</span><span style="color:#719e07">(</span>Class<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> type<span style="color:#719e07">,</span> URL url<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RpcException<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><h2 id="扩展配置">扩展配置</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 声明协议,如果没有配置id,将以name为id --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:protocol</span> id=<span style="color:#2aa198">&#34;xxx1&#34;</span> name=<span style="color:#2aa198">&#34;xxx&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 引用协议,如果没有配置protocol属性,将在ApplicationContext中自动扫描protocol配置 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:service</span> protocol=<span style="color:#2aa198">&#34;xxx1&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 引用协议缺省值,当&lt;dubbo:service&gt;没有配置prototol属性时,使用此配置 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:provider</span> protocol=<span style="color:#2aa198">&#34;xxx1&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span></code></pre></div><h2 id="已知扩展">已知扩展</h2> |
| <ul> |
| <li><code>org.apache.dubbo.rpc.protocol.injvm.InjvmProtocol</code></li> |
| <li><code>org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol</code></li> |
| <li><code>org.apache.dubbo.rpc.protocol.rmi.RmiProtocol</code></li> |
| <li><code>org.apache.dubbo.rpc.protocol.http.HttpProtocol</code></li> |
| <li><code>org.apache.dubbo.rpc.protocol.http.hessian.HessianProtocol</code></li> |
| <li><code>org.apache.dubbo.rpc.support.MockProtocol</code></li> |
| </ul> |
| <h2 id="扩展示例">扩展示例</h2> |
| <p>Maven项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxProtocol.java (实现Protocol接口) |
| </span></span><span style="display:flex;"><span> |-XxxExporter.java (实现Exporter接口) |
| </span></span><span style="display:flex;"><span> |-XxxInvoker.java (实现Invoker接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.rpc.Protocol (纯文本文件,内容为:xxx=com.xxx.XxxProtocol) |
| </span></span></code></pre></div><p>XxxProtocol.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.Protocol<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxProtocol</span> <span style="color:#268bd2">implements</span> Protocol <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> Exporter<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">export</span><span style="color:#719e07">(</span>Invoker<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> invoker<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RpcException <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#719e07">new</span> XxxExporter<span style="color:#719e07">(</span>invoker<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> Invoker<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">refer</span><span style="color:#719e07">(</span>Class<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> type<span style="color:#719e07">,</span> URL url<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RpcException <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#719e07">new</span> XxxInvoker<span style="color:#719e07">(</span>type<span style="color:#719e07">,</span> url<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>XxxExporter.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.support.AbstractExporter<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxExporter</span><span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">extends</span> AbstractExporter<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">XxxExporter</span><span style="color:#719e07">(</span>Invoker<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> invoker<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RemotingException<span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">super</span><span style="color:#719e07">(</span>invoker<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">unexport</span><span style="color:#719e07">()</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">super</span><span style="color:#719e07">.</span>unexport<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>XxxInvoker.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.support.AbstractInvoker<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxInvoker</span><span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">extends</span> AbstractInvoker<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">XxxInvoker</span><span style="color:#719e07">(</span>Class<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> type<span style="color:#719e07">,</span> URL url<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RemotingException<span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">super</span><span style="color:#719e07">(</span>type<span style="color:#719e07">,</span> url<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">protected</span> Result <span style="color:#268bd2">doInvoke</span><span style="color:#719e07">(</span>Invocation invocation<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> Throwable <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.rpc.Protocol:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxProtocol</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: 调用拦截扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/filter/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/filter/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>服务提供方和服务消费方调用过程拦截,Dubbo 本身的大多功能均基于此扩展点实现,每次远程方法执行,该拦截都会被执行,请注意对性能的影响。</p> |
| <p>约定:</p> |
| <ul> |
| <li>用户自定义 filter 默认在内置 filter 之后。</li> |
| <li>特殊值 <code>default</code>,表示缺省扩展点插入的位置。比如:<code>filter=&quot;xxx,default,yyy&quot;</code>,表示 <code>xxx</code> 在缺省 filter 之前,<code>yyy</code> 在缺省 filter 之后。</li> |
| <li>特殊符号 <code>-</code>,表示剔除。比如:<code>filter=&quot;-foo1&quot;</code>,剔除添加缺省扩展点 <code>foo1</code>。比如:<code>filter=&quot;-default&quot;</code>,剔除添加所有缺省扩展点。</li> |
| <li>provider 和 service 同时配置的 filter 时,累加所有 filter,而不是覆盖。比如:<code>&lt;dubbo:provider filter=&quot;xxx,yyy&quot;/&gt;</code> 和 <code>&lt;dubbo:service filter=&quot;aaa,bbb&quot; /&gt;</code>,则 <code>xxx</code>,<code>yyy</code>,<code>aaa</code>,<code>bbb</code> 均会生效。如果要覆盖,需配置:<code>&lt;dubbo:service filter=&quot;-xxx,-yyy,aaa,bbb&quot; /&gt;</code></li> |
| </ul> |
| <h2 id="扩展接口">扩展接口</h2> |
| <p><code>org.apache.dubbo.rpc.Filter</code></p> |
| <h2 id="扩展配置">扩展配置</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 消费方调用过程拦截 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:reference</span> filter=<span style="color:#2aa198">&#34;xxx,yyy&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 消费方调用过程缺省拦截器,将拦截所有reference --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:consumer</span> filter=<span style="color:#2aa198">&#34;xxx,yyy&#34;</span><span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 提供方调用过程拦截 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:service</span> filter=<span style="color:#2aa198">&#34;xxx,yyy&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 提供方调用过程缺省拦截器,将拦截所有service --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:provider</span> filter=<span style="color:#2aa198">&#34;xxx,yyy&#34;</span><span style="color:#268bd2">/&gt;</span> |
| </span></span></code></pre></div><h2 id="已知扩展">已知扩展</h2> |
| <ul> |
| <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 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxFilter.java (实现Filter接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.rpc.Filter (纯文本文件,内容为:xxx=com.xxx.XxxFilter) |
| </span></span></code></pre></div><p>XxxFilter.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.Filter<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.Invoker<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.Invocation<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.Result<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.RpcException<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxFilter</span> <span style="color:#268bd2">implements</span> Filter <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> Result <span style="color:#268bd2">invoke</span><span style="color:#719e07">(</span>Invoker<span style="color:#719e07">&lt;?&gt;</span> invoker<span style="color:#719e07">,</span> Invocation invocation<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RpcException <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// before filter ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> Result result <span style="color:#719e07">=</span> invoker<span style="color:#719e07">.</span>invoke<span style="color:#719e07">(</span>invocation<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// after filter ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">return</span> result<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.rpc.Filter:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxFilter</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: 引用监听扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/invoker-listener/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/invoker-listener/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>当有服务引用时,触发该事件。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <p><code>org.apache.dubbo.rpc.InvokerListener</code></p> |
| <h2 id="扩展配置">扩展配置</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 引用服务监听 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:reference</span> listener=<span style="color:#2aa198">&#34;xxx,yyy&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 引用服务缺省监听器 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:consumer</span> listener=<span style="color:#2aa198">&#34;xxx,yyy&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span></code></pre></div><h2 id="已知扩展">已知扩展</h2> |
| <p><code>org.apache.dubbo.rpc.listener.DeprecatedInvokerListener</code></p> |
| <h2 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxInvokerListener.java (实现InvokerListener接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.rpc.InvokerListener (纯文本文件,内容为:xxx=com.xxx.XxxInvokerListener) |
| </span></span></code></pre></div><p>XxxInvokerListener.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.InvokerListener<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.Invoker<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.RpcException<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxInvokerListener</span> <span style="color:#268bd2">implements</span> InvokerListener <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">referred</span><span style="color:#719e07">(</span>Invoker<span style="color:#719e07">&lt;?&gt;</span> invoker<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RpcException <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">destroyed</span><span style="color:#719e07">(</span>Invoker<span style="color:#719e07">&lt;?&gt;</span> invoker<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RpcException <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.rpc.InvokerListener:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxInvokerListener</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: 暴露监听扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/exporter-listener/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/exporter-listener/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>当有服务暴露时,触发该事件。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <p><code>org.apache.dubbo.rpc.ExporterListener</code></p> |
| <h2 id="扩展配置">扩展配置</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 暴露服务监听 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:service</span> listener=<span style="color:#2aa198">&#34;xxx,yyy&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 暴露服务缺省监听器 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:provider</span> listener=<span style="color:#2aa198">&#34;xxx,yyy&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span></code></pre></div><h2 id="已知扩展">已知扩展</h2> |
| <p><code>org.apache.dubbo.registry.directory.RegistryExporterListener</code></p> |
| <h2 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxExporterListener.java (实现ExporterListener接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.rpc.ExporterListener (纯文本文件,内容为:xxx=com.xxx.XxxExporterListener) |
| </span></span></code></pre></div><p>XxxExporterListener.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.ExporterListener<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.Exporter<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.RpcException<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxExporterListener</span> <span style="color:#268bd2">implements</span> ExporterListener <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">exported</span><span style="color:#719e07">(</span>Exporter<span style="color:#719e07">&lt;?&gt;</span> exporter<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RpcException <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">unexported</span><span style="color:#719e07">(</span>Exporter<span style="color:#719e07">&lt;?&gt;</span> exporter<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RpcException <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.rpc.ExporterListener:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxExporterListener</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: 集群扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/cluster/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/cluster/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>当有多个服务提供方时,将多个服务提供方组织成一个集群,并伪装成一个提供方。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <p><code>org.apache.dubbo.rpc.cluster.Cluster</code></p> |
| <h2 id="扩展配置">扩展配置</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:protocol</span> cluster=<span style="color:#2aa198">&#34;xxx&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 缺省值配置,如果&lt;dubbo:protocol&gt;没有配置cluster时,使用此配置 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:provider</span> cluster=<span style="color:#2aa198">&#34;xxx&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span></code></pre></div><h2 id="已知扩展">已知扩展</h2> |
| <ul> |
| <li><code>org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterWrapper</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> |
| <li><code>org.apache.dubbo.rpc.cluster.support.MergeableCluster</code></li> |
| <li><code>org.apache.dubbo.rpc.cluster.support.BroadcastCluster</code></li> |
| <li><code>org.apache.dubbo.rpc.cluster.support.registry.ZoneAwareCluster</code></li> |
| </ul> |
| <h2 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxCluster.java (实现Cluster接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.rpc.cluster.Cluster (纯文本文件,内容为:xxx=com.xxx.XxxCluster) |
| </span></span></code></pre></div><p>XxxCluster.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.cluster.Cluster<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.cluster.Directory<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.cluster.LoadBalance<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.Invoker<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.Invocation<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.Result<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.RpcException<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxCluster</span> <span style="color:#268bd2">implements</span> Cluster <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> Invoker<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">merge</span><span style="color:#719e07">(</span>Directory<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> directory<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RpcException <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#719e07">new</span> AbstractClusterInvoker<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;(</span>directory<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> Result <span style="color:#268bd2">doInvoke</span><span style="color:#719e07">(</span>Invocation invocation<span style="color:#719e07">,</span> List<span style="color:#719e07">&lt;</span>Invoker<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;&gt;</span> invokers<span style="color:#719e07">,</span> LoadBalance loadbalance<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RpcException <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">};</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.rpc.cluster.Cluster:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxCluster</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: 路由扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/router/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/router/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>从多个服务提供方中选择一个进行调用。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <ul> |
| <li><code>org.apache.dubbo.rpc.cluster.RouterFactory</code></li> |
| <li><code>org.apache.dubbo.rpc.cluster.Router</code></li> |
| </ul> |
| <h2 id="已知扩展">已知扩展</h2> |
| <ul> |
| <li><code>org.apache.dubbo.rpc.cluster.router.ScriptRouterFactory</code></li> |
| <li><code>org.apache.dubbo.rpc.cluster.router.FileRouterFactory</code></li> |
| <li><code>org.apache.dubbo.rpc.cluster.router.condition.config.AppRouterFactory</code></li> |
| <li><code>org.apache.dubbo.rpc.cluster.CacheableRouterFactory</code></li> |
| <li><code>org.apache.dubbo.rpc.cluster.router.condition.ConditionRouterFactory</code></li> |
| <li><code>org.apache.dubbo.rpc.cluster.router.mock.MockRouterFactory</code></li> |
| <li><code>org.apache.dubbo.rpc.cluster.router.condition.config.ServiceRouterFactory</code></li> |
| <li><code>org.apache.dubbo.rpc.cluster.router.tag.TagRouterFactory</code></li> |
| </ul> |
| <h2 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxRouterFactory.java (实现RouterFactory接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.rpc.cluster.RouterFactory (纯文本文件,内容为:xxx=com.xxx.XxxRouterFactory) |
| </span></span></code></pre></div><p>XxxRouterFactory.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.cluster.RouterFactory<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.Invoker<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.Invocation<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.RpcException<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxRouterFactory</span> <span style="color:#268bd2">implements</span> RouterFactory <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> Router <span style="color:#268bd2">getRouter</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.rpc.cluster.RouterFactory:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxRouterFactory</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: 负载均衡扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/load-balance/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/load-balance/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>从多个服务提供方中选择一个进行调用</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <p><code>org.apache.dubbo.rpc.cluster.LoadBalance</code></p> |
| <h2 id="扩展配置">扩展配置</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:protocol</span> loadbalance=<span style="color:#2aa198">&#34;xxx&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 缺省值设置,当&lt;dubbo:protocol&gt;没有配置loadbalance时,使用此配置 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:provider</span> loadbalance=<span style="color:#2aa198">&#34;xxx&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span></code></pre></div><h2 id="已知扩展">已知扩展</h2> |
| <ul> |
| <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> |
| <li><code>org.apache.dubbo.rpc.cluster.loadbalance.ConsistentHashLoadBalance</code></li> |
| <li><code>org.apache.dubbo.rpc.cluster.loadbalance.ShortestResponseLoadBalance</code></li> |
| </ul> |
| <h2 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxLoadBalance.java (实现LoadBalance接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.rpc.cluster.LoadBalance (纯文本文件,内容为:xxx=com.xxx.XxxLoadBalance) |
| </span></span></code></pre></div><p>XxxLoadBalance.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.cluster.LoadBalance<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.Invoker<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.Invocation<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.RpcException<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxLoadBalance</span> <span style="color:#268bd2">implements</span> LoadBalance <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> Invoker<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">select</span><span style="color:#719e07">(</span>List<span style="color:#719e07">&lt;</span>Invoker<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;&gt;</span> invokers<span style="color:#719e07">,</span> Invocation invocation<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RpcException <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.rpc.cluster.LoadBalance:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxLoadBalance</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: 合并结果扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/merger/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/merger/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>合并返回结果,用于分组聚合。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <p><code>org.apache.dubbo.rpc.cluster.Merger</code></p> |
| <h2 id="扩展配置">扩展配置</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:method</span> merger=<span style="color:#2aa198">&#34;xxx&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span></code></pre></div><h2 id="已知扩展">已知扩展</h2> |
| <ul> |
| <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> |
| <li><code>org.apache.dubbo.rpc.cluster.merger.ByteArrayMerger</code></li> |
| <li><code>org.apache.dubbo.rpc.cluster.merger.CharArrayMerger</code></li> |
| <li><code>org.apache.dubbo.rpc.cluster.merger.ShortArrayMerger</code></li> |
| <li><code>org.apache.dubbo.rpc.cluster.merger.IntArrayMerger</code></li> |
| <li><code>org.apache.dubbo.rpc.cluster.merger.LongArrayMerger</code></li> |
| <li><code>org.apache.dubbo.rpc.cluster.merger.FloatArrayMerger</code></li> |
| <li><code>org.apache.dubbo.rpc.cluster.merger.DoubleArrayMerger</code></li> |
| <li><code>org.apache.dubbo.rpc.cluster.merger.BooleanArrayMerger</code></li> |
| </ul> |
| <h2 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxMerger.java (实现Merger接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.rpc.cluster.Merger (纯文本文件,内容为:xxx=com.xxx.XxxMerger) |
| </span></span></code></pre></div><p>XxxMerger.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.cluster.Merger<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxMerger</span><span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">implements</span> Merger<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> T <span style="color:#268bd2">merge</span><span style="color:#719e07">(</span>T<span style="color:#719e07">...</span> results<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.rpc.cluster.Merger:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxMerger</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: 注册中心扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/registry/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/registry/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>负责服务的注册与发现。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <ul> |
| <li><code>org.apache.dubbo.registry.RegistryFactory</code></li> |
| <li><code>org.apache.dubbo.registry.Registry</code></li> |
| </ul> |
| <h2 id="扩展配置">扩展配置</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 定义注册中心 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:registry</span> id=<span style="color:#2aa198">&#34;xxx1&#34;</span> address=<span style="color:#2aa198">&#34;xxx://ip:port&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 引用注册中心,如果没有配置registry属性,将在ApplicationContext中自动扫描registry配置 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:service</span> registry=<span style="color:#2aa198">&#34;xxx1&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 引用注册中心缺省值,当&lt;dubbo:service&gt;没有配置registry属性时,使用此配置 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:provider</span> registry=<span style="color:#2aa198">&#34;xxx1&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span></code></pre></div><h2 id="扩展契约">扩展契约</h2> |
| <p>RegistryFactory.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">interface</span> <span style="color:#268bd2">RegistryFactory</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">/** |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 连接注册中心. |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 连接注册中心需处理契约:&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 1. 当设置check=false时表示不检查连接,否则在连接不上时抛出异常。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 2. 支持URL上的username:password权限认证。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 3. 支持backup=10.20.153.10备选注册中心集群地址。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 4. 支持file=registry.cache本地磁盘文件缓存。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 5. 支持timeout=1000请求超时设置。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 6. 支持session=60000会话超时或过期设置。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * @param url 注册中心地址,不允许为空 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * @return 注册中心引用,总不返回空 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> */</span> |
| </span></span><span style="display:flex;"><span> Registry <span style="color:#268bd2">getRegistry</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>RegistryService.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">interface</span> <span style="color:#268bd2">RegistryService</span> <span style="color:#719e07">{</span> <span style="color:#586e75">// Registry extends RegistryService |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#586e75">/** |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 注册服务. |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 注册需处理契约:&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 1. 当URL设置了check=false时,注册失败后不报错,在后台定时重试,否则抛出异常。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 2. 当URL设置了dynamic=false参数,则需持久存储,否则,当注册者出现断电等情况异常退出时,需自动删除。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 3. 当URL设置了category=overrides时,表示分类存储,缺省类别为providers,可按分类部分通知数据。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 4. 当注册中心重启,网络抖动,不能丢失数据,包括断线自动删除数据。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 5. 允许URI相同但参数不同的URL并存,不能覆盖。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * @param url 注册信息,不允许为空,如:dubbo://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&amp;application=kylin |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> */</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">register</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">/** |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 取消注册服务. |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 取消注册需处理契约:&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 1. 如果是dynamic=false的持久存储数据,找不到注册数据,则抛IllegalStateException,否则忽略。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 2. 按全URL匹配取消注册。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * @param url 注册信息,不允许为空,如:dubbo://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&amp;application=kylin |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> */</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">unregister</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">/** |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 订阅服务. |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 订阅需处理契约:&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 1. 当URL设置了check=false时,订阅失败后不报错,在后台定时重试。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 2. 当URL设置了category=overrides,只通知指定分类的数据,多个分类用逗号分隔,并允许星号通配,表示订阅所有分类数据。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 3. 允许以interface,group,version,classifier作为条件查询,如:interface=com.alibaba.foo.BarService&amp;version=1.0.0&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 4. 并且查询条件允许星号通配,订阅所有接口的所有分组的所有版本,或:interface=*&amp;group=*&amp;version=*&amp;classifier=*&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 5. 当注册中心重启,网络抖动,需自动恢复订阅请求。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 6. 允许URI相同但参数不同的URL并存,不能覆盖。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 7. 必须阻塞订阅过程,等第一次通知完后再返回。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * @param url 订阅条件,不允许为空,如:consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&amp;application=kylin |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * @param listener 变更事件监听器,不允许为空 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> */</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">subscribe</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">,</span> NotifyListener listener<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">/** |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 取消订阅服务. |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 取消订阅需处理契约:&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 1. 如果没有订阅,直接忽略。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 2. 按全URL匹配取消订阅。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * @param url 订阅条件,不允许为空,如:consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&amp;application=kylin |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * @param listener 变更事件监听器,不允许为空 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> */</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">unsubscribe</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">,</span> NotifyListener listener<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">/** |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 查询注册列表,与订阅的推模式相对应,这里为拉模式,只返回一次结果。 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * @see org.apache.dubbo.registry.NotifyListener#notify(List) |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * @param url 查询条件,不允许为空,如:consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&amp;application=kylin |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * @return 已注册信息列表,可能为空,含义同{@link org.apache.dubbo.registry.NotifyListener#notify(List&lt;URL&gt;)}的参数。 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> */</span> |
| </span></span><span style="display:flex;"><span> List<span style="color:#719e07">&lt;</span>URL<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">lookup</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>NotifyListener.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">interface</span> <span style="color:#268bd2">NotifyListener</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">/** |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 当收到服务变更通知时触发。 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 通知需处理契约:&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 1. 总是以服务接口和数据类型为维度全量通知,即不会通知一个服务的同类型的部分数据,用户不需要对比上一次通知结果。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 2. 订阅时的第一次通知,必须是一个服务的所有类型数据的全量通知。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 3. 中途变更时,允许不同类型的数据分开通知,比如:providers, consumers, routes, overrides,允许只通知其中一种类型,但该类型的数据必须是全量的,不是增量的。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 4. 如果一种类型的数据为空,需通知一个empty协议并带category参数的标识性URL数据。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 5. 通知者(即注册中心实现)需保证通知的顺序,比如:单线程推送,队列串行化,带版本对比。&lt;br&gt; |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * @param urls 已注册信息列表,总不为空,含义同{@link org.apache.dubbo.registry.RegistryService#lookup(URL)}的返回值。 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> */</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">notify</span><span style="color:#719e07">(</span>List<span style="color:#719e07">&lt;</span>URL<span style="color:#719e07">&gt;</span> urls<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><h2 id="已知扩展">已知扩展</h2> |
| <p><code>org.apache.dubbo.registry.support.dubbo.DubboRegistryFactory</code></p> |
| <h2 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxRegistryFactoryjava (实现RegistryFactory接口) |
| </span></span><span style="display:flex;"><span> |-XxxRegistry.java (实现Registry接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.registry.RegistryFactory (纯文本文件,内容为:xxx=com.xxx.XxxRegistryFactory) |
| </span></span></code></pre></div><p>XxxRegistryFactory.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.registry.RegistryFactory<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.registry.Registry<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.common.URL<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxRegistryFactory</span> <span style="color:#268bd2">implements</span> RegistryFactory <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> Registry <span style="color:#268bd2">getRegistry</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#719e07">new</span> XxxRegistry<span style="color:#719e07">(</span>url<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>XxxRegistry.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.registry.Registry<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.registry.NotifyListener<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.common.URL<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxRegistry</span> <span style="color:#268bd2">implements</span> Registry <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">register</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">unregister</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">subscribe</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">,</span> NotifyListener listener<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">unsubscribe</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">,</span> NotifyListener listener<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.registry.RegistryFactory:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxRegistryFactory</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: 监控中心扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/monitor/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/monitor/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>负责服务调用次和调用时间的监控。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <ul> |
| <li><code>org.apache.dubbo.monitor.MonitorFactory</code></li> |
| <li><code>org.apache.dubbo.monitor.Monitor</code></li> |
| </ul> |
| <h2 id="扩展配置">扩展配置</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 定义监控中心 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:monitor</span> address=<span style="color:#2aa198">&#34;xxx://ip:port&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span></code></pre></div><h2 id="已知扩展">已知扩展</h2> |
| <p>org.apache.dubbo.monitor.support.dubbo.DubboMonitorFactory</p> |
| <h2 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxMonitorFactoryjava (实现MonitorFactory接口) |
| </span></span><span style="display:flex;"><span> |-XxxMonitor.java (实现Monitor接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.monitor.MonitorFactory (纯文本文件,内容为:xxx=com.xxx.XxxMonitorFactory) |
| </span></span></code></pre></div><p>XxxMonitorFactory.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.monitor.MonitorFactory<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.monitor.Monitor<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.common.URL<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxMonitorFactory</span> <span style="color:#268bd2">implements</span> MonitorFactory <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> Monitor <span style="color:#268bd2">getMonitor</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#719e07">new</span> XxxMonitor<span style="color:#719e07">(</span>url<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>XxxMonitor.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.monitor.Monitor<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxMonitor</span> <span style="color:#268bd2">implements</span> Monitor <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">count</span><span style="color:#719e07">(</span>URL statistics<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.monitor.MonitorFactory:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxMonitorFactory</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: 扩展点加载扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/extension-factory/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/extension-factory/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>扩展点本身的加载容器,可从不同容器加载扩展点。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <p><code>org.apache.dubbo.common.extension.ExtensionFactory</code></p> |
| <h2 id="扩展配置">扩展配置</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:application</span> compiler=<span style="color:#2aa198">&#34;jdk&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span></code></pre></div><h2 id="已知扩展">已知扩展</h2> |
| <ul> |
| <li><code>org.apache.dubbo.common.extension.factory.SpiExtensionFactory</code></li> |
| <li><code>org.apache.dubbo.config.spring.extension.SpringExtensionFactory</code></li> |
| </ul> |
| <h2 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxExtensionFactory.java (实现ExtensionFactory接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.common.extension.ExtensionFactory (纯文本文件,内容为:xxx=com.xxx.XxxExtensionFactory) |
| </span></span></code></pre></div><p>XxxExtensionFactory.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.common.extension.ExtensionFactory<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxExtensionFactory</span> <span style="color:#268bd2">implements</span> ExtensionFactory <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> Object <span style="color:#268bd2">getExtension</span><span style="color:#719e07">(</span>Class<span style="color:#719e07">&lt;?&gt;</span> type<span style="color:#719e07">,</span> String name<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.common.extension.ExtensionFactory:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxExtensionFactory</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: Liveness 存活探针</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/liveness/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/liveness/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>拓展应用存活的检测点。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <p><code>org.apache.dubbo.qos.probe.LivenessProbe</code></p> |
| <h2 id="扩展配置">扩展配置</h2> |
| <p>Dubbo QOS <code>live</code> 命令自动发现</p> |
| <h2 id="已知扩展">已知扩展</h2> |
| <p>暂无默认实现</p> |
| <h2 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxLivenessProbe.java (实现LivenessProbe接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.qos.probe.LivenessProbe (纯文本文件,内容为:xxx=com.xxx.XxxLivenessProbe) |
| </span></span></code></pre></div><p>XxxLivenessProbe.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxLivenessProbe</span> <span style="color:#268bd2">implements</span> LivenessProbe <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">boolean</span> <span style="color:#268bd2">check</span><span style="color:#719e07">()</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.qos.probe.LivenessProbe:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>xxx=com.xxx.XxxLivenessProbe |
| </span></span></code></pre></div></description></item><item><title>Overview: 动态代理扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/proxy-factory/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/proxy-factory/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>将 <code>Invoker</code> 接口转换成业务接口。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <p><code>org.apache.dubbo.rpc.ProxyFactory</code></p> |
| <h2 id="扩展配置">扩展配置</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:protocol</span> proxy=<span style="color:#2aa198">&#34;xxx&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 缺省值配置,当&lt;dubbo:protocol&gt;没有配置proxy属性时,使用此配置 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:provider</span> proxy=<span style="color:#2aa198">&#34;xxx&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span></code></pre></div><h2 id="已知扩展">已知扩展</h2> |
| <ul> |
| <li><code>org.apache.dubbo.rpc.proxy.JdkProxyFactory</code></li> |
| <li><code>org.apache.dubbo.rpc.proxy.JavassistProxyFactory</code></li> |
| </ul> |
| <h2 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxProxyFactory.java (实现ProxyFactory接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.rpc.ProxyFactory (纯文本文件,内容为:xxx=com.xxx.XxxProxyFactory) |
| </span></span></code></pre></div><p>XxxProxyFactory.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.ProxyFactory<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.Invoker<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.rpc.RpcException<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxProxyFactory</span> <span style="color:#268bd2">implements</span> ProxyFactory <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> T <span style="color:#268bd2">getProxy</span><span style="color:#719e07">(</span>Invoker<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> invoker<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RpcException <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> Invoker<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">getInvoker</span><span style="color:#719e07">(</span>T proxy<span style="color:#719e07">,</span> Class<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> type<span style="color:#719e07">,</span> URL url<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RpcException <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.rpc.ProxyFactory:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxProxyFactory</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: Readiness 就绪探针</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/readiness/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/readiness/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>拓展应用就绪的检测点。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <p><code>org.apache.dubbo.qos.probe.ReadinessProbe</code></p> |
| <h2 id="扩展配置">扩展配置</h2> |
| <p>Dubbo QOS <code>ready</code> 命令自动发现</p> |
| <h2 id="已知扩展">已知扩展</h2> |
| <ul> |
| <li><code>org.apache.dubbo.qos.probe.impl.BootstrapReadinessProbe</code></li> |
| <li><code>org.apache.dubbo.qos.probe.impl.ProviderReadinessProbe</code></li> |
| </ul> |
| <h2 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxReadinessProbe.java (实现ReadinessProbe接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.qos.probe.ReadinessProbe (纯文本文件,内容为:xxx=com.xxx.XxxReadinessProbe) |
| </span></span></code></pre></div><p>XxxReadinessProbe.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxReadinessProbe</span> <span style="color:#268bd2">implements</span> ReadinessProbe <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">boolean</span> <span style="color:#268bd2">check</span><span style="color:#719e07">()</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.qos.probe.ReadinessProbe:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>xxx=com.xxx.XxxReadinessProbe |
| </span></span></code></pre></div></description></item><item><title>Overview: Startup 启动探针</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/startup/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/startup/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>拓展应用启动的检测点。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <p><code>org.apache.dubbo.qos.probe.StartupProbe</code></p> |
| <h2 id="扩展配置">扩展配置</h2> |
| <p>Dubbo QOS <code>startup</code> 命令自动发现</p> |
| <h2 id="已知扩展">已知扩展</h2> |
| <ul> |
| <li><code>org.apache.dubbo.qos.probe.impl.BootstrapLivenessProbe</code></li> |
| </ul> |
| <h2 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxStartupProbe.java (实现StartupProbe接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.qos.probe.StartupProbe (纯文本文件,内容为:xxx=com.xxx.XxxStartupProbe) |
| </span></span></code></pre></div><p>XxxStartupProbee.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxStartupProbe</span> <span style="color:#268bd2">implements</span> StartupProbe <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">boolean</span> <span style="color:#268bd2">check</span><span style="color:#719e07">()</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.qos.probe.StartupProbe:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>xxx=com.xxx.XxxStartupProbe |
| </span></span></code></pre></div></description></item><item><title>Overview: 编译器扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/compiler/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/compiler/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>Java 代码编译器,用于动态生成字节码,加速调用。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <p><code>org.apache.dubbo.common.compiler.Compiler</code></p> |
| <h2 id="扩展配置">扩展配置</h2> |
| <p>自动加载</p> |
| <h2 id="已知扩展">已知扩展</h2> |
| <ul> |
| <li><code>org.apache.dubbo.common.compiler.support.JdkCompiler</code></li> |
| <li><code>org.apache.dubbo.common.compiler.support.JavassistCompiler</code></li> |
| </ul> |
| <h2 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxCompiler.java (实现Compiler接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.common.compiler.Compiler (纯文本文件,内容为:xxx=com.xxx.XxxCompiler) |
| </span></span></code></pre></div><p>XxxCompiler.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.common.compiler.Compiler<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxCompiler</span> <span style="color:#268bd2">implements</span> Compiler <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> Object <span style="color:#268bd2">getExtension</span><span style="color:#719e07">(</span>Class<span style="color:#719e07">&lt;?&gt;</span> type<span style="color:#719e07">,</span> String name<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.common.compiler.Compiler:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxCompiler</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: 配置中心扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/config-center/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/config-center/</guid><description> |
| <h2 id="设计目的">设计目的</h2> |
| <p>配置中心的核心功能是作为 Key-Value 存储,Dubbo 框架告知配置中心其关心的 key,配置中心返回该key对应的 value 值。</p> |
| <p>按照应用场景划分,配置中心在 Dubbo 框架中主要承担以下职责:</p> |
| <ul> |
| <li>作为外部化配置中心,即存储 dubbo.properties 配置文件,此时,key 值通常为文件名如 dubbo.properties,value 则为配置文件内容。</li> |
| <li>存储单个配置项,如各种开关项、常量值等。</li> |
| <li>存储服务治理规则,此时key通常按照 &ldquo;服务名+规则类型&rdquo; 的格式来组织,而 value 则为具体的治理规则。</li> |
| </ul> |
| <p>为了进一步实现对 key-value 的分组管理,Dubbo 的配置中心还加入了 namespace、group 的概念,这些概念在很多专业的第三方配置中心中都有体现,通常情况下,namespace 用来隔离不同的租户,group 用来对同一租户的key集合做分组。</p> |
| <p>当前,Dubbo 配置中心实现了对 Zookeeper、Nacos、Etcd、Consul、Apollo 的对接,接下来我们具体看一下 Dubbo 抽象的配置中心是怎么映射到具体的第三方实现中的。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <ul> |
| <li><code>org.apache.dubbo.configcenter.DynamicConfigurationFactory</code></li> |
| <li><code>org.apache.dubbo.configcenter.DynamicConfiguration</code></li> |
| </ul> |
| <h2 id="已知扩展">已知扩展</h2> |
| <ul> |
| <li><code>org.apache.dubbo.configcenter.support.zookeeper.ZookeeperDynamicConfigurationFactory</code></li> |
| <li><code>org.apache.dubbo.configcenter.support.nacos.NacosDynamicConfigurationFactory</code></li> |
| <li><code>org.apache.dubbo.configcenter.support.etcd.EtcdDynamicConfigurationFactory</code></li> |
| <li><code>org.apache.dubbo.configcenter.consul.ConsulDynamicConfigurationFactory</code></li> |
| <li><code>org.apache.dubbo.configcenter.support.apollo.ApolloDynamicConfigurationFactory</code></li> |
| <li><code>org.apache.dubbo.common.config.configcenter.file.FileSystemDynamicConfigurationFactory</code></li> |
| </ul> |
| <h2 id="实现原理">实现原理</h2> |
| <h3 id="zookeeper">Zookeeper</h3> |
| <p>zookeeper提供了一个树状的存储模型,其实现原理如下:</p> |
| <p><img src="https://dubbo.apache.org/imgs/dev/configcenter_zk_model.jpg" alt="image-20190127225608553"></p> |
| <p>namespace, group, key 等分别对应不同层级的 ZNode 节点,而 value 则作为根 ZNode 节点的值存储。</p> |
| <ol> |
| <li> |
| <p>外部化配置中心 dubbo.properties</p> |
| <p><img src="https://dubbo.apache.org/imgs/dev/configcenter_zk_properties.jpg" alt="image-20190127225608553"></p> |
| <p>上图展示了两个不同作用域的 dubbo.properties 文件在 zookeeper 中的存储结构:</p> |
| <ul> |
| <li>命名空间namespace都为:dubbo</li> |
| <li>分组 group:全局级别为 dubbo,所有应用共享;应用级别为应用名 demo-provider,只对该应用生效</li> |
| <li>key:dubbo.properties</li> |
| </ul> |
| </li> |
| <li> |
| <p>单个配置项</p> |
| <p><img src="https://dubbo.apache.org/imgs/dev/configcenter_zk_singleitem.jpg" alt="image-20190127225608553"></p> |
| <p>设置优雅停机事件为15000:</p> |
| <ul> |
| <li>命名空间 namespace:dubbo</li> |
| <li>分组 group:dubbo</li> |
| <li>key:dubbo.service.shutdown.wait</li> |
| <li>value:15000</li> |
| </ul> |
| </li> |
| <li> |
| <p>服务治理规则</p> |
| <p><img src="https://dubbo.apache.org/imgs/dev/configcenter_zk_rule.jpg" alt="image-20190127225608553"></p> |
| <p>上图展示了一条应用级别的条件路由规则:</p> |
| <ul> |
| <li>命名空间 namespace:dubbo</li> |
| <li>分组 group:dubbo</li> |
| <li>key:governance-conditionrouter-consumer.condition-router,其中 governance-conditionrouter-consumer 为应用名,condition-router 代表条件路由</li> |
| </ul> |
| <blockquote> |
| <p>注意:</p> |
| <p>Dubbo同时支持应用、服务两种粒度的服务治理规则,对于这两种粒度,其key取值规则如下:</p> |
| <ul> |
| <li>应用粒度 {应用名 + 规则后缀}。如: <code>demo-application.configurators</code>、<code>demo-application.tag-router</code>等</li> |
| <li>服务粒度 {服务接口名:[服务版本]:[服务分组] + 规则后缀},其中服务版本、服务分组是可选的,如果它们有配置则在key中体现,没被配置则用&quot;:&ldquo;占位。如 |
| <code>org.apache.dubbo.demo.DemoService::.configurators</code>、<code>org.apache.dubbo.demo.DemoService:1.0.0:group1.configurators</code></li> |
| </ul> |
| </blockquote> |
| </li> |
| </ol> |
| <h3 id="etcd--consul">Etcd &amp; Consul</h3> |
| <p>Etcd 和 Consul 本质上也是一种类似 zookeeper 的树状存储结构,实现请参考 zookeeper。</p> |
| <h3 id="nacos">Nacos</h3> |
| <p>Nacos 作为一个专业的第三方配置中心,拥有专门为配置中心设计的存储结构,包括内置的 namespace、group、dataid 等概念。并且这几个概念基本上与 Dubbo 框架抽象的配置中心是一一对应的。</p> |
| <p>与 Zookeeper 实现的对应关系如下:</p> |
| <p><img src="https://dubbo.apache.org/imgs/dev/configcenter_nacos_model.jpg" alt="image-20190127225608553"></p> |
| <p>参考上文关于 zookeeper 实现中描述的示例,这里的 dataid 可能为:</p> |
| <ul> |
| <li>外部化配置中心:dubbo.properties</li> |
| <li>单个配置项:dubbo.service.shutdown.wait</li> |
| <li>服务治理规则:org.apache.dubbo.demo.DemoService:1.0.0:group1.configurators</li> |
| </ul> |
| <h3 id="apollo">Apollo</h3> |
| <p>Apollo 与 Nacos 类似,请参考动态配置中心使用文档中关于 Apollo 部分的描述。</p></description></item><item><title>Overview: 元数据中心扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/metadata-report/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/metadata-report/</guid><description> |
| <h2 id="设计目的">设计目的</h2> |
| <p>请参见 <a href="../../../metadata-center/overview/">元数据中心手册</a></p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <ul> |
| <li><code>org.apache.dubbo.metadata.store.MetadataReportFactory</code></li> |
| <li><code>org.apache.dubbo.metadata.store.MetadataReport</code></li> |
| </ul> |
| <h2 id="已知扩展">已知扩展</h2> |
| <h2 id="实现原理">实现原理</h2> |
| <h3 id="spi定义">SPI定义</h3> |
| <p>参考:org.apache.dubbo.metadata.store.MetadataReportFactory,org.apache.dubbo.metadata.store.MetadataReport</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">@SPI</span><span style="color:#719e07">(</span><span style="color:#2aa198">&#34;redis&#34;</span><span style="color:#719e07">)</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">interface</span> <span style="color:#268bd2">MetadataReportFactory</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Adaptive</span><span style="color:#719e07">({</span><span style="color:#2aa198">&#34;protocol&#34;</span><span style="color:#719e07">})</span> |
| </span></span><span style="display:flex;"><span> MetadataReport <span style="color:#268bd2">getMetadataReport</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><h3 id="自定义元数据的存储">自定义元数据的存储</h3> |
| <p>下面以Redis存储为例进行说明。</p> |
| <p>新建一个project,需要支持以下修改:</p> |
| <h4 id="扩展abstractmetadatareport">扩展AbstractMetadataReport</h4> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">RedisMetadataReport</span> <span style="color:#268bd2">extends</span> AbstractMetadataReport <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">private</span> <span style="color:#268bd2">final</span> <span style="color:#268bd2">static</span> Logger logger <span style="color:#719e07">=</span> LoggerFactory<span style="color:#719e07">.</span>getLogger<span style="color:#719e07">(</span>RedisMetadataReport<span style="color:#719e07">.</span>class<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">final</span> JedisPool pool<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">RedisMetadataReport</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">super</span><span style="color:#719e07">(</span>url<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> pool <span style="color:#719e07">=</span> <span style="color:#719e07">new</span> JedisPool<span style="color:#719e07">(</span><span style="color:#719e07">new</span> JedisPoolConfig<span style="color:#719e07">(),</span> url<span style="color:#719e07">.</span>getHost<span style="color:#719e07">(),</span> url<span style="color:#719e07">.</span>getPort<span style="color:#719e07">());</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">protected</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">doStoreProviderMetadata</span><span style="color:#719e07">(</span>ProviderMetadataIdentifier providerMetadataIdentifier<span style="color:#719e07">,</span> String serviceDefinitions<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">this</span><span style="color:#719e07">.</span>storeMetadata<span style="color:#719e07">(</span>providerMetadataIdentifier<span style="color:#719e07">,</span> serviceDefinitions<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">protected</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">doStoreConsumerMetadata</span><span style="color:#719e07">(</span>ConsumerMetadataIdentifier consumerMetadataIdentifier<span style="color:#719e07">,</span> String value<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">this</span><span style="color:#719e07">.</span>storeMetadata<span style="color:#719e07">(</span>consumerMetadataIdentifier<span style="color:#719e07">,</span> value<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">private</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">storeMetadata</span><span style="color:#719e07">(</span>MetadataIdentifier metadataIdentifier<span style="color:#719e07">,</span> String v<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">try</span> <span style="color:#719e07">(</span>Jedis jedis <span style="color:#719e07">=</span> pool<span style="color:#719e07">.</span>getResource<span style="color:#719e07">())</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> jedis<span style="color:#719e07">.</span>set<span style="color:#719e07">(</span>metadataIdentifier<span style="color:#719e07">.</span>getIdentifierKey<span style="color:#719e07">()</span> <span style="color:#719e07">+</span> META_DATA_SOTRE_TAG<span style="color:#719e07">,</span> v<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> <span style="color:#719e07">catch</span> <span style="color:#719e07">(</span>Throwable e<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> logger<span style="color:#719e07">.</span>error<span style="color:#719e07">(</span><span style="color:#2aa198">&#34;Failed to put &#34;</span> <span style="color:#719e07">+</span> metadataIdentifier <span style="color:#719e07">+</span> <span style="color:#2aa198">&#34; to redis &#34;</span> <span style="color:#719e07">+</span> v <span style="color:#719e07">+</span> <span style="color:#2aa198">&#34;, cause: &#34;</span> <span style="color:#719e07">+</span> e<span style="color:#719e07">.</span>getMessage<span style="color:#719e07">(),</span> e<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">throw</span> <span style="color:#719e07">new</span> RpcException<span style="color:#719e07">(</span><span style="color:#2aa198">&#34;Failed to put &#34;</span> <span style="color:#719e07">+</span> metadataIdentifier <span style="color:#719e07">+</span> <span style="color:#2aa198">&#34; to redis &#34;</span> <span style="color:#719e07">+</span> v <span style="color:#719e07">+</span> <span style="color:#2aa198">&#34;, cause: &#34;</span> <span style="color:#719e07">+</span> e<span style="color:#719e07">.</span>getMessage<span style="color:#719e07">(),</span> e<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><h4 id="扩展-abstractmetadatareportfactory">扩展 AbstractMetadataReportFactory</h4> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">RedisMetadataReportFactory</span> <span style="color:#268bd2">extends</span> AbstractMetadataReportFactory <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> MetadataReport <span style="color:#268bd2">createMetadataReport</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#719e07">new</span> RedisMetadataReport<span style="color:#719e07">(</span>url<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><h4 id="增加-metadatareportfactory">增加 MetadataReportFactory</h4> |
| <blockquote> |
| <p>META-INF/dubbo/internal/org.apache.dubbo.metadata.store.MetadataReportFactory</p> |
| </blockquote> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>redis<span style="color:#719e07">=</span><span style="color:#2aa198">org.apache.dubbo.metadata.store.redis.RedisMetadataReportFactory</span> |
| </span></span></code></pre></div><p>只要将上面的修改和project打包成jar包,然后配置元数据中心的url:redis://10.20.153.10:6379。</p> |
| <p>至此,一个自定义的元数据存储就可以运行了。</p></description></item><item><title>Overview: 消息派发扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/dispatcher/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/dispatcher/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>通道信息派发器,用于指定线程池模型。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <p><code>org.apache.dubbo.remoting.Dispatcher</code></p> |
| <h2 id="扩展配置">扩展配置</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:protocol</span> dispatcher=<span style="color:#2aa198">&#34;xxx&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 缺省值设置,当&lt;dubbo:protocol&gt;没有配置dispatcher属性时,使用此配置 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:provider</span> dispatcher=<span style="color:#2aa198">&#34;xxx&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span></code></pre></div><h2 id="已知扩展">已知扩展</h2> |
| <ul> |
| <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 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxDispatcher.java (实现Dispatcher接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.remoting.Dispatcher (纯文本文件,内容为:xxx=com.xxx.XxxDispatcher) |
| </span></span></code></pre></div><p>XxxDispatcher.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.remoting.Dispatcher<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxDispatcher</span> <span style="color:#268bd2">implements</span> Dispatcher <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> Group <span style="color:#268bd2">lookup</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.remoting.Dispatcher:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxDispatcher</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: 线程池扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/threadpool/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/threadpool/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>服务提供方线程池实现策略,当服务器收到一个请求时,需要在线程池中创建一个线程去执行服务提供方业务逻辑。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <p><code>org.apache.dubbo.common.threadpool.ThreadPool</code></p> |
| <h2 id="扩展配置">扩展配置</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:protocol</span> threadpool=<span style="color:#2aa198">&#34;xxx&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 缺省值设置,当&lt;dubbo:protocol&gt;没有配置threadpool时,使用此配置 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:provider</span> threadpool=<span style="color:#2aa198">&#34;xxx&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span></code></pre></div><h2 id="已知扩展">已知扩展</h2> |
| <ul> |
| <li><code>org.apache.dubbo.common.threadpool.FixedThreadPool</code></li> |
| <li><code>org.apache.dubbo.common.threadpool.CachedThreadPool</code></li> |
| </ul> |
| <h2 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxThreadPool.java (实现ThreadPool接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.common.threadpool.ThreadPool (纯文本文件,内容为:xxx=com.xxx.XxxThreadPool) |
| </span></span></code></pre></div><p>XxxThreadPool.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.common.threadpool.ThreadPool<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> java.util.concurrent.Executor<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxThreadPool</span> <span style="color:#268bd2">implements</span> ThreadPool <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> Executor <span style="color:#268bd2">getExecutor</span><span style="color:#719e07">()</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.common.threadpool.ThreadPool:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxThreadPool</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: 序列化扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/serialize/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/serialize/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>将对象转成字节流,用于网络传输,以及将字节流转为对象,用于在收到字节流数据后还原成对象。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <ul> |
| <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 id="扩展配置">扩展配置</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 协议的序列化方式 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:protocol</span> serialization=<span style="color:#2aa198">&#34;xxx&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 缺省值设置,当&lt;dubbo:protocol&gt;没有配置serialization时,使用此配置 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:provider</span> serialization=<span style="color:#2aa198">&#34;xxx&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span></code></pre></div><h2 id="已知扩展">已知扩展</h2> |
| <ul> |
| <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 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxSerialization.java (实现Serialization接口) |
| </span></span><span style="display:flex;"><span> |-XxxObjectInput.java (实现ObjectInput接口) |
| </span></span><span style="display:flex;"><span> |-XxxObjectOutput.java (实现ObjectOutput接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.common.serialize.Serialization (纯文本文件,内容为:xxx=com.xxx.XxxSerialization) |
| </span></span></code></pre></div><p>XxxSerialization.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.common.serialize.Serialization<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.common.serialize.ObjectInput<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.common.serialize.ObjectOutput<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxSerialization</span> <span style="color:#268bd2">implements</span> Serialization <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> ObjectOutput <span style="color:#268bd2">serialize</span><span style="color:#719e07">(</span>Parameters parameters<span style="color:#719e07">,</span> OutputStream output<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> IOException <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#719e07">new</span> XxxObjectOutput<span style="color:#719e07">(</span>output<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> ObjectInput <span style="color:#268bd2">deserialize</span><span style="color:#719e07">(</span>Parameters parameters<span style="color:#719e07">,</span> InputStream input<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> IOException <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#719e07">new</span> XxxObjectInput<span style="color:#719e07">(</span>input<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.common.serialize.Serialization:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxSerialization</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: 网络传输扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/remoting/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/remoting/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>远程通讯的服务器及客户端传输实现。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <ul> |
| <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 id="扩展配置">扩展配置</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 服务器和客户端使用相同的传输实现 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:protocol</span> transporter=<span style="color:#2aa198">&#34;xxx&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 服务器和客户端使用不同的传输实现 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:protocol</span> server=<span style="color:#2aa198">&#34;xxx&#34;</span> client=<span style="color:#2aa198">&#34;xxx&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 缺省值设置,当&lt;dubbo:protocol&gt;没有配置transporter/server/client属性时,使用此配置 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:provider</span> transporter=<span style="color:#2aa198">&#34;xxx&#34;</span> server=<span style="color:#2aa198">&#34;xxx&#34;</span> client=<span style="color:#2aa198">&#34;xxx&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span></code></pre></div><h2 id="已知扩展">已知扩展</h2> |
| <ul> |
| <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 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxTransporter.java (实现Transporter接口) |
| </span></span><span style="display:flex;"><span> |-XxxServer.java (实现Server接口) |
| </span></span><span style="display:flex;"><span> |-XxxClient.java (实现Client接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.remoting.Transporter (纯文本文件,内容为:xxx=com.xxx.XxxTransporter) |
| </span></span></code></pre></div><p>XxxTransporter.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.remoting.Transporter<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxTransporter</span> <span style="color:#268bd2">implements</span> Transporter <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> Server <span style="color:#268bd2">bind</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">,</span> ChannelHandler handler<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RemotingException <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#719e07">new</span> XxxServer<span style="color:#719e07">(</span>url<span style="color:#719e07">,</span> handler<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> Client <span style="color:#268bd2">connect</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">,</span> ChannelHandler handler<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RemotingException <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#719e07">new</span> XxxClient<span style="color:#719e07">(</span>url<span style="color:#719e07">,</span> handler<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>XxxServer.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.remoting.transport.transporter.AbstractServer<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxServer</span> <span style="color:#268bd2">extends</span> AbstractServer <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">XxxServer</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">,</span> ChannelHandler handler<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RemotingException<span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">super</span><span style="color:#719e07">(</span>url<span style="color:#719e07">,</span> handler<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">protected</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">doOpen</span><span style="color:#719e07">()</span> <span style="color:#268bd2">throws</span> Throwable <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">protected</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">doClose</span><span style="color:#719e07">()</span> <span style="color:#268bd2">throws</span> Throwable <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> Collection<span style="color:#719e07">&lt;</span>Channel<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">getChannels</span><span style="color:#719e07">()</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> Channel <span style="color:#268bd2">getChannel</span><span style="color:#719e07">(</span>InetSocketAddress remoteAddress<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>XxxClient.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.remoting.transport.transporter.AbstractClient<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxClient</span> <span style="color:#268bd2">extends</span> AbstractClient <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">XxxServer</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">,</span> ChannelHandler handler<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RemotingException<span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">super</span><span style="color:#719e07">(</span>url<span style="color:#719e07">,</span> handler<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">protected</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">doOpen</span><span style="color:#719e07">()</span> <span style="color:#268bd2">throws</span> Throwable <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">protected</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">doClose</span><span style="color:#719e07">()</span> <span style="color:#268bd2">throws</span> Throwable <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">protected</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">doConnect</span><span style="color:#719e07">()</span> <span style="color:#268bd2">throws</span> Throwable <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> Channel <span style="color:#268bd2">getChannel</span><span style="color:#719e07">()</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.remoting.Transporter:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxTransporter</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: 信息交换扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/exchanger/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/exchanger/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>基于传输层之上,实现 Request-Response 信息交换语义。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <ul> |
| <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 id="扩展配置">扩展配置</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:protocol</span> exchanger=<span style="color:#2aa198">&#34;xxx&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 缺省值设置,当&lt;dubbo:protocol&gt;没有配置exchanger属性时,使用此配置 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:provider</span> exchanger=<span style="color:#2aa198">&#34;xxx&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span></code></pre></div><h2 id="已知扩展">已知扩展</h2> |
| <p><code>org.apache.dubbo.remoting.exchange.exchanger.HeaderExchanger</code></p> |
| <h2 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxExchanger.java (实现Exchanger接口) |
| </span></span><span style="display:flex;"><span> |-XxxExchangeServer.java (实现ExchangeServer接口) |
| </span></span><span style="display:flex;"><span> |-XxxExchangeClient.java (实现ExchangeClient接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.remoting.exchange.Exchanger (纯文本文件,内容为:xxx=com.xxx.XxxExchanger) |
| </span></span></code></pre></div><p>XxxExchanger.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.remoting.exchange.Exchanger<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxExchanger</span> <span style="color:#268bd2">implements</span> Exchanger <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> ExchangeServer <span style="color:#268bd2">bind</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">,</span> ExchangeHandler handler<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RemotingException <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#719e07">new</span> XxxExchangeServer<span style="color:#719e07">(</span>url<span style="color:#719e07">,</span> handler<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> ExchangeClient <span style="color:#268bd2">connect</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">,</span> ExchangeHandler handler<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RemotingException <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#719e07">new</span> XxxExchangeClient<span style="color:#719e07">(</span>url<span style="color:#719e07">,</span> handler<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>XxxExchangeServer.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.remoting.exchange.ExchangeServer<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxExchangeServer</span> impelements ExchangeServer <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>XxxExchangeClient.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.remoting.exchange.ExchangeClient<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxExchangeClient</span> impelments ExchangeClient <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.remoting.exchange.Exchanger:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxExchanger</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: 对等网络节点组网器扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/page/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/page/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>对等网络节点组网器。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <p><code>org.apache.dubbo.container.page.PageHandler</code></p> |
| <h2 id="扩展配置">扩展配置</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:protocol</span> page=<span style="color:#2aa198">&#34;xxx,yyy&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 缺省值设置,当&lt;dubbo:protocol&gt;没有配置page属性时,使用此配置 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:provider</span> page=<span style="color:#2aa198">&#34;xxx,yyy&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span></code></pre></div><h2 id="已知扩展">已知扩展</h2> |
| <ul> |
| <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 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxPageHandler.java (实现PageHandler接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.container.page.PageHandler (纯文本文件,内容为:xxx=com.xxx.XxxPageHandler) |
| </span></span></code></pre></div><p>XxxPageHandler.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.container.page.PageHandler<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxPageHandler</span> <span style="color:#268bd2">implements</span> PageHandler <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> Group <span style="color:#268bd2">lookup</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.container.page.PageHandler:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxPageHandler</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: 组网扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/networker/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/networker/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>对等网络节点组网器。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <p><code>org.apache.dubbo.remoting.p2p.Networker</code></p> |
| <h2 id="扩展配置">扩展配置</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:protocol</span> networker=<span style="color:#2aa198">&#34;xxx&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 缺省值设置,当&lt;dubbo:protocol&gt;没有配置networker属性时,使用此配置 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:provider</span> networker=<span style="color:#2aa198">&#34;xxx&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span></code></pre></div><h2 id="已知扩展">已知扩展</h2> |
| <ul> |
| <li><code>org.apache.dubbo.remoting.p2p.support.MulticastNetworker</code></li> |
| <li><code>org.apache.dubbo.remoting.p2p.support.FileNetworker</code></li> |
| </ul> |
| <h2 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxNetworker.java (实现Networker接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.remoting.p2p.Networker (纯文本文件,内容为:xxx=com.xxx.XxxNetworker) |
| </span></span></code></pre></div><p>XxxNetworker.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.remoting.p2p.Networker<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxNetworker</span> <span style="color:#268bd2">implements</span> Networker <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> Group <span style="color:#268bd2">lookup</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.remoting.p2p.Networker:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxNetworker</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: Telnet 命令扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/telnet-handler/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/telnet-handler/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>所有服务器均支持 telnet 访问,用于人工干预。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <p><code>org.apache.dubbo.remoting.telnet.TelnetHandler</code></p> |
| <h2 id="扩展配置">扩展配置</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:protocol</span> telnet=<span style="color:#2aa198">&#34;xxx,yyy&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 缺省值设置,当&lt;dubbo:protocol&gt;没有配置telnet属性时,使用此配置 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:provider</span> telnet=<span style="color:#2aa198">&#34;xxx,yyy&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span></code></pre></div><h2 id="已知扩展">已知扩展</h2> |
| <ul> |
| <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 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxTelnetHandler.java (实现TelnetHandler接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.remoting.telnet.TelnetHandler (纯文本文件,内容为:xxx=com.xxx.XxxTelnetHandler) |
| </span></span></code></pre></div><p>XxxTelnetHandler.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.remoting.telnet.TelnetHandler<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">@Help</span><span style="color:#719e07">(</span>parameter<span style="color:#719e07">=</span><span style="color:#2aa198">&#34;...&#34;</span><span style="color:#719e07">,</span> summary<span style="color:#719e07">=</span><span style="color:#2aa198">&#34;...&#34;</span><span style="color:#719e07">,</span> detail<span style="color:#719e07">=</span><span style="color:#2aa198">&#34;...&#34;</span><span style="color:#719e07">)</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxTelnetHandler</span> <span style="color:#268bd2">implements</span> TelnetHandler <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> String <span style="color:#268bd2">telnet</span><span style="color:#719e07">(</span>Channel channel<span style="color:#719e07">,</span> String message<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RemotingException <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.remoting.telnet.TelnetHandler:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxTelnetHandler</span> |
| </span></span></code></pre></div><h2 id="命令用法">命令用法</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>telnet 127.0.0.1 <span style="color:#2aa198">20880</span> |
| </span></span><span style="display:flex;"><span>dubbo&gt; xxx args |
| </span></span></code></pre></div></description></item><item><title>Overview: 状态检查扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/status-checker/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/status-checker/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>检查服务依赖各种资源的状态,此状态检查可同时用于 telnet 的 status 命令和 hosting 的 status 页面。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <p><code>org.apache.dubbo.common.status.StatusChecker</code></p> |
| <h2 id="扩展配置">扩展配置</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:protocol</span> status=<span style="color:#2aa198">&#34;xxx,yyy&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 缺省值设置,当&lt;dubbo:protocol&gt;没有配置status属性时,使用此配置 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:provider</span> status=<span style="color:#2aa198">&#34;xxx,yyy&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span></code></pre></div><h2 id="已知扩展">已知扩展</h2> |
| <ul> |
| <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 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxStatusChecker.java (实现StatusChecker接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.common.status.StatusChecker (纯文本文件,内容为:xxx=com.xxx.XxxStatusChecker) |
| </span></span></code></pre></div><p>XxxStatusChecker.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.common.status.StatusChecker<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxStatusChecker</span> <span style="color:#268bd2">implements</span> StatusChecker <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> Status <span style="color:#268bd2">check</span><span style="color:#719e07">()</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.common.status.StatusChecker:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxStatusChecker</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: 容器扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/container/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/container/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>服务容器扩展,用于自定义加载内容。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <p><code>org.apache.dubbo.container.Container</code></p> |
| <h2 id="扩展配置">扩展配置</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>java org.apache.dubbo.container.Main spring jetty log4j |
| </span></span></code></pre></div><h2 id="已知扩展">已知扩展</h2> |
| <ul> |
| <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 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxContainer.java (实现Container接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.container.Container (纯文本文件,内容为:xxx=com.xxx.XxxContainer) |
| </span></span></code></pre></div><p>XxxContainer.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span>org<span style="color:#719e07">.</span>apache<span style="color:#719e07">.</span>dubbo<span style="color:#719e07">.</span>container<span style="color:#719e07">.</span>Container<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxContainer</span> <span style="color:#268bd2">implements</span> Container <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> Status <span style="color:#268bd2">start</span><span style="color:#719e07">()</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> Status <span style="color:#268bd2">stop</span><span style="color:#719e07">()</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.container.Container:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxContainer</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: 缓存扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/cache/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/cache/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>用请求参数作为 key,缓存返回结果。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <p><code>org.apache.dubbo.cache.CacheFactory</code></p> |
| <h2 id="扩展配置">扩展配置</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:service</span> cache=<span style="color:#2aa198">&#34;lru&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 方法级缓存 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:service&gt;&lt;dubbo:method</span> cache=<span style="color:#2aa198">&#34;lru&#34;</span> <span style="color:#268bd2">/&gt;&lt;/dubbo:service&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 缺省值设置,当&lt;dubbo:service&gt;没有配置cache属性时,使用此配置 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:provider</span> cache=<span style="color:#2aa198">&#34;xxx,yyy&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span></code></pre></div><h2 id="已知扩展">已知扩展</h2> |
| <ul> |
| <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 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxCacheFactory.java (实现CacheFactory接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.cache.CacheFactory (纯文本文件,内容为:xxx=com.xxx.XxxCacheFactory) |
| </span></span></code></pre></div><p>XxxCacheFactory.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.cache.CacheFactory<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxCacheFactory</span> <span style="color:#268bd2">implements</span> CacheFactory <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> Cache <span style="color:#268bd2">getCache</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">,</span> String name<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#719e07">new</span> XxxCache<span style="color:#719e07">(</span>url<span style="color:#719e07">,</span> name<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>XxxCache.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.cache.Cache<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxCache</span> <span style="color:#268bd2">implements</span> Cache <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">Cache</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">,</span> String name<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">put</span><span style="color:#719e07">(</span>Object key<span style="color:#719e07">,</span> Object value<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> Object <span style="color:#268bd2">get</span><span style="color:#719e07">(</span>Object key<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.cache.CacheFactory:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxCacheFactory</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: 验证扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/validation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/validation/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>参数验证扩展点。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <p><code>org.apache.dubbo.validation.Validation</code></p> |
| <h2 id="扩展配置">扩展配置</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:service</span> validation=<span style="color:#2aa198">&#34;xxx,yyy&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#586e75">&lt;!-- 缺省值设置,当&lt;dubbo:service&gt;没有配置validation属性时,使用此配置 --&gt;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:provider</span> validation=<span style="color:#2aa198">&#34;xxx,yyy&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span></code></pre></div><h2 id="已知扩展">已知扩展</h2> |
| <p><code>org.apache.dubbo.validation.support.jvalidation.JValidation</code></p> |
| <h2 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxValidation.java (实现Validation接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.validation.Validation (纯文本文件,内容为:xxx=com.xxx.XxxValidation) |
| </span></span></code></pre></div><p>XxxValidation.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.validation.Validation<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxValidation</span> <span style="color:#268bd2">implements</span> Validation <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> Object <span style="color:#268bd2">getValidator</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>XxxValidator.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.validation.Validator<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxValidator</span> <span style="color:#268bd2">implements</span> Validator <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">XxxValidator</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">validate</span><span style="color:#719e07">(</span>Invocation invocation<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> Exception <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.validation.Validation:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxValidation</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: 日志适配扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/logger-adapter/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/logger-adapter/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>日志输出适配扩展点。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <p><code>org.apache.dubbo.common.logger.LoggerAdapter</code></p> |
| <h2 id="扩展配置">扩展配置</h2> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#268bd2">&lt;dubbo:application</span> logger=<span style="color:#2aa198">&#34;xxx&#34;</span> <span style="color:#268bd2">/&gt;</span> |
| </span></span></code></pre></div><p>或者:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>-Ddubbo:application.logger<span style="color:#719e07">=</span>xxx |
| </span></span></code></pre></div><h2 id="已知扩展">已知扩展</h2> |
| <ul> |
| <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 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxLoggerAdapter.java (实现LoggerAdapter接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.common.logger.LoggerAdapter (纯文本文件,内容为:xxx=com.xxx.XxxLoggerAdapter) |
| </span></span></code></pre></div><p>XxxLoggerAdapter.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.common.logger.LoggerAdapter<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxLoggerAdapter</span> <span style="color:#268bd2">implements</span> LoggerAdapter <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> Logger <span style="color:#268bd2">getLogger</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>XxxLogger.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.common.logger.Logger<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxLogger</span> <span style="color:#268bd2">implements</span> Logger <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#268bd2">XxxLogger</span><span style="color:#719e07">(</span>URL url<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">info</span><span style="color:#719e07">(</span>String msg<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.common.logger.LoggerAdapter:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>xxx<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxLoggerAdapter</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: QoS匿名访问权限验证扩展</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/qos-permission/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/qos-permission/</guid><description> |
| <h2 id="扩展说明">扩展说明</h2> |
| <p>QoS匿名访问权限验证扩展点。</p> |
| <h2 id="扩展接口">扩展接口</h2> |
| <p><code>org.apache.dubbo.qos.permission.PermissionChecker</code></p> |
| <h2 id="扩展配置">扩展配置</h2> |
| <p>Dubbo QoS <code>dubbo.application.qos-anonymous-access-permission-level</code> 匿名访问权限校验。</p> |
| <h2 id="默认实现">默认实现</h2> |
| <p><code>org.apache.dubbo.qos.permission.DefaultAnonymousAccessPermissionChecker</code></p> |
| <h2 id="扩展示例">扩展示例</h2> |
| <p>Maven 项目结构:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>src |
| </span></span><span style="display:flex;"><span> |-main |
| </span></span><span style="display:flex;"><span> |-java |
| </span></span><span style="display:flex;"><span> |-com |
| </span></span><span style="display:flex;"><span> |-xxx |
| </span></span><span style="display:flex;"><span> |-XxxPermissionChecker.java (实现PermissionChecker接口) |
| </span></span><span style="display:flex;"><span> |-resources |
| </span></span><span style="display:flex;"><span> |-META-INF |
| </span></span><span style="display:flex;"><span> |-dubbo |
| </span></span><span style="display:flex;"><span> |-org.apache.dubbo.qos.permission.PermissionChecker` (纯文本文件,内容为:qosPermissionChecker=com.xxx.XxxPermissionChecker) |
| </span></span></code></pre></div><p>XxxPermissionChecker.java:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> com.xxx.qos.permission<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.qos.permission.PermissionChecker<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">XxxAnonymousAccessPermissionChecker</span> <span style="color:#268bd2">implements</span> PermissionChecker <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">boolean</span> <span style="color:#268bd2">access</span><span style="color:#719e07">(</span>CommandContext commandContext<span style="color:#719e07">,</span> PermissionLevel defaultCmdRequiredPermissionLevel<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// ... |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>META-INF/dubbo/org.apache.dubbo.qos.permission.PermissionChecker:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-properties" data-lang="properties"><span style="display:flex;"><span>qosPermissionChecker<span style="color:#719e07">=</span><span style="color:#2aa198">com.xxx.XxxPermissionChecker</span> |
| </span></span></code></pre></div></description></item><item><title>Overview: 扩展点开发指南</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/dubbo-spi/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/dubbo-spi/</guid><description> |
| <h2 id="1-dubbo-spi-扩展简介">1. Dubbo SPI 扩展简介</h2> |
| <p>SPI 全称为 Service Provider Interface,是一种服务发现机制。SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口替换实现类。正因此特性,我们可以很容易的通过 SPI 机制为我们的程序提供拓展功能。SPI 机制在第三方框架中也有所应用,比如 Dubbo 就是通过 SPI 机制加载所有的组件。不过,Dubbo 并未使用 Java 原生的 SPI 机制,而是对其进行了增强,使其能够更好的满足需求。在 Dubbo 中,SPI 是一个非常重要的模块。基于 SPI,我们可以很容易的对 Dubbo 进行拓展。 |
| Dubbo 中,SPI 主要有两种用法,一种是加载固定的扩展类,另一种是加载自适应扩展类。这两种方式会在下面详细的介绍。 |
| 需要特别注意的是: 在 Dubbo 中,基于 SPI 扩展加载的类是单例的。</p> |
| <h3 id="11-加载固定的扩展类">1.1 加载固定的扩展类</h3> |
| <p>如果让你来设计加载固定扩展类,你会怎么做了? |
| 一种常见思路是读取特定目录下的配置文件,然后解析出全类名,通过反射机制来实例化这个类,然后将这个类放在集合中存起来,如果有需要的时候,直接从集合中取。Dubbo 中的实现也是这么一个思路。 |
| 不过在 Dubbo 中,实现的更加完善,它实现类了 IOC 和 AOP 的功能。IOC 就是说如果这个扩展类依赖其他属性,Dubbo 会自动的将这个属性进行注入。这个功能如何实现了?一个常见思路是获取这个扩展类的 setter |
| 方法,调用 setter 方法进行属性注入。AOP 指的是什么了?这个说的是 Dubbo 能够为扩展类注入其包装类。比如 DubboProtocol 是 Protocol 的扩展类,ProtocolListenerWrapper 是 DubboProtocol 的包装类。</p> |
| <h3 id="12-加载自适应扩展类">1.2 加载自适应扩展类</h3> |
| <p>先说明下自适应扩展类的使用场景。比如我们有需求,在调用某一个方法时,基于参数选择调用到不同的实现类。和工厂方法有些类似,基于不同的参数,构造出不同的实例对象。 |
| 在 Dubbo 中实现的思路和这个差不多,不过 Dubbo 的实现更加灵活,它的实现和策略模式有些类似。每一种扩展类相当于一种策略,基于 URL 消息总线,将参数传递给 ExtensionLoader,通过 ExtensionLoader 基于参数加载对应的扩展类,实现运行时动态调用到目标实例上。</p> |
| <h2 id="2-dubbo-spi-源码分析">2. Dubbo SPI 源码分析</h2> |
| <h3 id="21-加载固定的扩展类">2.1 加载固定的扩展类</h3> |
| <p>Dubbo 中,SPI 加载固定扩展类的入口是 ExtensionLoader 的 getExtension 方法,下面我们对拓展类对象的获取过程进行详细的分析。</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">public</span> T <span style="color:#268bd2">getExtension</span><span style="color:#719e07">(</span>String name<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>name <span style="color:#719e07">==</span> <span style="color:#cb4b16">null</span> <span style="color:#719e07">||</span> name<span style="color:#719e07">.</span>length<span style="color:#719e07">()</span> <span style="color:#719e07">==</span> 0<span style="color:#719e07">)</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">throw</span> <span style="color:#719e07">new</span> IllegalArgumentException<span style="color:#719e07">(</span><span style="color:#2aa198">&#34;Extension name == null&#34;</span><span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span><span style="color:#2aa198">&#34;true&#34;</span><span style="color:#719e07">.</span>equals<span style="color:#719e07">(</span>name<span style="color:#719e07">))</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 获取默认的拓展实现类 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">return</span> getDefaultExtension<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// Holder,顾名思义,用于持有目标对象 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> Holder<span style="color:#719e07">&lt;</span>Object<span style="color:#719e07">&gt;</span> holder <span style="color:#719e07">=</span> cachedInstances<span style="color:#719e07">.</span>get<span style="color:#719e07">(</span>name<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 这段逻辑保证了只有一个线程能够创建 Holder 对象 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>holder <span style="color:#719e07">==</span> <span style="color:#cb4b16">null</span><span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> cachedInstances<span style="color:#719e07">.</span>putIfAbsent<span style="color:#719e07">(</span>name<span style="color:#719e07">,</span> <span style="color:#719e07">new</span> Holder<span style="color:#719e07">&lt;</span>Object<span style="color:#719e07">&gt;());</span> |
| </span></span><span style="display:flex;"><span> holder <span style="color:#719e07">=</span> cachedInstances<span style="color:#719e07">.</span>get<span style="color:#719e07">(</span>name<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> Object instance <span style="color:#719e07">=</span> holder<span style="color:#719e07">.</span>get<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 双重检查 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>instance <span style="color:#719e07">==</span> <span style="color:#cb4b16">null</span><span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">synchronized</span> <span style="color:#719e07">(</span>holder<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> instance <span style="color:#719e07">=</span> holder<span style="color:#719e07">.</span>get<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>instance <span style="color:#719e07">==</span> <span style="color:#cb4b16">null</span><span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 创建拓展实例 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> instance <span style="color:#719e07">=</span> createExtension<span style="color:#719e07">(</span>name<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 设置实例到 holder 中 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> holder<span style="color:#719e07">.</span>set<span style="color:#719e07">(</span>instance<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#719e07">(</span>T<span style="color:#719e07">)</span> instance<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>上面代码的逻辑比较简单,首先检查缓存,缓存未命中则创建拓展对象。下面我们来看一下创建拓展对象的过程是怎样的。</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">private</span> T <span style="color:#268bd2">createExtension</span><span style="color:#719e07">(</span>String name<span style="color:#719e07">,</span> <span style="color:#dc322f">boolean</span> wrap<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 从配置文件中加载所有的拓展类,可得到“配置项名称”到“配置类”的映射关系表 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> Class<span style="color:#719e07">&lt;?&gt;</span> clazz <span style="color:#719e07">=</span> getExtensionClasses<span style="color:#719e07">().</span>get<span style="color:#719e07">(</span>name<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 如果没有该接口的扩展,或者该接口的实现类不允许重复但实际上重复了,直接抛出异常 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>clazz <span style="color:#719e07">==</span> <span style="color:#cb4b16">null</span> <span style="color:#719e07">||</span> unacceptableExceptions<span style="color:#719e07">.</span>contains<span style="color:#719e07">(</span>name<span style="color:#719e07">))</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">throw</span> findException<span style="color:#719e07">(</span>name<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">try</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> T instance <span style="color:#719e07">=</span> <span style="color:#719e07">(</span>T<span style="color:#719e07">)</span> EXTENSION_INSTANCES<span style="color:#719e07">.</span>get<span style="color:#719e07">(</span>clazz<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 这段代码保证了扩展类只会被构造一次,也就是单例的. |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>instance <span style="color:#719e07">==</span> <span style="color:#cb4b16">null</span><span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> EXTENSION_INSTANCES<span style="color:#719e07">.</span>putIfAbsent<span style="color:#719e07">(</span>clazz<span style="color:#719e07">,</span> clazz<span style="color:#719e07">.</span>getDeclaredConstructor<span style="color:#719e07">().</span>newInstance<span style="color:#719e07">());</span> |
| </span></span><span style="display:flex;"><span> instance <span style="color:#719e07">=</span> <span style="color:#719e07">(</span>T<span style="color:#719e07">)</span> EXTENSION_INSTANCES<span style="color:#719e07">.</span>get<span style="color:#719e07">(</span>clazz<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 向实例中注入依赖 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> injectExtension<span style="color:#719e07">(</span>instance<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 如果启用包装的话,则自动为进行包装. |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#586e75">// 比如我基于 Protocol 定义了 DubboProtocol 的扩展,但实际上在 Dubbo 中不是直接使用的 DubboProtocol, 而是其包装类 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#586e75">// ProtocolListenerWrapper |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>wrap<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> List<span style="color:#719e07">&lt;</span>Class<span style="color:#719e07">&lt;?&gt;&gt;</span> wrapperClassesList <span style="color:#719e07">=</span> <span style="color:#719e07">new</span> ArrayList<span style="color:#719e07">&lt;&gt;();</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>cachedWrapperClasses <span style="color:#719e07">!=</span> <span style="color:#cb4b16">null</span><span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> wrapperClassesList<span style="color:#719e07">.</span>addAll<span style="color:#719e07">(</span>cachedWrapperClasses<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> wrapperClassesList<span style="color:#719e07">.</span>sort<span style="color:#719e07">(</span>WrapperComparator<span style="color:#719e07">.</span>COMPARATOR<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> Collections<span style="color:#719e07">.</span>reverse<span style="color:#719e07">(</span>wrapperClassesList<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 循环创建 Wrapper 实例 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>CollectionUtils<span style="color:#719e07">.</span>isNotEmpty<span style="color:#719e07">(</span>wrapperClassesList<span style="color:#719e07">))</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">for</span> <span style="color:#719e07">(</span>Class<span style="color:#719e07">&lt;?&gt;</span> wrapperClass <span style="color:#719e07">:</span> wrapperClassesList<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> Wrapper wrapper <span style="color:#719e07">=</span> wrapperClass<span style="color:#719e07">.</span>getAnnotation<span style="color:#719e07">(</span>Wrapper<span style="color:#719e07">.</span>class<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>wrapper <span style="color:#719e07">==</span> <span style="color:#cb4b16">null</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">||</span> <span style="color:#719e07">(</span>ArrayUtils<span style="color:#719e07">.</span>contains<span style="color:#719e07">(</span>wrapper<span style="color:#719e07">.</span>matches<span style="color:#719e07">(),</span> name<span style="color:#719e07">)</span> <span style="color:#719e07">&amp;&amp;</span> <span style="color:#719e07">!</span>ArrayUtils<span style="color:#719e07">.</span>contains<span style="color:#719e07">(</span>wrapper<span style="color:#719e07">.</span>mismatches<span style="color:#719e07">(),</span> name<span style="color:#719e07">)))</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 将当前 instance 作为参数传给 Wrapper 的构造方法,并通过反射创建 Wrapper 实例。 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#586e75">// 然后向 Wrapper 实例中注入依赖,最后将 Wrapper 实例再次赋值给 instance 变量 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> instance <span style="color:#719e07">=</span> injectExtension<span style="color:#719e07">((</span>T<span style="color:#719e07">)</span> wrapperClass<span style="color:#719e07">.</span>getConstructor<span style="color:#719e07">(</span>type<span style="color:#719e07">).</span>newInstance<span style="color:#719e07">(</span>instance<span style="color:#719e07">));</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 初始化 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> initExtension<span style="color:#719e07">(</span>instance<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> instance<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> <span style="color:#719e07">catch</span> <span style="color:#719e07">(</span>Throwable t<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">throw</span> <span style="color:#719e07">new</span> IllegalStateException<span style="color:#719e07">(</span><span style="color:#2aa198">&#34;Extension instance (name: &#34;</span> <span style="color:#719e07">+</span> name <span style="color:#719e07">+</span> <span style="color:#2aa198">&#34;, class: &#34;</span> <span style="color:#719e07">+</span> |
| </span></span><span style="display:flex;"><span> type <span style="color:#719e07">+</span> <span style="color:#2aa198">&#34;) couldn&#39;t be instantiated: &#34;</span> <span style="color:#719e07">+</span> t<span style="color:#719e07">.</span>getMessage<span style="color:#719e07">(),</span> t<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>createExtension 方法的逻辑稍复杂一下,包含了如下的步骤:</p> |
| <ol> |
| <li>通过 getExtensionClasses 获取所有的拓展类</li> |
| <li>通过反射创建拓展对象</li> |
| <li>向拓展对象中注入依赖</li> |
| <li>将拓展对象包裹在相应的 Wrapper 对象中</li> |
| <li>初始化拓展对象</li> |
| </ol> |
| <p>以上步骤中,第一个步骤是加载拓展类的关键,第三和第四个步骤是 Dubbo IOC 与 AOP 的具体实现。在接下来的章节中,将会重点分析 getExtensionClasses 方法的逻辑,以及简单介绍 Dubbo IOC 的具体实现。</p> |
| <h4 id="211-获取所有的拓展类">2.1.1 获取所有的拓展类</h4> |
| <p>我们在通过名称获取拓展类之前,首先需要根据配置文件解析出拓展项名称到拓展类的映射关系表(Map&lt;名称, 拓展类&gt;),之后再根据拓展项名称从映射关系表中取出相应的拓展类即可。相关过程的代码分析如下:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">private</span> Map<span style="color:#719e07">&lt;</span>String<span style="color:#719e07">,</span> Class<span style="color:#719e07">&lt;?&gt;&gt;</span> getExtensionClasses<span style="color:#719e07">()</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 从缓存中获取已加载的拓展类 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> Map<span style="color:#719e07">&lt;</span>String<span style="color:#719e07">,</span> Class<span style="color:#719e07">&lt;?&gt;&gt;</span> classes <span style="color:#719e07">=</span> cachedClasses<span style="color:#719e07">.</span>get<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 双重检查 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>classes <span style="color:#719e07">==</span> <span style="color:#cb4b16">null</span><span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">synchronized</span> <span style="color:#719e07">(</span>cachedClasses<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> classes <span style="color:#719e07">=</span> cachedClasses<span style="color:#719e07">.</span>get<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>classes <span style="color:#719e07">==</span> <span style="color:#cb4b16">null</span><span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 加载拓展类 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> classes <span style="color:#719e07">=</span> loadExtensionClasses<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> cachedClasses<span style="color:#719e07">.</span>set<span style="color:#719e07">(</span>classes<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> classes<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>这里也是先检查缓存,若缓存未命中,则通过 synchronized 加锁。加锁后再次检查缓存,并判空。此时如果 classes 仍为 null,则通过 loadExtensionClasses 加载拓展类。下面分析 loadExtensionClasses 方法的逻辑。</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">private</span> Map<span style="color:#719e07">&lt;</span>String<span style="color:#719e07">,</span> Class<span style="color:#719e07">&lt;?&gt;&gt;</span> loadExtensionClasses<span style="color:#719e07">()</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 缓存默认的 SPI 扩展名 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> cacheDefaultExtensionName<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> Map<span style="color:#719e07">&lt;</span>String<span style="color:#719e07">,</span> Class<span style="color:#719e07">&lt;?&gt;&gt;</span> extensionClasses <span style="color:#719e07">=</span> <span style="color:#719e07">new</span> HashMap<span style="color:#719e07">&lt;&gt;();</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 基于策略来加载指定文件夹下的文件 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#586e75">// 目前有四种策略,分别读取 META-INF/services/ META-INF/dubbo/ META-INF/dubbo/internal/ META-INF/dubbo/external/ 这四个目录下的配置文件 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">for</span> <span style="color:#719e07">(</span>LoadingStrategy strategy <span style="color:#719e07">:</span> strategies<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> loadDirectory<span style="color:#719e07">(</span>extensionClasses<span style="color:#719e07">,</span> strategy<span style="color:#719e07">.</span>directory<span style="color:#719e07">(),</span> type<span style="color:#719e07">.</span>getName<span style="color:#719e07">(),</span> strategy<span style="color:#719e07">.</span>preferExtensionClassLoader<span style="color:#719e07">(),</span> strategy<span style="color:#719e07">.</span>overridden<span style="color:#719e07">(),</span> strategy<span style="color:#719e07">.</span>excludedPackages<span style="color:#719e07">());</span> |
| </span></span><span style="display:flex;"><span> loadDirectory<span style="color:#719e07">(</span>extensionClasses<span style="color:#719e07">,</span> strategy<span style="color:#719e07">.</span>directory<span style="color:#719e07">(),</span> type<span style="color:#719e07">.</span>getName<span style="color:#719e07">().</span>replace<span style="color:#719e07">(</span><span style="color:#2aa198">&#34;org.apache&#34;</span><span style="color:#719e07">,</span> <span style="color:#2aa198">&#34;com.alibaba&#34;</span><span style="color:#719e07">),</span> strategy<span style="color:#719e07">.</span>preferExtensionClassLoader<span style="color:#719e07">(),</span> strategy<span style="color:#719e07">.</span>overridden<span style="color:#719e07">(),</span> strategy<span style="color:#719e07">.</span>excludedPackages<span style="color:#719e07">());</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> extensionClasses<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>loadExtensionClasses 方法总共做了两件事情,一是对 SPI 注解进行解析,二是调用 loadDirectory 方法加载指定文件夹配置文件。SPI 注解解析过程比较简单,无需多说。下面我们来看一下 loadDirectory 做了哪些事情。</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">private</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">loadDirectory</span><span style="color:#719e07">(</span>Map<span style="color:#719e07">&lt;</span>String<span style="color:#719e07">,</span> Class<span style="color:#719e07">&lt;?&gt;&gt;</span> extensionClasses<span style="color:#719e07">,</span> String dir<span style="color:#719e07">,</span> String type<span style="color:#719e07">,</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#dc322f">boolean</span> extensionLoaderClassLoaderFirst<span style="color:#719e07">,</span> <span style="color:#dc322f">boolean</span> overridden<span style="color:#719e07">,</span> String<span style="color:#719e07">...</span> excludedPackages<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// fileName = 文件夹路径 + type 全限定名 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> String fileName <span style="color:#719e07">=</span> dir <span style="color:#719e07">+</span> type<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">try</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> Enumeration<span style="color:#719e07">&lt;</span>java<span style="color:#719e07">.</span>net<span style="color:#719e07">.</span>URL<span style="color:#719e07">&gt;</span> urls <span style="color:#719e07">=</span> <span style="color:#cb4b16">null</span><span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> ClassLoader classLoader <span style="color:#719e07">=</span> findClassLoader<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// try to load from ExtensionLoader&#39;s ClassLoader first |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>extensionLoaderClassLoaderFirst<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> ClassLoader extensionLoaderClassLoader <span style="color:#719e07">=</span> ExtensionLoader<span style="color:#719e07">.</span>class<span style="color:#719e07">.</span>getClassLoader<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>ClassLoader<span style="color:#719e07">.</span>getSystemClassLoader<span style="color:#719e07">()</span> <span style="color:#719e07">!=</span> extensionLoaderClassLoader<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> urls <span style="color:#719e07">=</span> extensionLoaderClassLoader<span style="color:#719e07">.</span>getResources<span style="color:#719e07">(</span>fileName<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 根据文件名加载所有的同名文件 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>urls <span style="color:#719e07">==</span> <span style="color:#cb4b16">null</span> <span style="color:#719e07">||</span> <span style="color:#719e07">!</span>urls<span style="color:#719e07">.</span>hasMoreElements<span style="color:#719e07">())</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>classLoader <span style="color:#719e07">!=</span> <span style="color:#cb4b16">null</span><span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> urls <span style="color:#719e07">=</span> classLoader<span style="color:#719e07">.</span>getResources<span style="color:#719e07">(</span>fileName<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> <span style="color:#719e07">else</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> urls <span style="color:#719e07">=</span> ClassLoader<span style="color:#719e07">.</span>getSystemResources<span style="color:#719e07">(</span>fileName<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>urls <span style="color:#719e07">!=</span> <span style="color:#cb4b16">null</span><span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">while</span> <span style="color:#719e07">(</span>urls<span style="color:#719e07">.</span>hasMoreElements<span style="color:#719e07">())</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> java<span style="color:#719e07">.</span>net<span style="color:#719e07">.</span>URL resourceURL <span style="color:#719e07">=</span> urls<span style="color:#719e07">.</span>nextElement<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 加载资源 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> loadResource<span style="color:#719e07">(</span>extensionClasses<span style="color:#719e07">,</span> classLoader<span style="color:#719e07">,</span> resourceURL<span style="color:#719e07">,</span> overridden<span style="color:#719e07">,</span> excludedPackages<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> <span style="color:#719e07">catch</span> <span style="color:#719e07">(</span>Throwable t<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> logger<span style="color:#719e07">.</span>error<span style="color:#719e07">(</span><span style="color:#2aa198">&#34;Exception occurred when loading extension class (interface: &#34;</span> <span style="color:#719e07">+</span> |
| </span></span><span style="display:flex;"><span> type <span style="color:#719e07">+</span> <span style="color:#2aa198">&#34;, description file: &#34;</span> <span style="color:#719e07">+</span> fileName <span style="color:#719e07">+</span> <span style="color:#2aa198">&#34;).&#34;</span><span style="color:#719e07">,</span> t<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>loadDirectory 方法先通过 classLoader 获取所有资源链接,然后再通过 loadResource 方法加载资源。我们继续跟下去,看一下 loadResource 方法的实现。</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">private</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">loadResource</span><span style="color:#719e07">(</span>Map<span style="color:#719e07">&lt;</span>String<span style="color:#719e07">,</span> Class<span style="color:#719e07">&lt;?&gt;&gt;</span> extensionClasses<span style="color:#719e07">,</span> ClassLoader classLoader<span style="color:#719e07">,</span> |
| </span></span><span style="display:flex;"><span> java<span style="color:#719e07">.</span>net<span style="color:#719e07">.</span>URL resourceURL<span style="color:#719e07">,</span> <span style="color:#dc322f">boolean</span> overridden<span style="color:#719e07">,</span> String<span style="color:#719e07">...</span> excludedPackages<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">try</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">try</span> <span style="color:#719e07">(</span>BufferedReader reader <span style="color:#719e07">=</span> <span style="color:#719e07">new</span> BufferedReader<span style="color:#719e07">(</span><span style="color:#719e07">new</span> InputStreamReader<span style="color:#719e07">(</span>resourceURL<span style="color:#719e07">.</span>openStream<span style="color:#719e07">(),</span> StandardCharsets<span style="color:#719e07">.</span>UTF_8<span style="color:#719e07">)))</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> String line<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> String clazz <span style="color:#719e07">=</span> <span style="color:#cb4b16">null</span><span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 按行读取配置内容 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">while</span> <span style="color:#719e07">((</span>line <span style="color:#719e07">=</span> reader<span style="color:#719e07">.</span>readLine<span style="color:#719e07">())</span> <span style="color:#719e07">!=</span> <span style="color:#cb4b16">null</span><span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 定位 # 字符 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#268bd2">final</span> <span style="color:#dc322f">int</span> ci <span style="color:#719e07">=</span> line<span style="color:#719e07">.</span>indexOf<span style="color:#719e07">(</span><span style="color:#2aa198">&#39;#&#39;</span><span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>ci <span style="color:#719e07">&gt;=</span> 0<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 截取 # 之前的字符串,# 之后的内容为注释,需要忽略 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> line <span style="color:#719e07">=</span> line<span style="color:#719e07">.</span>substring<span style="color:#719e07">(</span>0<span style="color:#719e07">,</span> ci<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> line <span style="color:#719e07">=</span> line<span style="color:#719e07">.</span>trim<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>line<span style="color:#719e07">.</span>length<span style="color:#719e07">()</span> <span style="color:#719e07">&gt;</span> 0<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">try</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> String name <span style="color:#719e07">=</span> <span style="color:#cb4b16">null</span><span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 以等于号 = 为界,截取键与值 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#dc322f">int</span> i <span style="color:#719e07">=</span> line<span style="color:#719e07">.</span>indexOf<span style="color:#719e07">(</span><span style="color:#2aa198">&#39;=&#39;</span><span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>i <span style="color:#719e07">&gt;</span> 0<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> name <span style="color:#719e07">=</span> line<span style="color:#719e07">.</span>substring<span style="color:#719e07">(</span>0<span style="color:#719e07">,</span> i<span style="color:#719e07">).</span>trim<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> clazz <span style="color:#719e07">=</span> line<span style="color:#719e07">.</span>substring<span style="color:#719e07">(</span>i <span style="color:#719e07">+</span> 1<span style="color:#719e07">).</span>trim<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> <span style="color:#719e07">else</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> clazz <span style="color:#719e07">=</span> line<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 加载类,并通过 loadClass 方法对类进行缓存 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>StringUtils<span style="color:#719e07">.</span>isNotEmpty<span style="color:#719e07">(</span>clazz<span style="color:#719e07">)</span> <span style="color:#719e07">&amp;&amp;</span> <span style="color:#719e07">!</span>isExcluded<span style="color:#719e07">(</span>clazz<span style="color:#719e07">,</span> excludedPackages<span style="color:#719e07">))</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> loadClass<span style="color:#719e07">(</span>extensionClasses<span style="color:#719e07">,</span> resourceURL<span style="color:#719e07">,</span> Class<span style="color:#719e07">.</span>forName<span style="color:#719e07">(</span>clazz<span style="color:#719e07">,</span> <span style="color:#cb4b16">true</span><span style="color:#719e07">,</span> classLoader<span style="color:#719e07">),</span> name<span style="color:#719e07">,</span> overridden<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> <span style="color:#719e07">catch</span> <span style="color:#719e07">(</span>Throwable t<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> IllegalStateException e <span style="color:#719e07">=</span> <span style="color:#719e07">new</span> IllegalStateException<span style="color:#719e07">(</span><span style="color:#2aa198">&#34;Failed to load extension class (interface: &#34;</span> <span style="color:#719e07">+</span> type <span style="color:#719e07">+</span> <span style="color:#2aa198">&#34;, class line: &#34;</span> <span style="color:#719e07">+</span> line <span style="color:#719e07">+</span> <span style="color:#2aa198">&#34;) in &#34;</span> <span style="color:#719e07">+</span> resourceURL <span style="color:#719e07">+</span> <span style="color:#2aa198">&#34;, cause: &#34;</span> <span style="color:#719e07">+</span> t<span style="color:#719e07">.</span>getMessage<span style="color:#719e07">(),</span> t<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> exceptions<span style="color:#719e07">.</span>put<span style="color:#719e07">(</span>line<span style="color:#719e07">,</span> e<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> <span style="color:#719e07">catch</span> <span style="color:#719e07">(</span>Throwable t<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> logger<span style="color:#719e07">.</span>error<span style="color:#719e07">(</span><span style="color:#2aa198">&#34;Exception occurred when loading extension class (interface: &#34;</span> <span style="color:#719e07">+</span> |
| </span></span><span style="display:flex;"><span> type <span style="color:#719e07">+</span> <span style="color:#2aa198">&#34;, class file: &#34;</span> <span style="color:#719e07">+</span> resourceURL <span style="color:#719e07">+</span> <span style="color:#2aa198">&#34;) in &#34;</span> <span style="color:#719e07">+</span> resourceURL<span style="color:#719e07">,</span> t<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>loadResource 方法用于读取和解析配置文件,并通过反射加载类,最后调用 loadClass 方法进行其他操作。loadClass 方法用于主要用于操作缓存,该方法的逻辑如下:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">private</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">loadClass</span><span style="color:#719e07">(</span>Map<span style="color:#719e07">&lt;</span>String<span style="color:#719e07">,</span> Class<span style="color:#719e07">&lt;?&gt;&gt;</span> extensionClasses<span style="color:#719e07">,</span> java<span style="color:#719e07">.</span>net<span style="color:#719e07">.</span>URL resourceURL<span style="color:#719e07">,</span> Class<span style="color:#719e07">&lt;?&gt;</span> clazz<span style="color:#719e07">,</span> String name<span style="color:#719e07">,</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#dc322f">boolean</span> overridden<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> NoSuchMethodException <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(!</span>type<span style="color:#719e07">.</span>isAssignableFrom<span style="color:#719e07">(</span>clazz<span style="color:#719e07">))</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">throw</span> <span style="color:#719e07">new</span> IllegalStateException<span style="color:#719e07">(</span><span style="color:#2aa198">&#34;Error occurred when loading extension class (interface: &#34;</span> <span style="color:#719e07">+</span> |
| </span></span><span style="display:flex;"><span> type <span style="color:#719e07">+</span> <span style="color:#2aa198">&#34;, class line: &#34;</span> <span style="color:#719e07">+</span> clazz<span style="color:#719e07">.</span>getName<span style="color:#719e07">()</span> <span style="color:#719e07">+</span> <span style="color:#2aa198">&#34;), class &#34;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">+</span> clazz<span style="color:#719e07">.</span>getName<span style="color:#719e07">()</span> <span style="color:#719e07">+</span> <span style="color:#2aa198">&#34; is not subtype of interface.&#34;</span><span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 检测目标类上是否有 Adaptive 注解 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>clazz<span style="color:#719e07">.</span>isAnnotationPresent<span style="color:#719e07">(</span>Adaptive<span style="color:#719e07">.</span>class<span style="color:#719e07">))</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> cacheAdaptiveClass<span style="color:#719e07">(</span>clazz<span style="color:#719e07">,</span> overridden<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> <span style="color:#719e07">else</span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>isWrapperClass<span style="color:#719e07">(</span>clazz<span style="color:#719e07">))</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 缓存包装类 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> cacheWrapperClass<span style="color:#719e07">(</span>clazz<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> <span style="color:#719e07">else</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 进入到这里,表明只是该类只是一个普通的拓展类 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#586e75">// 检测 clazz 是否有默认的构造方法,如果没有,则抛出异常 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> clazz<span style="color:#719e07">.</span>getConstructor<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>StringUtils<span style="color:#719e07">.</span>isEmpty<span style="color:#719e07">(</span>name<span style="color:#719e07">))</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 如果 name 为空,则尝试从 Extension 注解中获取 name,或使用小写的类名作为 name |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> name <span style="color:#719e07">=</span> findAnnotationName<span style="color:#719e07">(</span>clazz<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>name<span style="color:#719e07">.</span>length<span style="color:#719e07">()</span> <span style="color:#719e07">==</span> 0<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">throw</span> <span style="color:#719e07">new</span> IllegalStateException<span style="color:#719e07">(</span><span style="color:#2aa198">&#34;No such extension name for the class &#34;</span> <span style="color:#719e07">+</span> clazz<span style="color:#719e07">.</span>getName<span style="color:#719e07">()</span> <span style="color:#719e07">+</span> <span style="color:#2aa198">&#34; in the config &#34;</span> <span style="color:#719e07">+</span> resourceURL<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> String<span style="color:#719e07">[]</span> names <span style="color:#719e07">=</span> NAME_SEPARATOR<span style="color:#719e07">.</span>split<span style="color:#719e07">(</span>name<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>ArrayUtils<span style="color:#719e07">.</span>isNotEmpty<span style="color:#719e07">(</span>names<span style="color:#719e07">))</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 如果类上有 Activate 注解,则使用 names 数组的第一个元素作为键, |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#586e75">// 存储 name 到 Activate 注解对象的映射关系 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> cacheActivateClass<span style="color:#719e07">(</span>clazz<span style="color:#719e07">,</span> names<span style="color:#719e07">[</span>0<span style="color:#719e07">]);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">for</span> <span style="color:#719e07">(</span>String n <span style="color:#719e07">:</span> names<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 存储 Class 到名称的映射关系 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> cacheName<span style="color:#719e07">(</span>clazz<span style="color:#719e07">,</span> n<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 存储 name 到 Class 的映射关系. |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#586e75">// 如果存在同一个扩展名对应多个实现类,基于 override 参数是否允许覆盖,如果不允许,则抛出异常. |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> saveInExtensionClass<span style="color:#719e07">(</span>extensionClasses<span style="color:#719e07">,</span> clazz<span style="color:#719e07">,</span> n<span style="color:#719e07">,</span> overridden<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>如上,loadClass 方法操作了不同的缓存,比如 cachedAdaptiveClass、cachedWrapperClasses 和 cachedNames 等等。除此之外,该方法没有其他什么逻辑了。</p> |
| <p>到此,关于缓存类加载的过程就分析完了。整个过程没什么特别复杂的地方,大家按部就班的分析即可,不懂的地方可以调试一下。接下来,我们来聊聊 Dubbo IOC 方面的内容。</p> |
| <h4 id="212-dubbo-ioc">2.1.2 Dubbo IOC</h4> |
| <p>Dubbo IOC 是通过 setter 方法注入依赖。Dubbo 首先会通过反射获取到实例的所有方法,然后再遍历方法列表,检测方法名是否具有 setter 方法特征。若有,则通过 ObjectFactory 获取依赖对象,最后通过反射调用 setter 方法将依赖设置到目标对象中。整个过程对应的代码如下:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">private</span> T <span style="color:#268bd2">injectExtension</span><span style="color:#719e07">(</span>T instance<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>objectFactory <span style="color:#719e07">==</span> <span style="color:#cb4b16">null</span><span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> instance<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">try</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 遍历目标类的所有方法 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">for</span> <span style="color:#719e07">(</span>Method method <span style="color:#719e07">:</span> instance<span style="color:#719e07">.</span>getClass<span style="color:#719e07">().</span>getMethods<span style="color:#719e07">())</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 检测方法是否以 set 开头,且方法仅有一个参数,且方法访问级别为 public |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">if</span> <span style="color:#719e07">(!</span>isSetter<span style="color:#719e07">(</span>method<span style="color:#719e07">))</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">continue</span><span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">/** |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 检测是否有 DisableInject 注解修饰. |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> */</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>method<span style="color:#719e07">.</span>getAnnotation<span style="color:#719e07">(</span>DisableInject<span style="color:#719e07">.</span>class<span style="color:#719e07">)</span> <span style="color:#719e07">!=</span> <span style="color:#cb4b16">null</span><span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">continue</span><span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">/** |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> * 检测是否实现了ScopeModelAware、ExtensionAccessorAware类,如果实现则不注入 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"> */</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>method<span style="color:#719e07">.</span>getDeclaringClass<span style="color:#719e07">()</span> <span style="color:#719e07">==</span> ScopeModelAware<span style="color:#719e07">.</span>class<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">continue</span><span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>instance <span style="color:#719e07">instanceof</span> ScopeModelAware <span style="color:#719e07">||</span> instance <span style="color:#719e07">instanceof</span> ExtensionAccessorAware<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>ignoredInjectMethodsDesc<span style="color:#719e07">.</span>contains<span style="color:#719e07">(</span>ReflectUtils<span style="color:#719e07">.</span>getDesc<span style="color:#719e07">(</span>method<span style="color:#719e07">)))</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">continue</span><span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 基本类型不注入 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> Class<span style="color:#719e07">&lt;?&gt;</span> pt <span style="color:#719e07">=</span> method<span style="color:#719e07">.</span>getParameterTypes<span style="color:#719e07">()[</span>0<span style="color:#719e07">];</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>ReflectUtils<span style="color:#719e07">.</span>isPrimitives<span style="color:#719e07">(</span>pt<span style="color:#719e07">))</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">continue</span><span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">try</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 获取属性名,比如 setName 方法对应属性名 name |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> String property <span style="color:#719e07">=</span> getSetterProperty<span style="color:#719e07">(</span>method<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 从 ObjectFactory 中获取依赖对象 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> Object object <span style="color:#719e07">=</span> objectFactory<span style="color:#719e07">.</span>getExtension<span style="color:#719e07">(</span>pt<span style="color:#719e07">,</span> property<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>object <span style="color:#719e07">!=</span> <span style="color:#cb4b16">null</span><span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 注入 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> method<span style="color:#719e07">.</span>invoke<span style="color:#719e07">(</span>instance<span style="color:#719e07">,</span> object<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> <span style="color:#719e07">catch</span> <span style="color:#719e07">(</span>Exception e<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> logger<span style="color:#719e07">.</span>error<span style="color:#719e07">(</span><span style="color:#2aa198">&#34;Failed to inject via method &#34;</span> <span style="color:#719e07">+</span> method<span style="color:#719e07">.</span>getName<span style="color:#719e07">()</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">+</span> <span style="color:#2aa198">&#34; of interface &#34;</span> <span style="color:#719e07">+</span> type<span style="color:#719e07">.</span>getName<span style="color:#719e07">()</span> <span style="color:#719e07">+</span> <span style="color:#2aa198">&#34;: &#34;</span> <span style="color:#719e07">+</span> e<span style="color:#719e07">.</span>getMessage<span style="color:#719e07">(),</span> e<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> <span style="color:#719e07">catch</span> <span style="color:#719e07">(</span>Exception e<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> logger<span style="color:#719e07">.</span>error<span style="color:#719e07">(</span>e<span style="color:#719e07">.</span>getMessage<span style="color:#719e07">(),</span> e<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> instance<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>在上面代码中,objectFactory 变量的类型为 AdaptiveExtensionFactory,AdaptiveExtensionFactory 内部维护了一个 ExtensionFactory 列表,用于存储其他类型的 ExtensionFactory。Dubbo 目前提供了两种 ExtensionFactory,分别是 SpiExtensionFactory 和 SpringExtensionFactory。前者用于创建自适应的拓展,后者是用于从 Spring 的 IOC 容器中获取所需的拓展。这两个类的类的代码不是很复杂,这里就不一一分析了。</p> |
| <p>Dubbo IOC 目前仅支持 setter 方式注入,总的来说,逻辑比较简单易懂。</p> |
| <h3 id="22-加载自适应扩展类">2.2 加载自适应扩展类</h3> |
| <p>自适应扩展类的含义是说,基于参数,在运行时动态选择到具体的目标类,然后执行。 |
| 在 Dubbo 中,很多拓展都是通过 SPI 机制进行加载的,比如 Protocol、Cluster、LoadBalance 等。有时,有些拓展并不想在框架启动阶段被加载,而是希望在拓展方法被调用时,根据运行时参数进行加载。这听起来有些矛盾。拓展未被加载,那么拓展方法就无法被调用(静态方法除外)。拓展方法未被调用,拓展就无法被加载。对于这个矛盾的问题,Dubbo 通过自适应拓展机制很好的解决了。自适应拓展机制的实现逻辑比较复杂,首先 Dubbo 会为拓展接口生成具有代理功能的代码。然后通过 javassist 或 jdk 编译这段代码,得到 Class 类。最后再通过反射创建代理类,整个过程比较复杂。</p> |
| <p>加载自适应扩展类的入口是 ExtensionLoader 的 getAdaptiveExtension 方法。</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">public</span> T <span style="color:#268bd2">getAdaptiveExtension</span><span style="color:#719e07">()</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 从缓存中获取自适应拓展 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> Object instance <span style="color:#719e07">=</span> cachedAdaptiveInstance<span style="color:#719e07">.</span>get<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>instance <span style="color:#719e07">==</span> <span style="color:#cb4b16">null</span><span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 如果存在异常,则直接抛出 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>createAdaptiveInstanceError <span style="color:#719e07">!=</span> <span style="color:#cb4b16">null</span><span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">throw</span> <span style="color:#719e07">new</span> IllegalStateException<span style="color:#719e07">(</span><span style="color:#2aa198">&#34;Failed to create adaptive instance: &#34;</span> <span style="color:#719e07">+</span> |
| </span></span><span style="display:flex;"><span> createAdaptiveInstanceError<span style="color:#719e07">.</span>toString<span style="color:#719e07">(),</span> |
| </span></span><span style="display:flex;"><span> createAdaptiveInstanceError<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">synchronized</span> <span style="color:#719e07">(</span>cachedAdaptiveInstance<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> instance <span style="color:#719e07">=</span> cachedAdaptiveInstance<span style="color:#719e07">.</span>get<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// double check |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>instance <span style="color:#719e07">==</span> <span style="color:#cb4b16">null</span><span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">try</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 创建自适应拓展 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#586e75">// 这里分为两种情况:一种是存在 Adaptive 类,另一个是需要生成 Adaptive 类 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> instance <span style="color:#719e07">=</span> createAdaptiveExtension<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> cachedAdaptiveInstance<span style="color:#719e07">.</span>set<span style="color:#719e07">(</span>instance<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> <span style="color:#719e07">catch</span> <span style="color:#719e07">(</span>Throwable t<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> createAdaptiveInstanceError <span style="color:#719e07">=</span> t<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">throw</span> <span style="color:#719e07">new</span> IllegalStateException<span style="color:#719e07">(</span><span style="color:#2aa198">&#34;Failed to create adaptive instance: &#34;</span> <span style="color:#719e07">+</span> t<span style="color:#719e07">.</span>toString<span style="color:#719e07">(),</span> t<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> <span style="color:#719e07">(</span>T<span style="color:#719e07">)</span> instance<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>getAdaptiveExtension 方法首先会检查缓存,缓存未命中,则调用 createAdaptiveExtension 方法创建自适应拓展。下面,我们看一下 createAdaptiveExtension 方法的代码。</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">private</span> T <span style="color:#268bd2">createAdaptiveExtension</span><span style="color:#719e07">()</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">try</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 获取自适应拓展类,并通过反射实例化 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">return</span> injectExtension<span style="color:#719e07">((</span>T<span style="color:#719e07">)</span> getAdaptiveExtensionClass<span style="color:#719e07">().</span>newInstance<span style="color:#719e07">());</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> <span style="color:#719e07">catch</span> <span style="color:#719e07">(</span>Exception e<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">throw</span> <span style="color:#719e07">new</span> IllegalStateException<span style="color:#719e07">(</span><span style="color:#2aa198">&#34;Can not create adaptive extension ...&#34;</span><span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>createAdaptiveExtension 方法的代码比较少,但却包含了三个逻辑,分别如下:</p> |
| <ol> |
| <li>调用 getAdaptiveExtensionClass 方法获取自适应拓展 Class 对象</li> |
| <li>通过反射进行实例化</li> |
| <li>调用 injectExtension 方法向拓展实例中注入依赖</li> |
| </ol> |
| <p>前两个逻辑比较好理解,第三个逻辑用于向自适应拓展对象中注入依赖。这个逻辑看似多余,但有存在的必要,这里简单说明一下。前面说过,Dubbo 中有两种类型的自适应拓展,一种是手工编码的,一种是自动生成的。手工编码的自适应拓展中可能存在着一些依赖,而自动生成的 Adaptive 拓展则不会依赖其他类。这里调用 injectExtension 方法的目的是为手工编码的自适应拓展注入依赖,这一点需要大家注意一下。关于 injectExtension 方法,前文已经分析过了,这里不再赘述。接下来,分析 getAdaptiveExtensionClass 方法的逻辑。</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">private</span> Class<span style="color:#719e07">&lt;?&gt;</span> getAdaptiveExtensionClass<span style="color:#719e07">()</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 通过 SPI 获取所有的拓展类 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> getExtensionClasses<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 检查缓存,若缓存不为空,则直接返回缓存 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>cachedAdaptiveClass <span style="color:#719e07">!=</span> <span style="color:#cb4b16">null</span><span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> cachedAdaptiveClass<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 创建自适应拓展类 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">return</span> cachedAdaptiveClass <span style="color:#719e07">=</span> createAdaptiveExtensionClass<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>getAdaptiveExtensionClass 方法同样包含了三个逻辑,如下:</p> |
| <ol> |
| <li>调用 getExtensionClasses 获取所有的拓展类</li> |
| <li>检查缓存,若缓存不为空,则返回缓存</li> |
| <li>若缓存为空,则调用 createAdaptiveExtensionClass 创建自适应拓展类</li> |
| </ol> |
| <p>这三个逻辑看起来平淡无奇,似乎没有多讲的必要。但是这些平淡无奇的代码中隐藏了着一些细节,需要说明一下。首先从第一个逻辑说起,getExtensionClasses 这个方法用于获取某个接口的所有实现类。比如该方法可以获取 Protocol 接口的 DubboProtocol、HttpProtocol、InjvmProtocol 等实现类。在获取实现类的过程中,如果某个实现类被 Adaptive 注解修饰了,那么该类就会被赋值给 cachedAdaptiveClass 变量。此时,上面步骤中的第二步条件成立(缓存不为空),直接返回 cachedAdaptiveClass 即可。如果所有的实现类均未被 Adaptive 注解修饰,那么执行第三步逻辑,创建自适应拓展类。相关代码如下:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">private</span> Class<span style="color:#719e07">&lt;?&gt;</span> createAdaptiveExtensionClass<span style="color:#719e07">()</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 构建自适应拓展代码 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> String code <span style="color:#719e07">=</span> <span style="color:#719e07">new</span> AdaptiveClassCodeGenerator<span style="color:#719e07">(</span>type<span style="color:#719e07">,</span> cachedDefaultName<span style="color:#719e07">).</span>generate<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> ClassLoader classLoader <span style="color:#719e07">=</span> findClassLoader<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 获取编译器实现类 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> org<span style="color:#719e07">.</span>apache<span style="color:#719e07">.</span>dubbo<span style="color:#719e07">.</span>common<span style="color:#719e07">.</span>compiler<span style="color:#719e07">.</span>Compiler compiler <span style="color:#719e07">=</span> ExtensionLoader<span style="color:#719e07">.</span>getExtensionLoader<span style="color:#719e07">(</span>org<span style="color:#719e07">.</span>apache<span style="color:#719e07">.</span>dubbo<span style="color:#719e07">.</span>common<span style="color:#719e07">.</span>compiler<span style="color:#719e07">.</span>Compiler<span style="color:#719e07">.</span>class<span style="color:#719e07">).</span>getAdaptiveExtension<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 编译代码,生成 Class |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">return</span> compiler<span style="color:#719e07">.</span>compile<span style="color:#719e07">(</span>code<span style="color:#719e07">,</span> classLoader<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>createAdaptiveExtensionClass 方法用于生成自适应拓展类,该方法首先会生成自适应拓展类的源码,然后通过 Compiler 实例(Dubbo 默认使用 javassist 作为编译器)编译源码,得到代理类 Class 实例。接下来,我们把重点放在代理类代码生成的逻辑上,其他逻辑大家自行分析。</p> |
| <h4 id="221-自适应拓展类代码生成">2.2.1 自适应拓展类代码生成</h4> |
| <p>AdaptiveClassCodeGenerator#generate 方法生成扩展类代码</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">public</span> String <span style="color:#268bd2">generate</span><span style="color:#719e07">()</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 如果该接口中没有方法被 @Adaptive 注解修饰,直接抛出异常 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">if</span> <span style="color:#719e07">(!</span>hasAdaptiveMethod<span style="color:#719e07">())</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">throw</span> <span style="color:#719e07">new</span> IllegalStateException<span style="color:#719e07">(</span><span style="color:#2aa198">&#34;No adaptive method exist on extension &#34;</span> <span style="color:#719e07">+</span> type<span style="color:#719e07">.</span>getName<span style="color:#719e07">()</span> <span style="color:#719e07">+</span> <span style="color:#2aa198">&#34;, refuse to create the adaptive class!&#34;</span><span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> StringBuilder code <span style="color:#719e07">=</span> <span style="color:#719e07">new</span> StringBuilder<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 生成包名、import、方法等. |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> code<span style="color:#719e07">.</span>append<span style="color:#719e07">(</span>generatePackageInfo<span style="color:#719e07">());</span> |
| </span></span><span style="display:flex;"><span> code<span style="color:#719e07">.</span>append<span style="color:#719e07">(</span>generateImports<span style="color:#719e07">());</span> |
| </span></span><span style="display:flex;"><span> code<span style="color:#719e07">.</span>append<span style="color:#719e07">(</span>generateClassDeclaration<span style="color:#719e07">());</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> Method<span style="color:#719e07">[]</span> methods <span style="color:#719e07">=</span> type<span style="color:#719e07">.</span>getMethods<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">for</span> <span style="color:#719e07">(</span>Method method <span style="color:#719e07">:</span> methods<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> code<span style="color:#719e07">.</span>append<span style="color:#719e07">(</span>generateMethod<span style="color:#719e07">(</span>method<span style="color:#719e07">));</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> code<span style="color:#719e07">.</span>append<span style="color:#719e07">(</span><span style="color:#2aa198">&#34;}&#34;</span><span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>logger<span style="color:#719e07">.</span>isDebugEnabled<span style="color:#719e07">())</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> logger<span style="color:#719e07">.</span>debug<span style="color:#719e07">(</span>code<span style="color:#719e07">.</span>toString<span style="color:#719e07">());</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> code<span style="color:#719e07">.</span>toString<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><h4 id="222-生成方法">2.2.2 生成方法</h4> |
| <p>上面代码中,生成方法的逻辑是最关键的,我们详细分析下。</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">private</span> String <span style="color:#268bd2">generateMethod</span><span style="color:#719e07">(</span>Method method<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> String methodReturnType <span style="color:#719e07">=</span> method<span style="color:#719e07">.</span>getReturnType<span style="color:#719e07">().</span>getCanonicalName<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> String methodName <span style="color:#719e07">=</span> method<span style="color:#719e07">.</span>getName<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 生成方法内容 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> String methodContent <span style="color:#719e07">=</span> generateMethodContent<span style="color:#719e07">(</span>method<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> String methodArgs <span style="color:#719e07">=</span> generateMethodArguments<span style="color:#719e07">(</span>method<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> String methodThrows <span style="color:#719e07">=</span> generateMethodThrows<span style="color:#719e07">(</span>method<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> String<span style="color:#719e07">.</span>format<span style="color:#719e07">(</span>CODE_METHOD_DECLARATION<span style="color:#719e07">,</span> methodReturnType<span style="color:#719e07">,</span> methodName<span style="color:#719e07">,</span> methodArgs<span style="color:#719e07">,</span> methodThrows<span style="color:#719e07">,</span> methodContent<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>generateMethodContent 分析</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">private</span> String <span style="color:#268bd2">generateMethodContent</span><span style="color:#719e07">(</span>Method method<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 该方法上必须有 @Adaptive 注解修饰 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> Adaptive adaptiveAnnotation <span style="color:#719e07">=</span> method<span style="color:#719e07">.</span>getAnnotation<span style="color:#719e07">(</span>Adaptive<span style="color:#719e07">.</span>class<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> StringBuilder code <span style="color:#719e07">=</span> <span style="color:#719e07">new</span> StringBuilder<span style="color:#719e07">(</span>512<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>adaptiveAnnotation <span style="color:#719e07">==</span> <span style="color:#cb4b16">null</span><span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 没有 @Adaptive 注解修饰,生成异常信息 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">return</span> generateUnsupported<span style="color:#719e07">(</span>method<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> <span style="color:#719e07">else</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 获取 URL 在参数列表上的索引 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#dc322f">int</span> urlTypeIndex <span style="color:#719e07">=</span> getUrlTypeIndex<span style="color:#719e07">(</span>method<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>urlTypeIndex <span style="color:#719e07">!=</span> <span style="color:#719e07">-</span>1<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 如果参数列表上存在 URL,生成对 URL 进行空检查 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> code<span style="color:#719e07">.</span>append<span style="color:#719e07">(</span>generateUrlNullCheck<span style="color:#719e07">(</span>urlTypeIndex<span style="color:#719e07">));</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> <span style="color:#719e07">else</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 如果参数列表不存在 URL 类型的参数,那么就看参数列表上参数对象中是否包含 getUrl 方法 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#586e75">// 有的话,生成 URL 空检查 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> code<span style="color:#719e07">.</span>append<span style="color:#719e07">(</span>generateUrlAssignmentIndirectly<span style="color:#719e07">(</span>method<span style="color:#719e07">));</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 解析 Adaptive 注解上的 value 属性 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> String<span style="color:#719e07">[]</span> value <span style="color:#719e07">=</span> getMethodAdaptiveValue<span style="color:#719e07">(</span>adaptiveAnnotation<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 如果参数列表上有 Invocation 类型的参数,生成空检查并获取 methodName. |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#dc322f">boolean</span> hasInvocation <span style="color:#719e07">=</span> hasInvocationArgument<span style="color:#719e07">(</span>method<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> code<span style="color:#719e07">.</span>append<span style="color:#719e07">(</span>generateInvocationArgumentNullCheck<span style="color:#719e07">(</span>method<span style="color:#719e07">));</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 这段逻辑主要就是为了生成 extName(也就是扩展名) |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#586e75">// 分为多种情况: |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#586e75">// 1.defaultExtName 是否存在 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#586e75">// 2.参数中是否存在 invocation 类型参数 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#586e75">// 3.是否是为 protocol 生成代理 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#586e75">// 为什么要对 protocol 单独考虑了?因为 URL 中有获取 protocol 值的方法 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> code<span style="color:#719e07">.</span>append<span style="color:#719e07">(</span>generateExtNameAssignment<span style="color:#719e07">(</span>value<span style="color:#719e07">,</span> hasInvocation<span style="color:#719e07">));</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// check extName == null? |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> code<span style="color:#719e07">.</span>append<span style="color:#719e07">(</span>generateExtNameNullCheck<span style="color:#719e07">(</span>value<span style="color:#719e07">));</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 生成获取扩展(使用 ExtensionLoader.getExtension 方法) |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> code<span style="color:#719e07">.</span>append<span style="color:#719e07">(</span>generateExtensionAssignment<span style="color:#719e07">());</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 生成返回语句 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> code<span style="color:#719e07">.</span>append<span style="color:#719e07">(</span>generateReturnAndInvocation<span style="color:#719e07">(</span>method<span style="color:#719e07">));</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> code<span style="color:#719e07">.</span>toString<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><p>上面那段逻辑主要做了如下几件事: |
| 1.检查方法上是否 Adaptive 注解修饰 |
| 2.为方法生成代码的时候,参数列表上要有 URL(或参数对象中有 URL) |
| 3.使用 ExtensionLoader.getExtension 获取扩展 |
| 4.执行对应的方法</p> |
| <h4 id="223-附一个动态生成代码后的例子">2.2.3 附一个动态生成代码后的例子</h4> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#719e07">package</span> org.apache.dubbo.common.extension.adaptive<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">import</span> org.apache.dubbo.common.extension.ExtensionLoader<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">HasAdaptiveExt$Adaptive</span> <span style="color:#268bd2">implements</span> org<span style="color:#719e07">.</span>apache<span style="color:#719e07">.</span>dubbo<span style="color:#719e07">.</span>common<span style="color:#719e07">.</span>extension<span style="color:#719e07">.</span>adaptive<span style="color:#719e07">.</span>HasAdaptiveExt <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> java<span style="color:#719e07">.</span>lang<span style="color:#719e07">.</span>String <span style="color:#268bd2">echo</span><span style="color:#719e07">(</span>org<span style="color:#719e07">.</span>apache<span style="color:#719e07">.</span>dubbo<span style="color:#719e07">.</span>common<span style="color:#719e07">.</span>URL arg0<span style="color:#719e07">,</span> |
| </span></span><span style="display:flex;"><span> java<span style="color:#719e07">.</span>lang<span style="color:#719e07">.</span>String arg1<span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// URL 空校验 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>arg0 <span style="color:#719e07">==</span> <span style="color:#cb4b16">null</span><span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">throw</span> <span style="color:#719e07">new</span> IllegalArgumentException<span style="color:#719e07">(</span><span style="color:#2aa198">&#34;url == null&#34;</span><span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> org<span style="color:#719e07">.</span>apache<span style="color:#719e07">.</span>dubbo<span style="color:#719e07">.</span>common<span style="color:#719e07">.</span>URL url <span style="color:#719e07">=</span> arg0<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 获取扩展名 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> String extName <span style="color:#719e07">=</span> url<span style="color:#719e07">.</span>getParameter<span style="color:#719e07">(</span><span style="color:#2aa198">&#34;has.adaptive.ext&#34;</span><span style="color:#719e07">,</span> <span style="color:#2aa198">&#34;adaptive&#34;</span><span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 扩展名空校验 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">if</span> <span style="color:#719e07">(</span>extName <span style="color:#719e07">==</span> <span style="color:#cb4b16">null</span><span style="color:#719e07">)</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">throw</span> <span style="color:#719e07">new</span> IllegalStateException<span style="color:#719e07">(</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#2aa198">&#34;Failed to get extension (org.apache.dubbo.common.extension.adaptive.HasAdaptiveExt) name from url (&#34;</span> <span style="color:#719e07">+</span> |
| </span></span><span style="display:flex;"><span> url<span style="color:#719e07">.</span>toString<span style="color:#719e07">()</span> <span style="color:#719e07">+</span> <span style="color:#2aa198">&#34;) use keys([has.adaptive.ext])&#34;</span><span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 获取扩展 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> org<span style="color:#719e07">.</span>apache<span style="color:#719e07">.</span>dubbo<span style="color:#719e07">.</span>common<span style="color:#719e07">.</span>extension<span style="color:#719e07">.</span>adaptive<span style="color:#719e07">.</span>HasAdaptiveExt extension <span style="color:#719e07">=</span> <span style="color:#719e07">(</span>org<span style="color:#719e07">.</span>apache<span style="color:#719e07">.</span>dubbo<span style="color:#719e07">.</span>common<span style="color:#719e07">.</span>extension<span style="color:#719e07">.</span>adaptive<span style="color:#719e07">.</span>HasAdaptiveExt<span style="color:#719e07">)</span> ExtensionLoader<span style="color:#719e07">.</span>getExtensionLoader<span style="color:#719e07">(</span>org<span style="color:#719e07">.</span>apache<span style="color:#719e07">.</span>dubbo<span style="color:#719e07">.</span>common<span style="color:#719e07">.</span>extension<span style="color:#719e07">.</span>adaptive<span style="color:#719e07">.</span>HasAdaptiveExt<span style="color:#719e07">.</span>class<span style="color:#719e07">)</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">.</span>getExtension<span style="color:#719e07">(</span>extName<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#586e75">// 执行对应的方法 |
| </span></span></span><span style="display:flex;"><span><span style="color:#586e75"></span> <span style="color:#719e07">return</span> extension<span style="color:#719e07">.</span>echo<span style="color:#719e07">(</span>arg0<span style="color:#719e07">,</span> arg1<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><h2 id="3-dubbo-spi-扩展示例">3. Dubbo SPI 扩展示例</h2> |
| <h3 id="31--加载固定扩展类">3.1 加载固定扩展类</h3> |
| <h4 id="311-编写-spi-接口及实现类">3.1.1 编写 SPI 接口及实现类</h4> |
| <p>不管是 Java SPI,还是 Dubbo 中实现的 SPI,都需要编写接口。不过 Dubbo 中的接口需要被 @SPI 注解修饰。</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">@SPI</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">interface</span> <span style="color:#268bd2">DemoSpi</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">say</span><span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">DemoSpiImpl</span> <span style="color:#268bd2">implements</span> DemoSpi <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">say</span><span style="color:#719e07">()</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><h4 id="312-将实现类放在特定目录下">3.1.2 将实现类放在特定目录下</h4> |
| <p>从上面的代码可知,dubbo 在加载扩展类的时候,会从四个目录中读取。我们在 META-INF/dubbo 目录下新建一个以 DemoSpi 接口名为文件名的文件,内容如下:</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>demoSpiImpl = com.xxx.xxx.DemoSpiImpl(为 DemoSpi 接口实现类的全类名) |
| </span></span></code></pre></div><h4 id="313-使用">3.1.3 使用</h4> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">DubboSPITest</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Test</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">sayHello</span><span style="color:#719e07">()</span> <span style="color:#268bd2">throws</span> Exception <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> ExtensionLoader<span style="color:#719e07">&lt;</span>DemoSpi<span style="color:#719e07">&gt;</span> extensionLoader <span style="color:#719e07">=</span> |
| </span></span><span style="display:flex;"><span> ExtensionLoader<span style="color:#719e07">.</span>getExtensionLoader<span style="color:#719e07">(</span>DemoSpi<span style="color:#719e07">.</span>class<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> DemoSpi dmeoSpi <span style="color:#719e07">=</span> extensionLoader<span style="color:#719e07">.</span>getExtension<span style="color:#719e07">(</span><span style="color:#2aa198">&#34;demoSpiImpl&#34;</span><span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> optimusPrime<span style="color:#719e07">.</span>sayHello<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><h3 id="32-加载自适应扩展类">3.2 加载自适应扩展类</h3> |
| <p>这个以 Protocol 为例进行说明</p> |
| <h4 id="321-protocol-接口抽取部分核心方法">3.2.1 Protocol 接口(抽取部分核心方法)</h4> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">@SPI</span><span style="color:#719e07">(</span><span style="color:#2aa198">&#34;dubbo&#34;</span><span style="color:#719e07">)</span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">interface</span> <span style="color:#268bd2">Protocol</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Adaptive</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> Exporter<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">export</span><span style="color:#719e07">(</span>Invoker<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> invoker<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RpcException<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Adaptive</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> Invoker<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">refer</span><span style="color:#719e07">(</span>Class<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> type<span style="color:#719e07">,</span> URL url<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RpcException<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">DubboProtocol</span> <span style="color:#268bd2">extends</span> AbstractProtocol <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">......</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> Invoker<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">refer</span><span style="color:#719e07">(</span>Class<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> type<span style="color:#719e07">,</span> URL url<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RpcException <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> protocolBindingRefer<span style="color:#719e07">(</span>type<span style="color:#719e07">,</span> url<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Override</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> Exporter<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> <span style="color:#268bd2">export</span><span style="color:#719e07">(</span>Invoker<span style="color:#719e07">&lt;</span>T<span style="color:#719e07">&gt;</span> invoker<span style="color:#719e07">)</span> <span style="color:#268bd2">throws</span> RpcException <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">......</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">return</span> exporter<span style="color:#719e07">;</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div><h4 id="322-将实现类放在特定目录下">3.2.2 将实现类放在特定目录下</h4> |
| <p>在 dubbo 中,该配置路径 META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol</p> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>dubbo=org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol |
| </span></span></code></pre></div><p>需要说明一点的是,在 dubbo 中,并不是直接使用 DubboProtocol 的,而是使用的是其包装类。</p> |
| <h4 id="323-使用">3.2.3 使用</h4> |
| <div class="highlight"><pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#268bd2">public</span> <span style="color:#268bd2">class</span> <span style="color:#268bd2">DubboAdaptiveTest</span> <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">@Test</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#268bd2">public</span> <span style="color:#dc322f">void</span> <span style="color:#268bd2">sayHello</span><span style="color:#719e07">()</span> <span style="color:#268bd2">throws</span> Exception <span style="color:#719e07">{</span> |
| </span></span><span style="display:flex;"><span> URL url <span style="color:#719e07">=</span> URL<span style="color:#719e07">.</span>valueOf<span style="color:#719e07">(</span><span style="color:#2aa198">&#34;dubbo://localhost/test&#34;</span><span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> Protocol adaptiveProtocol <span style="color:#719e07">=</span> ExtensionLoader<span style="color:#719e07">.</span>getExtensionLoader<span style="color:#719e07">(</span>Protocol<span style="color:#719e07">.</span>class<span style="color:#719e07">).</span>getAdaptiveExtension<span style="color:#719e07">();</span> |
| </span></span><span style="display:flex;"><span> adaptiveProtocol<span style="color:#719e07">.</span>refer<span style="color:#719e07">(</span>type<span style="color:#719e07">,</span> url<span style="color:#719e07">);</span> |
| </span></span><span style="display:flex;"><span> <span style="color:#719e07">}</span> |
| </span></span><span style="display:flex;"><span><span style="color:#719e07">}</span> |
| </span></span></code></pre></div></description></item></channel></rss> |