blob: 8e96ba97a9b2bdb02a79ca8ac92a55bd54a1d050 [file] [log] [blame]
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Apache Dubbo – Dubbo SPI extension implementation description</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/</link><description>Recent content in Dubbo SPI extension implementation description on Apache Dubbo</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/index.xml" rel="self" type="application/rss+xml"/><item><title>Docs3-V2: Protocol Extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/protocol/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/protocol/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>RPC protocol extension, encapsulates remote call details.&lt;/p>
&lt;p>contract:&lt;/p>
&lt;ul>
&lt;li>When the user calls the &lt;code>invoke()&lt;/code> method of the &lt;code>Invoker&lt;/code> object returned by &lt;code>refer()&lt;/code>, the protocol needs to execute the &lt;code>invoke()&lt;/code> of the &lt;code>Invoker&lt;/code> object passed in from the remote &lt;code>export()&lt;/code> of the URL accordingly ` method.&lt;/li>
&lt;li>Among them, the &lt;code>Invoker&lt;/code> returned by &lt;code>refer()&lt;/code> is implemented by the protocol, and the protocol usually needs to send a remote request in this &lt;code>Invoker&lt;/code>, and the &lt;code>Invoker&lt;/code> passed in by &lt;code>export()&lt;/code> is implemented and passed in by the framework, and the protocol does not need to care.&lt;/li>
&lt;/ul>
&lt;p>Notice:&lt;/p>
&lt;ul>
&lt;li>The protocol does not care about the transparent proxy of the business interface, with &lt;code>Invoker&lt;/code> as the center, and the outer layer converts &lt;code>Invoker&lt;/code> into a business interface.&lt;/li>
&lt;li>The protocol does not have to be TCP network communication, such as through shared files, IPC inter-process communication, etc.&lt;/li>
&lt;/ul>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.rpc.Protocol&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.Exporter&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.Invoker&lt;/code>&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">interface&lt;/span> &lt;span style="color:#268bd2">Protocol&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * Expose remote services:&amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 1. When receiving a request, the protocol should record the request source address information: RpcContext.getContext().setRemoteAddress();&amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 2. export() must be idempotent, that is, exposing the Invoker of the same URL twice is no different from exposing it once. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 3. The Invoker passed in by export() is implemented and passed in by the framework, and the protocol does not need to care. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> *
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * @param &amp;lt;T&amp;gt; type of service
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * @param invoker service execution body
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * @return exporter The reference of the exposed service, used to cancel the exposure
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * @throws RpcException Throws when there is an error in the exposed service, such as the port is already occupied
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> Exporter&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> &lt;span style="color:#268bd2">export&lt;/span>(Invoker&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> invoker) &lt;span style="color:#268bd2">throws&lt;/span> RpcException;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * Quoting remote services:&amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 1. When the user calls the invoke() method of the Invoker object returned by refer(), the protocol needs to correspondingly execute the invoke() method of the Invoker object passed in from the URL remote export(). &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 2. The Invoker returned by refer() is implemented by the protocol, and the protocol usually needs to send a remote request in this Invoker. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 3. When check=false is set in the url, an exception cannot be thrown if the connection fails, and internal automatic recovery is required. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> *
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * @param &amp;lt;T&amp;gt; type of service
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * @param type service type
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * @param url URL address of the remote service
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * @return The local proxy for the invoker service
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * @throws RpcException thrown when the connection to the service provider fails
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> Invoker&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> &lt;span style="color:#268bd2">refer&lt;/span>(Class&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> type, URL url) &lt;span style="color:#268bd2">throws&lt;/span> RpcException;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- declare protocol, if no id is configured, name will be used as id --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> id=&lt;span style="color:#2aa198">&amp;#34;xxx1&amp;#34;&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- Reference protocol, if the protocol attribute is not configured, the protocol configuration will be automatically scanned in the ApplicationContext --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:service&lt;/span> protocol=&lt;span style="color:#2aa198">&amp;#34;xxx1&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- The reference protocol default value, when &amp;lt;dubbo:service&amp;gt; does not configure the protocol attribute, use this configuration --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:provider&lt;/span> protocol=&lt;span style="color:#2aa198">&amp;#34;xxx1&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.rpc.protocol.injvm.InjvmProtocol&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.protocol.rmi.RmiProtocol&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.protocol.http.HttpProtocol&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.protocol.http.hessian.HessianProtocol&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.support.MockProtocol&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxProtocol.java (implement the Protocol interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxExporter.java (implements the Exporter interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxInvoker.java (implements the Invoker interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.rpc.Protocol (plain text file, content: xxx=com.xxx.XxxProtocol)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxProtocol.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.Protocol;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxProtocol&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> Protocol {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> Exporter&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> &lt;span style="color:#268bd2">export&lt;/span>(Invoker&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> invoker) &lt;span style="color:#268bd2">throws&lt;/span> RpcException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> &lt;span style="color:#719e07">new&lt;/span> XxxExporter(invoker);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> Invoker&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> &lt;span style="color:#268bd2">refer&lt;/span>(Class&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> type, URL url) &lt;span style="color:#268bd2">throws&lt;/span> RpcException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> &lt;span style="color:#719e07">new&lt;/span> XxxInvoker(type, url);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxExporter.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.support.AbstractExporter;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxExporter&lt;/span>&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> &lt;span style="color:#268bd2">extends&lt;/span> AbstractExporter&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">XxxExporter&lt;/span>(Invoker&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> invoker) &lt;span style="color:#268bd2">throws&lt;/span> RemotingException{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">super&lt;/span>(invoker);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">unexport&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">super&lt;/span>. &lt;span style="color:#268bd2">unexport&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxInvoker.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.support.AbstractInvoker;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxInvoker&lt;/span>&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> &lt;span style="color:#268bd2">extends&lt;/span> AbstractInvoker&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">XxxInvoker&lt;/span>(Class&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> type, URL url) &lt;span style="color:#268bd2">throws&lt;/span> RemotingException{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">super&lt;/span>(type, url);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Override&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">protected&lt;/span> Result &lt;span style="color:#268bd2">doInvoke&lt;/span>(Invocation invocation) &lt;span style="color:#268bd2">throws&lt;/span> Throwable {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.rpc.Protocol:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxProtocol&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Call Intercept Extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/filter/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/filter/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>Service provider and service consumer call process interception. Most functions of Dubbo itself are implemented based on this extension point. Every time a remote method is executed, this interception will be executed. Please pay attention to the impact on performance.&lt;/p>
&lt;p>agreement:&lt;/p>
&lt;ul>
&lt;li>User-defined filters are by default after built-in filters.&lt;/li>
&lt;li>The special value &lt;code>default&lt;/code>, indicating where the default extension point is inserted. For example: &lt;code>filter=&amp;quot;xxx,default,yyy&amp;quot;&lt;/code>, means &lt;code>xxx&lt;/code> is before the default filter, and &lt;code>yyy&lt;/code> is after the default filter.&lt;/li>
&lt;li>The special symbol &lt;code>-&lt;/code> means culling. For example: &lt;code>filter=&amp;quot;-foo1&amp;quot;&lt;/code>, exclude adding the default extension point &lt;code>foo1&lt;/code>. For example: &lt;code>filter=&amp;quot;-default&amp;quot;&lt;/code>, remove all default extension points.&lt;/li>
&lt;li>When the provider and service configure filters at the same time, all filters are accumulated instead of overwritten. For example: &lt;code>&amp;lt;dubbo:provider filter=&amp;quot;xxx,yyy&amp;quot;/&amp;gt;&lt;/code> and &lt;code>&amp;lt;dubbo:service filter=&amp;quot;aaa,bbb&amp;quot; /&amp;gt;&lt;/code>, then &lt;code>xxx&lt;/code>,&lt;code>yyy&lt;/code>,&lt;code>aaa&lt;/code>,&lt;code>bbb&lt;/code> will take effect. If you want to overwrite, you need to configure: &lt;code>&amp;lt;dubbo:service filter=&amp;quot;-xxx,-yyy,aaa,bbb&amp;quot; /&amp;gt;&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.rpc.Filter&lt;/code>&lt;/p>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- Consumer call process interception --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:reference&lt;/span> filter=&lt;span style="color:#2aa198">&amp;#34;xxx,yyy&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- The default interceptor of the consumer call process, which will intercept all references --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:consumer&lt;/span> filter=&lt;span style="color:#2aa198">&amp;#34;xxx,yyy&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- provider call process interception --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:service&lt;/span> filter=&lt;span style="color:#2aa198">&amp;#34;xxx,yyy&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- Provider call process default interceptor, will intercept all services --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:provider&lt;/span> filter=&lt;span style="color:#2aa198">&amp;#34;xxx,yyy&amp;#34;&lt;/span>&lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.rpc.filter.EchoFilter&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.filter.GenericFilter&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.filter.GenericImplFilter&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.filter.TokenFilter&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.filter.AccessLogFilter&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.filter.CountFilter&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.filter.ActiveLimitFilter&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.filter.ClassLoaderFilter&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.filter.ContextFilter&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.filter.ConsumerContextFilter&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.filter.ExceptionFilter&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.filter.ExecuteLimitFilter&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.filter.DeprecatedFilter&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxFilter.java (implement the Filter interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.rpc.Filter (plain text file, content: xxx=com.xxx.XxxFilter)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxFilter.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.Filter;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.Invoker;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.Invocation;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.Result;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.RpcException;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxFilter&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> Filter {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Result &lt;span style="color:#268bd2">invoke&lt;/span>(Invoker&lt;span style="color:#719e07">&amp;lt;?&amp;gt;&lt;/span> invoker, Invocation invocation) &lt;span style="color:#268bd2">throws&lt;/span> RpcException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// before filter...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Result result &lt;span style="color:#719e07">=&lt;/span> invoker.invoke(invocation);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// after filter...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> result;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.rpc.Filter:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxFilter&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Reference Listener Extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/invoker-listener/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/invoker-listener/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>This event is triggered when there is a service reference.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.rpc.InvokerListener&lt;/code>&lt;/p>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- Reference service listener --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:reference&lt;/span> listener=&lt;span style="color:#2aa198">&amp;#34;xxx,yyy&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- Reference service default listener --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:consumer&lt;/span> listener=&lt;span style="color:#2aa198">&amp;#34;xxx,yyy&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.rpc.listener.DeprecatedInvokerListener&lt;/code>&lt;/p>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxInvokerListener.java (implements the InvokerListener interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.rpc.InvokerListener (plain text file, content: xxx=com.xxx.XxxInvokerListener)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxInvokerListener.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.InvokerListener;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.Invoker;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.RpcException;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxInvokerListener&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> InvokerListener {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">referred&lt;/span>(Invoker&lt;span style="color:#719e07">&amp;lt;?&amp;gt;&lt;/span> invoker) &lt;span style="color:#268bd2">throws&lt;/span> RpcException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">destroyed&lt;/span>(Invoker&lt;span style="color:#719e07">&amp;lt;?&amp;gt;&lt;/span> invoker) &lt;span style="color:#268bd2">throws&lt;/span> RpcException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.rpc.InvokerListener:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxInvokerListener&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Expose Listener Extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/exporter-listener/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/exporter-listener/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>This event is triggered when a service is exposed.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.rpc.ExporterListener&lt;/code>&lt;/p>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- Expose service monitoring --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:service&lt;/span> listener=&lt;span style="color:#2aa198">&amp;#34;xxx,yyy&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- Expose service default listener --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:provider&lt;/span> listener=&lt;span style="color:#2aa198">&amp;#34;xxx,yyy&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.registry.directory.RegistryExporterListener&lt;/code>&lt;/p>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxExporterListener.java (implements ExporterListener interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.rpc.ExporterListener (plain text file, content: xxx=com.xxx.XxxExporterListener)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxExporterListener.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.ExporterListener;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.Exporter;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.RpcException;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxExporterListener&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> ExporterListener {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">exported&lt;/span>(Exporter&lt;span style="color:#719e07">&amp;lt;?&amp;gt;&lt;/span> exporter) &lt;span style="color:#268bd2">throws&lt;/span> RpcException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">unexported&lt;/span>(Exporter&lt;span style="color:#719e07">&amp;lt;?&amp;gt;&lt;/span> exporter) &lt;span style="color:#268bd2">throws&lt;/span> RpcException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.rpc.ExporterListener:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxExporterListener&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Cluster Expansion</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/cluster/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/cluster/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>When there are multiple service providers, organize multiple service providers into a cluster and pretend to be one provider.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.rpc.cluster.Cluster&lt;/code>&lt;/p>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> cluster=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- Default value configuration, if &amp;lt;dubbo:protocol&amp;gt; is not configured with cluster, use this configuration --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:provider&lt;/span> cluster=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterWrapper&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.support.FailoverCluster&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.support.FailfastCluster&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.support.FailsafeCluster&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.support.FailbackCluster&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.support.ForkingCluster&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.support.AvailableCluster&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.support.MergeableCluster&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.support.BroadcastCluster&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.support.registry.ZoneAwareCluster&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxCluster.java (implements the Cluster interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.rpc.cluster.Cluster (plain text file, content: xxx=com.xxx.XxxCluster)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxCluster.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.cluster.Cluster;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.cluster.Directory;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.cluster.LoadBalance;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.Invoker;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.Invocation;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.Result;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.RpcException;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxCluster&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> Cluster {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> Invoker&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> &lt;span style="color:#268bd2">merge&lt;/span>(Directory&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> directory) &lt;span style="color:#268bd2">throws&lt;/span> RpcException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> &lt;span style="color:#719e07">new&lt;/span> AbstractClusterInvoker&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span>(directory) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Result &lt;span style="color:#268bd2">doInvoke&lt;/span>(Invocation invocation, List&lt;span style="color:#719e07">&amp;lt;&lt;/span>Invoker&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&amp;gt;&lt;/span> invokers, LoadBalance loadbalance) &lt;span style="color:#268bd2">throws&lt;/span> RpcException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> };
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.rpc.cluster.Cluster:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxCluster&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Route Extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/router/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/router/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>Select one of multiple service providers to call.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.RouterFactory&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.Router&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.router.ScriptRouterFactory&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.router.FileRouterFactory&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.router.condition.config.AppRouterFactory&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.CacheableRouterFactory&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.router.condition.ConditionRouterFactory&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.router.mock.MockRouterFactory&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.router.condition.config.ServiceRouterFactory&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.router.tag.TagRouterFactory&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxRouterFactory.java (implements RouterFactory interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.rpc.cluster.RouterFactory (plain text file, content: xxx=com.xxx.XxxRouterFactory)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxRouterFactory.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.cluster.RouterFactory;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.Invoker;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.Invocation;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.RpcException;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxRouterFactory&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> RouterFactory {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Router &lt;span style="color:#268bd2">getRouter&lt;/span>(URL url) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.rpc.cluster.RouterFactory:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxRouterFactory&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Load Balancing Extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/load-balance/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/load-balance/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>Select one of multiple service providers to call&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.rpc.cluster.LoadBalance&lt;/code>&lt;/p>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> loadbalance=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- Default value setting, when &amp;lt;dubbo:protocol&amp;gt; does not configure loadbalance, use this configuration --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:provider&lt;/span> loadbalance=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.loadbalance.RandomLoadBalance&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.loadbalance.LeastActiveLoadBalance&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.loadbalance.ConsistentHashLoadBalance&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.loadbalance.ShortestResponseLoadBalance&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxLoadBalance.java (implements the LoadBalance interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.rpc.cluster.LoadBalance (plain text file, content: xxx=com.xxx.XxxLoadBalance)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxLoadBalance.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.cluster.LoadBalance;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.Invoker;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.Invocation;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.RpcException;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxLoadBalance&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> LoadBalance {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> Invoker&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> &lt;span style="color:#268bd2">select&lt;/span>(List&lt;span style="color:#719e07">&amp;lt;&lt;/span>Invoker&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&amp;gt;&lt;/span> invokers, Invocation invocation) &lt;span style="color:#268bd2">throws&lt;/span> RpcException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.rpc.cluster.LoadBalance:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxLoadBalance&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Merge result extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/merger/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/merger/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>Merge returns results for grouping and aggregation.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.rpc.cluster.Merger&lt;/code>&lt;/p>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:method&lt;/span> merger=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.merger.ArrayMerger&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.merger.ListMerger&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.merger.SetMerger&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.merger.MapMerger&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.merger.ByteArrayMerger&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.merger.CharArrayMerger&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.merger.ShortArrayMerger&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.merger.IntArrayMerger&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.merger.LongArrayMerger&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.merger.FloatArrayMerger&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.merger.DoubleArrayMerger&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.cluster.merger.BooleanArrayMerger&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxMerger.java (implement Merger interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.rpc.cluster.Merger (plain text file, content: xxx=com.xxx.XxxMerger)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxMerger.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.cluster.Merger;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxMerger&lt;/span>&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> Merger&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> T &lt;span style="color:#268bd2">merge&lt;/span>(T... results) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.rpc.cluster.Merger:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxMerger&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Registry Extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/registry/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/registry/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>Responsible for service registration and discovery.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.registry.RegistryFactory&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.registry.Registry&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- Define the registration center --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:registry&lt;/span> id=&lt;span style="color:#2aa198">&amp;#34;xxx1&amp;#34;&lt;/span> address=&lt;span style="color:#2aa198">&amp;#34;xxx://ip:port&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- Reference registry, if registry property is not configured, registry configuration will be automatically scanned in ApplicationContext --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:service&lt;/span> registry=&lt;span style="color:#2aa198">&amp;#34;xxx1&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- Reference the default value of the registry, when &amp;lt;dubbo:service&amp;gt; does not configure the registry attribute, use this configuration --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:provider&lt;/span> registry=&lt;span style="color:#2aa198">&amp;#34;xxx1&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="extension-contract">Extension contract&lt;/h2>
&lt;p>RegistryFactory.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">interface&lt;/span> &lt;span style="color:#268bd2">RegistryFactory&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * Connect to the registration center.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> *
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * The connection to the registration center needs to deal with the contract:&amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 1. When check=false is set, it means that the connection will not be checked, otherwise an exception will be thrown when the connection fails. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 2. Support username:password authority authentication on the URL. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 3. Support backup=10.20.153.10 alternative registration center cluster address. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 4. Support file=registry.cache local disk file cache. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 5. Support timeout=1000 request timeout setting. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 6. Support session=60000 session timeout or expiration setting. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> *
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * @param url Registry address, not allowed to be empty
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * @return Registry reference, never return empty
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Registry &lt;span style="color:#268bd2">getRegistry&lt;/span>(URL url);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>RegistryService.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">interface&lt;/span> &lt;span style="color:#268bd2">RegistryService&lt;/span> { &lt;span style="color:#586e75">// Registry extends RegistryService&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * Registration service.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> *
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * Registration requires processing contract:&amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 1. When the URL is set to check=false, no error will be reported after the registration fails, and it will be retried regularly in the background, otherwise an exception will be thrown. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 2. When the dynamic=false parameter is set in the URL, it needs to be stored persistently. Otherwise, when the registrant exits abnormally due to power failure, etc., it needs to be automatically deleted. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 3. When category=overrides is set in the URL, it means classified storage, the default category is providers, and the data can be notified by category. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 4. When the registration center restarts and the network fluctuates, data cannot be lost, including automatic deletion of data when disconnected. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 5. URLs with the same URI but different parameters are allowed to coexist, and cannot be overwritten. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> *
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * @param url Registration information, not allowed to be empty, such as: dubbo://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&amp;amp;application=kylin
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">register&lt;/span>(URL url);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * Unregister service.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> *
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * Cancellation of registration needs to deal with the contract:&amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 1. If it is persistent storage data with dynamic=false and registration data cannot be found, throw IllegalStateException, otherwise ignore it. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 2. Cancel registration by full URL matching. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> *
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * @param url Registration information, not allowed to be empty, such as: dubbo://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&amp;amp;application=kylin
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">unregister&lt;/span>(URL url);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * Subscription service.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> *
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * Subscription requires processing contract:&amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 1. When the URL is set to check=false, no error will be reported after the subscription fails, and it will be retried periodically in the background. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 2. When category=overrides is set in the URL, only the data of the specified category will be notified. Multiple categories are separated by commas, and wildcards of asterisks are allowed, which means to subscribe to all category data. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 3. It is allowed to use interface, group, version, classifier as conditional query, such as: interface=com.alibaba.foo.BarService&amp;amp;version=1.0.0&amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 4. And the query condition allows asterisk wildcards, subscribe to all versions of all groups of all interfaces, or: interface=*&amp;amp;group=*&amp;amp;version=*&amp;amp;classifier=*&amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 5. When the registration center restarts and the network fluctuates, the subscription request needs to be automatically resumed. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 6. URLs with the same URI but different parameters are allowed to coexist, and cannot be overwritten. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 7. The subscription process must be blocked, and return after the first notification. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> *
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * @param url subscription condition, not allowed to be empty, such as: consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&amp;amp;application=kylin
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * @param listener Change event listener, not allowed to be empty
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">subscribe&lt;/span>(URL url, NotifyListener listener);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * Unsubscribe service.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> *
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * Unsubscribing requires processing contract:&amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 1. If there is no subscription, just ignore it. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 2. Unsubscribe by full URL match. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> *
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * @param url subscription condition, not allowed to be empty, such as: consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&amp;amp;application=kylin
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * @param listener Change event listener, not allowed to be empty
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">unsubscribe&lt;/span>(URL url, NotifyListener listener);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * Query the registration list, corresponding to the push mode of subscription, here is the pull mode, and the result is returned only once.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> *
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * @see org.apache.dubbo.registry.NotifyListener#notify(List)
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * @param url query condition, not allowed to be empty, such as: consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&amp;amp;application=kylin
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * @return The registered information list, which may be empty, has the same meaning as the parameter of {@link org.apache.dubbo.registry.NotifyListener#notify(List&amp;lt;URL&amp;gt;)}.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> List&lt;span style="color:#719e07">&amp;lt;&lt;/span>URL&lt;span style="color:#719e07">&amp;gt;&lt;/span> &lt;span style="color:#268bd2">lookup&lt;/span>(URL url);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>NotifyListener.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">interface&lt;/span> &lt;span style="color:#268bd2">NotifyListener&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * Triggered when a service change notification is received.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> *
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * Notice to process contract:&amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 1. The full notification is always based on the service interface and data type, that is, the partial data of the same type of a service will not be notified, and the user does not need to compare the results of the previous notification. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 2. The first notification when subscribing must be a full notification of all types of data for a service. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 3. When changing midway, different types of data are allowed to be notified separately, such as: providers, consumers, routes, overrides, and only one type is allowed to be notified, but the data of this type must be full, not incremental. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 4. If one type of data is empty, it is necessary to notify an empty protocol and identification URL data with category parameter. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * 5. The notifier (that is, the registration center implementation) needs to ensure the order of notifications, such as: single-threaded push, queue serialization, and version comparison. &amp;lt;br&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> *
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * @param urls Registered information list, always not empty, the meaning is the same as the return value of {@link org.apache.dubbo.registry.RegistryService#lookup(URL)}.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">notify&lt;/span>(List&lt;span style="color:#719e07">&amp;lt;&lt;/span>URL&lt;span style="color:#719e07">&amp;gt;&lt;/span> urls);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.registry.support.dubbo.DubboRegistryFactory&lt;/code>&lt;/p>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxRegistryFactoryjava (implements RegistryFactory interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxRegistry.java (implement Registry interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.registry.RegistryFactory (plain text file, content: xxx=com.xxx.XxxRegistryFactory)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxRegistryFactory.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.registry.RegistryFactory;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.registry.Registry;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.common.URL;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxRegistryFactory&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> RegistryFactory {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Registry &lt;span style="color:#268bd2">getRegistry&lt;/span>(URL url) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> &lt;span style="color:#719e07">new&lt;/span> XxxRegistry(url);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxRegistry.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.registry.Registry;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.registry.NotifyListener;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.common.URL;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxRegistry&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> Registry {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">register&lt;/span>(URL url) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">unregister&lt;/span>(URL url) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">subscribe&lt;/span>(URL url, NotifyListener listener) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">unsubscribe&lt;/span>(URL url, NotifyListener listener) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.registry.RegistryFactory:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxRegistryFactory&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Monitoring Center Extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/monitor/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/monitor/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>Responsible for the monitoring of service call times and call time.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.monitor.MonitorFactory&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.monitor.Monitor&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- Define the monitoring center --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:monitor&lt;/span> address=&lt;span style="color:#2aa198">&amp;#34;xxx://ip:port&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;p>org.apache.dubbo.monitor.support.dubbo.DubboMonitorFactory&lt;/p>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxMonitorFactoryjava (implement the MonitorFactory interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxMonitor.java (implement Monitor interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.monitor.MonitorFactory (plain text file, content: xxx=com.xxx.XxxMonitorFactory)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxMonitorFactory.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.monitor.MonitorFactory;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.monitor.Monitor;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.common.URL;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxMonitorFactory&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> MonitorFactory {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Monitor &lt;span style="color:#268bd2">getMonitor&lt;/span>(URL url) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> &lt;span style="color:#719e07">new&lt;/span> XxxMonitor(url);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxMonitor.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.monitor.Monitor;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxMonitor&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> Monitor {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">count&lt;/span>(URL statistics) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.monitor.MonitorFactory:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxMonitorFactory&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Extension Point Load Extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/extension-factory/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/extension-factory/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>The loading container of the extension point itself, which can load the extension point from different containers.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.common.extension.ExtensionFactory&lt;/code>&lt;/p>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:application&lt;/span> compiler=&lt;span style="color:#2aa198">&amp;#34;jdk&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.common.extension.factory.SpiExtensionFactory&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.config.spring.extension.SpringExtensionFactory&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxExtensionFactory.java (implements ExtensionFactory interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.common.extension.ExtensionFactory (plain text file, content: xxx=com.xxx.XxxExtensionFactory)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxExtensionFactory.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.common.extension.ExtensionFactory;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxExtensionFactory&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> ExtensionFactory {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Object &lt;span style="color:#268bd2">getExtension&lt;/span>(Class&lt;span style="color:#719e07">&amp;lt;?&amp;gt;&lt;/span> type, String name) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.common.extension.ExtensionFactory:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxExtensionFactory&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Dynamic Proxy Extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/proxy-factory/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/proxy-factory/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>Convert the &lt;code>Invoker&lt;/code> interface into a business interface.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.rpc.ProxyFactory&lt;/code>&lt;/p>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> proxy=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- Default value configuration, when &amp;lt;dubbo:protocol&amp;gt; does not configure proxy attribute, use this configuration --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:provider&lt;/span> proxy=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.rpc.proxy.JdkProxyFactory&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.proxy.JavassistProxyFactory&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxProxyFactory.java (implement ProxyFactory interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.rpc.ProxyFactory (plain text file, content: xxx=com.xxx.XxxProxyFactory)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxProxyFactory.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.ProxyFactory;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.Invoker;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.rpc.RpcException;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxProxyFactory&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> ProxyFactory {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> T &lt;span style="color:#268bd2">getProxy&lt;/span>(Invoker&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> invoker) &lt;span style="color:#268bd2">throws&lt;/span> RpcException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> Invoker&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> &lt;span style="color:#268bd2">getInvoker&lt;/span>(T proxy, Class&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> type, URL url) &lt;span style="color:#268bd2">throws&lt;/span> RpcException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.rpc.ProxyFactory:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxProxyFactory&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Readiness Probe</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/readiness/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/readiness/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>Extend the detection points of application readiness.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.qos.probe.ReadinessProbe&lt;/code>&lt;/p>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;p>Dubbo QOS &lt;code>ready&lt;/code> command auto-discovery&lt;/p>
&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.qos.probe.impl.BootstrapReadinessProbe&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.qos.probe.impl.ProviderReadinessProbe&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxReadinessProbe.java (implements ReadinessProbe interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.qos.probe.ReadinessProbe (plain text file, content: xxx=com.xxx.XxxReadinessProbe)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxReadinessProbe.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxReadinessProbe&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> ReadinessProbe {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">boolean&lt;/span> &lt;span style="color:#268bd2">check&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.qos.probe.ReadinessProbe:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>xxx=com.xxx.XxxReadinessProbe
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Startup Startup Probe</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/startup/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/startup/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>Extend the detection point of application startup.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.qos.probe.StartupProbe&lt;/code>&lt;/p>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;p>Dubbo QOS &lt;code>startup&lt;/code> command auto-discovery&lt;/p>
&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.qos.probe.impl.BootstrapLivenessProbe&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxStartupProbe.java (implement the StartupProbe interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.qos.probe.StartupProbe (plain text file, content: xxx=com.xxx.XxxStartupProbe)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxStartupProbee.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxStartupProbe&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> StartupProbe {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">boolean&lt;/span> &lt;span style="color:#268bd2">check&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.qos.probe.StartupProbe:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>xxx=com.xxx.XxxStartupProbe
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Liveness Survival Probe</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/liveness/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/liveness/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>Expand the detection point of application survival.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.qos.probe.LivenessProbe&lt;/code>&lt;/p>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;p>Dubbo QOS &lt;code>live&lt;/code> command automatic discovery&lt;/p>
&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;p>No default implementation yet&lt;/p>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxLivenessProbe.java (implement LivenessProbe interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.qos.probe.LivenessProbe (plain text file, content: xxx=com.xxx.XxxLivenessProbe)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxLivenessProbe.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxLivenessProbe&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> LivenessProbe {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">boolean&lt;/span> &lt;span style="color:#268bd2">check&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.qos.probe.LivenessProbe:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>xxx=com.xxx.XxxLivenessProbe
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Compiler Extensions</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/compiler/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/compiler/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>Java code compiler, used to dynamically generate bytecode to speed up calls.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.common.compiler.Compiler&lt;/code>&lt;/p>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;p>autoload&lt;/p>
&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.common.compiler.support.JdkCompiler&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.common.compiler.support.JavassistCompiler&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxCompiler.java (implement Compiler interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.common.compiler.Compiler (plain text file, content: xxx=com.xxx.XxxCompiler)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxCompiler.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.common.compiler.Compiler;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxCompiler&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> Compiler {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Object &lt;span style="color:#268bd2">getExtension&lt;/span>(Class&lt;span style="color:#719e07">&amp;lt;?&amp;gt;&lt;/span> type, String name) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.common.compiler.Compiler:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxCompiler&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Configuration Center Extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/config-center/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/config-center/</guid><description>
&lt;h2 id="aim-of-design">aim of design&lt;/h2>
&lt;p>The core function of the configuration center is as Key-Value storage. The Dubbo framework informs the configuration center of the key it cares about, and the configuration center returns the value corresponding to the key.&lt;/p>
&lt;p>According to the application scenarios, the configuration center mainly undertakes the following responsibilities in the Dubbo framework:&lt;/p>
&lt;ul>
&lt;li>As an external configuration center, it stores the dubbo.properties configuration file. At this time, the key value is usually the file name such as dubbo.properties, and the value is the content of the configuration file.&lt;/li>
&lt;li>Store individual configuration items, such as various switch items, constant values, etc.&lt;/li>
&lt;li>Store service governance rules. At this time, the key is usually organized in the format of &amp;ldquo;service name + rule type&amp;rdquo;, and the value is the specific governance rule.&lt;/li>
&lt;/ul>
&lt;p>In order to further realize the group management of key-value, Dubbo&amp;rsquo;s configuration center also added the concepts of namespace and group. These concepts are reflected in many professional third-party configuration centers. Usually, namespace is used to isolate different tenants , group is used to group the key collection of the same tenant.&lt;/p>
&lt;p>Currently, the Dubbo configuration center has realized the docking of Zookeeper, Nacos, Etcd, Consul, and Apollo. Next, let’s take a look at how Dubbo’s abstract configuration center is mapped to a specific third-party implementation.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.configcenter.DynamicConfigurationFactory&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.configcenter.DynamicConfiguration&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.configcenter.support.zookeeper.ZookeeperDynamicConfigurationFactory&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.configcenter.support.nacos.NacosDynamicConfigurationFactory&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.configcenter.support.etcd.EtcdDynamicConfigurationFactory&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.configcenter.consul.ConsulDynamicConfigurationFactory&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.configcenter.support.apollo.ApolloDynamicConfigurationFactory&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.common.config.configcenter.file.FileSystemDynamicConfigurationFactory&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="implementation-principle">Implementation principle&lt;/h2>
&lt;h3 id="zookeeper">Zookeeper&lt;/h3>
&lt;p>zookeeper provides a tree-like storage model, the implementation principle is as follows:&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/dev/configcenter_zk_model.jpg" alt="image-20190127225608553">&lt;/p>
&lt;p>namespace, group, key, etc. correspond to different levels of ZNode nodes, and value is stored as the value of the root ZNode node.&lt;/p>
&lt;ol>
&lt;li>
&lt;p>External configuration center dubbo.properties&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/dev/configcenter_zk_properties.jpg" alt="image-20190127225608553">&lt;/p>
&lt;p>The figure above shows the storage structure of dubbo.properties files in two different scopes in zookeeper:&lt;/p>
&lt;ul>
&lt;li>Namespace namespace is: dubbo&lt;/li>
&lt;li>Grouping group: the global level is dubbo, shared by all applications; the application level is the application name demo-provider, which only takes effect for this application&lt;/li>
&lt;li>key: dubbo.properties&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Single configuration item&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/dev/configcenter_zk_singleitem.jpg" alt="image-20190127225608553">&lt;/p>
&lt;p>Set the graceful shutdown event to 15000:&lt;/p>
&lt;ul>
&lt;li>Namespace namespace: dubbo&lt;/li>
&lt;li>Grouping group: dubbo&lt;/li>
&lt;li>key: dubbo.service.shutdown.wait&lt;/li>
&lt;li>value: 15000&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Service Governance Rules&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/dev/configcenter_zk_rule.jpg" alt="image-20190127225608553">&lt;/p>
&lt;p>The figure above shows an application-level conditional routing rule:&lt;/p>
&lt;ul>
&lt;li>Namespace namespace: dubbo&lt;/li>
&lt;li>Grouping group: dubbo&lt;/li>
&lt;li>key: governance-conditionrouter-consumer.condition-router, where governance-conditionrouter-consumer is the application name, and condition-router represents conditional routing&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>Note:&lt;/p>
&lt;p>Dubbo supports service governance rules at two granularities of application and service at the same time. For these two granularities, the key value rules are as follows:&lt;/p>
&lt;ul>
&lt;li>Application granularity {application name + rule suffix}. Such as: &lt;code>demo-application.configurators&lt;/code>, &lt;code>demo-application.tag-router&lt;/code>, etc.&lt;/li>
&lt;li>Service granularity {service interface name:[service version]:[service group] + rule suffix}, where service version and service group are optional, if they are configured, they will be reflected in the key, if they are not configured, use &amp;quot; :&amp;ldquo;Occupy place. Such as
&lt;code>org.apache.dubbo.demo.DemoService::.configurators&lt;/code>, &lt;code>org.apache.dubbo.demo.DemoService:1.0.0:group1.configurators&lt;/code>&lt;/li>
&lt;/ul>
&lt;/blockquote>
&lt;/li>
&lt;/ol>
&lt;h3 id="etcd--consul">Etcd &amp;amp; Consul&lt;/h3>
&lt;p>Etcd and Consul are essentially a tree-like storage structure similar to zookeeper. For implementation, please refer to zookeeper.&lt;/p>
&lt;h3 id="nacos">Nacos&lt;/h3>
&lt;p>As a professional third-party configuration center, Nacos has a storage structure specially designed for configuration centers, including built-in concepts such as namespace, group, and dataid. And these concepts are basically in one-to-one correspondence with the abstract configuration center of the Dubbo framework.&lt;/p>
&lt;p>The corresponding relationship with Zookeeper implementation is as follows:&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/dev/configcenter_nacos_model.jpg" alt="image-20190127225608553">&lt;/p>
&lt;p>Referring to the example described above about the zookeeper implementation, the dataid here may be:&lt;/p>
&lt;ul>
&lt;li>External configuration center: dubbo.properties&lt;/li>
&lt;li>Single configuration item: dubbo.service.shutdown.wait&lt;/li>
&lt;li>Service governance rules: org.apache.dubbo.demo.DemoService:1.0.0:group1.configurators&lt;/li>
&lt;/ul>
&lt;h3 id="apollo">Apollo&lt;/h3>
&lt;p>Apollo is similar to Nacos, please refer to the description about Apollo in the Dynamic Configuration Center Documentation.&lt;/p></description></item><item><title>Docs3-V2: Metadata Center Extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/metadata-report/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/metadata-report/</guid><description>
&lt;h2 id="aim-of-design">aim of design&lt;/h2>
&lt;p>See the &lt;a href="../../../metadata-center/overview/">Metadata Center Manual&lt;/a>&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.metadata.store.MetadataReportFactory&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.metadata.store.MetadataReport&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;h2 id="implementation-principle">Implementation principle&lt;/h2>
&lt;h3 id="spi-definition">SPI definition&lt;/h3>
&lt;p>Reference: org.apache.dubbo.metadata.store.MetadataReportFactory, org.apache.dubbo.metadata.store.MetadataReport&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@SPI&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;redis&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">interface&lt;/span> &lt;span style="color:#268bd2">MetadataReportFactory&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Adaptive&lt;/span>({&lt;span style="color:#2aa198">&amp;#34;protocol&amp;#34;&lt;/span>})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> MetadataReport &lt;span style="color:#268bd2">getMetadataReport&lt;/span>(URL url);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="custom-metadata-storage">Custom metadata storage&lt;/h3>
&lt;p>The following uses Redis storage as an example for illustration.&lt;/p>
&lt;p>To create a new project, you need to support the following modifications:&lt;/p>
&lt;h4 id="extend-abstractmetadatareport">Extend AbstractMetadataReport&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">RedisMetadataReport&lt;/span> &lt;span style="color:#268bd2">extends&lt;/span> AbstractMetadataReport {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">private&lt;/span> &lt;span style="color:#268bd2">final&lt;/span> &lt;span style="color:#268bd2">static&lt;/span> Logger logger &lt;span style="color:#719e07">=&lt;/span> LoggerFactory. &lt;span style="color:#268bd2">getLogger&lt;/span>(RedisMetadataReport. &lt;span style="color:#268bd2">class&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">final&lt;/span> JedisPool pool;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">RedisMetadataReport&lt;/span>(URL url) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">super&lt;/span>(url);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> pool &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#719e07">new&lt;/span> JedisPool(&lt;span style="color:#719e07">new&lt;/span> JedisPoolConfig(), url. &lt;span style="color:#268bd2">getHost&lt;/span>(), url. &lt;span style="color:#268bd2">getPort&lt;/span>());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Override&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">protected&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">doStoreProviderMetadata&lt;/span>(ProviderMetadataIdentifier providerMetadataIdentifier, String serviceDefinitions) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">this&lt;/span>.storeMetadata(providerMetadataIdentifier, serviceDefinitions);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Override&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">protected&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">doStoreConsumerMetadata&lt;/span>(ConsumerMetadataIdentifier consumerMetadataIdentifier, String value) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">this&lt;/span>.storeMetadata(consumerMetadataIdentifier, value);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">private&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">storeMetadata&lt;/span>(MetadataIdentifier metadataIdentifier, String v) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">try&lt;/span> (Jedis jedis &lt;span style="color:#719e07">=&lt;/span> pool. &lt;span style="color:#268bd2">getResource&lt;/span>()) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> jedis.set(metadataIdentifier.getIdentifierKey() &lt;span style="color:#719e07">+&lt;/span> META_DATA_SOTRE_TAG, v);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> } &lt;span style="color:#719e07">catch&lt;/span> (Throwable e) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> logger.error(&lt;span style="color:#2aa198">&amp;#34;Failed to put &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> metadataIdentifier &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34; to redis &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> v &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34;, cause: &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> e.getMessage(), e);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">throw&lt;/span> &lt;span style="color:#719e07">new&lt;/span> RpcException(&lt;span style="color:#2aa198">&amp;#34;Failed to put &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> metadataIdentifier &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34; to redis &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> v &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34;, cause: &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> e.getMessage(), e);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="extends-abstractmetadatareportfactory">Extends AbstractMetadataReportFactory&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">RedisMetadataReportFactory&lt;/span> &lt;span style="color:#268bd2">extends&lt;/span> AbstractMetadataReportFactory {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Override&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> MetadataReport &lt;span style="color:#268bd2">createMetadataReport&lt;/span>(URL url) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> &lt;span style="color:#719e07">new&lt;/span> RedisMetadataReport(url);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="add-metadatareportfactory">Add MetadataReportFactory&lt;/h4>
&lt;blockquote>
&lt;p>META-INF/dubbo/internal/org.apache.dubbo.metadata.store.MetadataReportFactory&lt;/p>
&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>redis&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">org.apache.dubbo.metadata.store.redis.RedisMetadataReportFactory&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Just pack the above modification and project into a jar package, and then configure the url of the metadata center: redis://10.20.153.10:6379.&lt;/p>
&lt;p>At this point, a custom metadata store is ready to run.&lt;/p></description></item><item><title>Docs3-V2: Message Dispatch Extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/dispatcher/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/dispatcher/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>Channel information dispatcher, used to specify the thread pool model.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.remoting.Dispatcher&lt;/code>&lt;/p>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> dispatcher=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- The default value setting, when &amp;lt;dubbo:protocol&amp;gt; does not configure the dispatcher attribute, use this configuration --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:provider&lt;/span> dispatcher=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.remoting.transport.dispatcher.all.AllDispatcher&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.remoting.transport.dispatcher.direct.DirectDispatcher&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.remoting.transport.dispatcher.message.MessageOnlyDispatcher&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.remoting.transport.dispatcher.execution.ExecutionDispatcher&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.remoting.transport.dispatcher.connection.ConnectionOrderedDispatcher&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxDispatcher.java (implements the Dispatcher interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.remoting.Dispatcher (plain text file, content: xxx=com.xxx.XxxDispatcher)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxDispatcher.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.remoting.Dispatcher;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxDispatcher&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> Dispatcher {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Group &lt;span style="color:#268bd2">lookup&lt;/span>(URL url) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.remoting.Dispatcher:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxDispatcher&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Thread Pool Extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/threadpool/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/threadpool/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>The service provider&amp;rsquo;s thread pool implements the strategy. When the server receives a request, it needs to create a thread in the thread pool to execute the service provider&amp;rsquo;s business logic.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.common.threadpool.ThreadPool&lt;/code>&lt;/p>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> threadpool=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- Default value setting, when &amp;lt;dubbo:protocol&amp;gt; does not configure threadpool, use this configuration --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:provider&lt;/span> threadpool=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.common.threadpool.FixedThreadPool&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.common.threadpool.CachedThreadPool&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxThreadPool.java (implement ThreadPool interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.common.threadpool.ThreadPool (plain text file, content: xxx=com.xxx.XxxThreadPool)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxThreadPool.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.common.threadpool.ThreadPool;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> java.util.concurrent.Executor;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxThreadPool&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> ThreadPool {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Executor &lt;span style="color:#268bd2">getExecutor&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.common.threadpool.ThreadPool:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxThreadPool&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Serialization Extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/serialize/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/serialize/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>Convert the object into a byte stream for network transmission, and convert the byte stream into an object for restoring the byte stream data into an object.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.common.serialize.Serialization&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.common.serialize.ObjectInput&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.common.serialize.ObjectOutput&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- Protocol serialization method --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> serialization=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- Default value setting, when &amp;lt;dubbo:protocol&amp;gt; does not configure serialization, use this configuration --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:provider&lt;/span> serialization=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.common.serialize.dubbo.DubboSerialization&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.common.serialize.hessian.Hessian2Serialization&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.common.serialize.java.JavaSerialization&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.common.serialize.java.CompactedJavaSerialization&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxSerialization.java (implements the Serialization interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxObjectInput.java (implement ObjectInput interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxObjectOutput.java (implement ObjectOutput interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.common.serialize.Serialization (plain text file, content: xxx=com.xxx.XxxSerialization)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxSerialization.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.common.serialize.Serialization;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.common.serialize.ObjectInput;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.common.serialize.ObjectOutput;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxSerialization&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> Serialization {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> ObjectOutput &lt;span style="color:#268bd2">serialize&lt;/span>(Parameters parameters, OutputStream output) &lt;span style="color:#268bd2">throws&lt;/span> IOException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> &lt;span style="color:#719e07">new&lt;/span> XxxObjectOutput(output);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> ObjectInput &lt;span style="color:#268bd2">deserialize&lt;/span>(Parameters parameters, InputStream input) &lt;span style="color:#268bd2">throws&lt;/span> IOException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> &lt;span style="color:#719e07">new&lt;/span> XxxObjectInput(input);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.common.serialize.Serialization:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxSerialization&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Network Transport Extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/remoting/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/remoting/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>Realization of remote communication server and client transmission.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.remoting.Transporter&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.remoting.Server&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.remoting.Client&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- server and client use the same transport implementation --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> transporter=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- server and client use different transport implementations --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> server=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> client=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- Default value setting, when &amp;lt;dubbo:protocol&amp;gt; is not configured with transporter/server/client attribute, use this configuration --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:provider&lt;/span> transporter=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> server=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> client=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.remoting.transport.transporter.netty.NettyTransporter&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.remoting.transport.transporter.mina.MinaTransporter&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.remoting.transport.transporter.grizzly.GrizzlyTransporter&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxTransporter.java (implements the Transporter interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxServer.java (implement Server interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxClient.java (implement Client interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.remoting.Transporter (plain text file, content: xxx=com.xxx.XxxTransporter)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxTransporter.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.remoting.Transporter;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxTransporter&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> Transporter {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Server &lt;span style="color:#268bd2">bind&lt;/span>(URL url, ChannelHandler handler) &lt;span style="color:#268bd2">throws&lt;/span> RemotingException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> &lt;span style="color:#719e07">new&lt;/span> XxxServer(url, handler);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Client &lt;span style="color:#268bd2">connect&lt;/span>(URL url, ChannelHandler handler) &lt;span style="color:#268bd2">throws&lt;/span> RemotingException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> &lt;span style="color:#719e07">new&lt;/span> XxxClient(url, handler);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxServer.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.remoting.transport.transporter.AbstractServer;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxServer&lt;/span> &lt;span style="color:#268bd2">extends&lt;/span> AbstractServer {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">XxxServer&lt;/span>(URL url, ChannelHandler handler) &lt;span style="color:#268bd2">throws&lt;/span> RemotingException{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">super&lt;/span>(url, handler);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">protected&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">doOpen&lt;/span>() &lt;span style="color:#268bd2">throws&lt;/span> Throwable {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">protected&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">doClose&lt;/span>() &lt;span style="color:#268bd2">throws&lt;/span> Throwable {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Collection&lt;span style="color:#719e07">&amp;lt;&lt;/span>Channel&lt;span style="color:#719e07">&amp;gt;&lt;/span> &lt;span style="color:#268bd2">getChannels&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Channel &lt;span style="color:#268bd2">getChannel&lt;/span>(InetSocketAddress remoteAddress) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxClient.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.remoting.transport.transporter.AbstractClient;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxClient&lt;/span> &lt;span style="color:#268bd2">extends&lt;/span> AbstractClient {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">XxxServer&lt;/span>(URL url, ChannelHandler handler) &lt;span style="color:#268bd2">throws&lt;/span> RemotingException{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">super&lt;/span>(url, handler);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">protected&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">doOpen&lt;/span>() &lt;span style="color:#268bd2">throws&lt;/span> Throwable {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">protected&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">doClose&lt;/span>() &lt;span style="color:#268bd2">throws&lt;/span> Throwable {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">protected&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">doConnect&lt;/span>() &lt;span style="color:#268bd2">throws&lt;/span> Throwable {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Channel &lt;span style="color:#268bd2">getChannel&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.remoting.Transporter:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxTransporter&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Information Exchange Extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/exchanger/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/exchanger/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>Based on the transport layer, implement the Request-Response information exchange semantics.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.remoting.exchange.Exchanger&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.remoting.exchange.ExchangeServer&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.remoting.exchange.ExchangeClient&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> exchanger=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- The default value setting, when &amp;lt;dubbo:protocol&amp;gt; does not configure the exchanger attribute, use this configuration --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:provider&lt;/span> exchanger=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.remoting.exchange.exchanger.HeaderExchanger&lt;/code>&lt;/p>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxExchanger.java (implements the Exchanger interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxExchangeServer.java (implements ExchangeServer interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxExchangeClient.java (implements ExchangeClient interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.remoting.exchange.Exchanger (plain text file, content: xxx=com.xxx.XxxExchanger)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxExchanger.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.remoting.exchange.Exchanger;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxExchanger&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> Exchanger {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> ExchangeServer &lt;span style="color:#268bd2">bind&lt;/span>(URL url, ExchangeHandler handler) &lt;span style="color:#268bd2">throws&lt;/span> RemotingException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> &lt;span style="color:#719e07">new&lt;/span> XxxExchangeServer(url, handler);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> ExchangeClient &lt;span style="color:#268bd2">connect&lt;/span>(URL url, ExchangeHandler handler) &lt;span style="color:#268bd2">throws&lt;/span> RemotingException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> &lt;span style="color:#719e07">new&lt;/span> XxxExchangeClient(url, handler);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxExchangeServer.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.remoting.exchange.ExchangeServer;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxExchangeServer&lt;/span> impelements ExchangeServer {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxExchangeClient.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.remoting.exchange.ExchangeClient;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxExchangeClient&lt;/span> impelments ExchangeClient {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.remoting.exchange.Exchanger:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxExchanger&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Network Expansion</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/networker/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/networker/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>Peer-to-peer network node builder.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.remoting.p2p.Networker&lt;/code>&lt;/p>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> networker=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- The default value setting, when &amp;lt;dubbo:protocol&amp;gt; does not configure the networker attribute, use this configuration --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:provider&lt;/span> networker=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.remoting.p2p.support.MulticastNetworker&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.remoting.p2p.support.FileNetworker&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxNetworker.java (implement Networker interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.remoting.p2p.Networker (plain text file, content: xxx=com.xxx.XxxNetworker)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxNetworker.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.remoting.p2p.Networker;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxNetworker&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> Networker {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Group &lt;span style="color:#268bd2">lookup&lt;/span>(URL url) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.remoting.p2p.Networker:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxNetworker&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Peer-to-peer network node builder extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/page/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/page/</guid><description>
&lt;h1 id="page-extension">page extension&lt;/h1>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>Peer-to-peer network node builder.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.container.page.PageHandler&lt;/code>&lt;/p>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> page=&lt;span style="color:#2aa198">&amp;#34;xxx,yyy&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- The default value setting, when &amp;lt;dubbo:protocol&amp;gt; does not configure the page attribute, use this configuration --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:provider&lt;/span> page=&lt;span style="color:#2aa198">&amp;#34;xxx,yyy&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.container.page.pages.HomePageHandler&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.container.page.pages.StatusPageHandler&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.container.page.pages.LogPageHandler&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.container.page.pages.SystemPageHandler&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxPageHandler.java (implement PageHandler interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.container.page.PageHandler (plain text file, content: xxx=com.xxx.XxxPageHandler)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxPageHandler.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.container.page.PageHandler;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxPageHandler&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> PageHandler {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Group &lt;span style="color:#268bd2">lookup&lt;/span>(URL url) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.container.page.PageHandler:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxPageHandler&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Telnet Command Extensions</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/telnet-handler/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/telnet-handler/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>All servers support telnet access for manual intervention.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.remoting.telnet.TelnetHandler&lt;/code>&lt;/p>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> telnet=&lt;span style="color:#2aa198">&amp;#34;xxx,yyy&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- The default value setting, when &amp;lt;dubbo:protocol&amp;gt; does not configure the telnet attribute, use this configuration --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:provider&lt;/span> telnet=&lt;span style="color:#2aa198">&amp;#34;xxx,yyy&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.remoting.telnet.support.ClearTelnetHandler&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.remoting.telnet.support.ExitTelnetHandler&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.remoting.telnet.support.HelpTelnetHandler&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.remoting.telnet.support.StatusTelnetHandler&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.dubbo.telnet.ListTelnetHandler&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.dubbo.telnet.ChangeTelnetHandler&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.dubbo.telnet.CurrentTelnetHandler&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.dubbo.telnet.InvokeTelnetHandler&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.dubbo.telnet.TraceTelnetHandler&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.dubbo.telnet.CountTelnetHandler&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.dubbo.telnet.PortTelnetHandler&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxTelnetHandler.java (implement TelnetHandler interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.remoting.telnet.TelnetHandler (plain text file, content: xxx=com.xxx.XxxTelnetHandler)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxTelnetHandler.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.remoting.telnet.TelnetHandler;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@Help&lt;/span>(parameter&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">&amp;#34;...&amp;#34;&lt;/span>, summary&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">&amp;#34;...&amp;#34;&lt;/span>, detail&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">&amp;#34;...&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxTelnetHandler&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> TelnetHandler {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> String &lt;span style="color:#268bd2">telnet&lt;/span>(Channel channel, String message) &lt;span style="color:#268bd2">throws&lt;/span> RemotingException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.remoting.telnet.TelnetHandler:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxTelnetHandler&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="usage">Usage&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>telnet 127.0.0.1 &lt;span style="color:#2aa198">20880&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>dubbo&amp;gt; xxx args
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Status Check Extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/status-checker/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/status-checker/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>Check the status of various resources that the service relies on. This status check can be used for both telnet&amp;rsquo;s status command and hosting&amp;rsquo;s status page.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.common.status.StatusChecker&lt;/code>&lt;/p>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:protocol&lt;/span> status=&lt;span style="color:#2aa198">&amp;#34;xxx,yyy&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- The default value setting, when &amp;lt;dubbo:protocol&amp;gt; does not configure the status attribute, use this configuration --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:provider&lt;/span> status=&lt;span style="color:#2aa198">&amp;#34;xxx,yyy&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.common.status.support.MemoryStatusChecker&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.common.status.support.LoadStatusChecker&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.dubbo.status.ServerStatusChecker&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.dubbo.status.ThreadPoolStatusChecker&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.registry.directory.RegistryStatusChecker&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.config.spring.status.SpringStatusChecker&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.rpc.config.spring.status.DataSourceStatusChecker&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxStatusChecker.java (implement StatusChecker interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.common.status.StatusChecker (plain text file, content: xxx=com.xxx.XxxStatusChecker)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxStatusChecker.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.common.status.StatusChecker;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxStatusChecker&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> StatusChecker {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Status &lt;span style="color:#268bd2">check&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.common.status.StatusChecker:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxStatusChecker&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Container Extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/container/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/container/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>Service container extension for custom loading content.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.container.Container&lt;/code>&lt;/p>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>java org.apache.dubbo.container.Main spring jetty log4j
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.container.spring.SpringContainer&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.container.spring.JettyContainer&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.container.spring.Log4jContainer&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxContainer.java (implements the Container interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.container.Container (plain text file, content: xxx=com.xxx.XxxContainer)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxContainer.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>org.apache.dubbo.container.Container;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxContainer&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> Container {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Status &lt;span style="color:#268bd2">start&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Status &lt;span style="color:#268bd2">stop&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.container.Container:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxContainer&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Cache Extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/cache/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/cache/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>Use the request parameter as the key to cache the returned result.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.cache.CacheFactory&lt;/code>&lt;/p>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:service&lt;/span> cache=&lt;span style="color:#2aa198">&amp;#34;lru&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- method level cache --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:service&amp;gt;&amp;lt;dubbo:method&lt;/span> cache=&lt;span style="color:#2aa198">&amp;#34;lru&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&amp;lt;/dubbo:service&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- The default value setting, when &amp;lt;dubbo:service&amp;gt; does not configure the cache attribute, use this configuration --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:provider&lt;/span> cache=&lt;span style="color:#2aa198">&amp;#34;xxx,yyy&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.cache.support.lru.LruCacheFactory&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.cache.support.threadlocal.ThreadLocalCacheFactory&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.cache.support.jcache.JCacheFactory&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxCacheFactory.java (implements the CacheFactory interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.cache.CacheFactory (plain text file, content: xxx=com.xxx.XxxCacheFactory)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxCacheFactory.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.cache.CacheFactory;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxCacheFactory&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> CacheFactory {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Cache &lt;span style="color:#268bd2">getCache&lt;/span>(URL url, String name) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> &lt;span style="color:#719e07">new&lt;/span> XxxCache(url, name);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxCache.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.cache.Cache;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxCache&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> Cache {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">Cache&lt;/span>(URL url, String name) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">put&lt;/span>(Object key, Object value) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Object &lt;span style="color:#268bd2">get&lt;/span>(Object key) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.cache.CacheFactory:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxCacheFactory&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Authentication Extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/validation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/validation/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>Parameter validation extension point.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.validation.Validation&lt;/code>&lt;/p>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:service&lt;/span> validation=&lt;span style="color:#2aa198">&amp;#34;xxx,yyy&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">&amp;lt;!-- The default value setting, when &amp;lt;dubbo:service&amp;gt; does not configure the authentication attribute, use this configuration --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:provider&lt;/span> validation=&lt;span style="color:#2aa198">&amp;#34;xxx,yyy&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.validation.support.jvalidation.JValidation&lt;/code>&lt;/p>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxValidation.java (implement Validation interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.validation.Validation (plain text file, content: xxx=com.xxx.XxxValidation)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxValidation.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.validation.Validation;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxValidation&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> Validation {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Object &lt;span style="color:#268bd2">getValidator&lt;/span>(URL url) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxValidator.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.validation.Validator;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxValidator&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> Validator {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">XxxValidator&lt;/span>(URL url) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">validate&lt;/span>(Invocation invocation) &lt;span style="color:#268bd2">throws&lt;/span> Exception {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.validation.Validation:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxValidation&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Log Adaptation Extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/logger-adapter/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/logger-adapter/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>Log output adaptation extension point.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.common.logger.LoggerAdapter&lt;/code>&lt;/p>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:application&lt;/span> logger=&lt;span style="color:#2aa198">&amp;#34;xxx&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>or:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>-Ddubbo:application.logger&lt;span style="color:#719e07">=&lt;/span>xxx
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="known-extensions">Known extensions&lt;/h2>
&lt;ul>
&lt;li>&lt;code>org.apache.dubbo.common.logger.slf4j.Slf4jLoggerAdapter&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.common.logger.jcl.JclLoggerAdapter&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.common.logger.log4j.Log4jLoggerAdapter&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.common.logger.log4j2.Log4j2LoggerAdapter&lt;/code>&lt;/li>
&lt;li>&lt;code>org.apache.dubbo.common.logger.jdk.JdkLoggerAdapter&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxLoggerAdapter.java (implement LoggerAdapter interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.common.logger.LoggerAdapter (plain text file, content: xxx=com.xxx.XxxLoggerAdapter)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxLoggerAdapter.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.common.logger.LoggerAdapter;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxLoggerAdapter&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> LoggerAdapter {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> Logger &lt;span style="color:#268bd2">getLogger&lt;/span>(URL url) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxLogger.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.common.logger.Logger;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxLogger&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> Logger {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">XxxLogger&lt;/span>(URL url) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">info&lt;/span>(String msg) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.common.logger.LoggerAdapter:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>xxx&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxLoggerAdapter&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: QoS Anonymous Access Verification Extension</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/qos-permission/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/qos-permission/</guid><description>
&lt;h2 id="expansion-description">Expansion Description&lt;/h2>
&lt;p>QoS anonymous access authentication extension point.&lt;/p>
&lt;h2 id="extension-ports">Extension ports&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.qos.permission.PermissionChecker&lt;/code>&lt;/p>
&lt;h2 id="extended-configuration">Extended configuration&lt;/h2>
&lt;p>Dubbo QoS &lt;code>dubbo.application.qos-anonymous-access-permission-level&lt;/code> Anonymous access permission verification.&lt;/p>
&lt;h2 id="default-implementation">Default implementation&lt;/h2>
&lt;p>&lt;code>org.apache.dubbo.qos.permission.DefaultAnonymousAccessPermissionChecker&lt;/code>&lt;/p>
&lt;h2 id="extended-example">Extended example&lt;/h2>
&lt;p>Maven project structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-main
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-com
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-xxx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-XxxPermissionChecker.java (implements PermissionChecker interface)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-META-INF
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> |-org.apache.dubbo.qos.permission.PermissionChecker` (plain text file, content: qosPermissionChecker=com.xxx.XxxPermissionChecker)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>XxxPermissionChecker.java:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> com.xxx.qos.permission;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.qos.permission.PermissionChecker;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">XxxAnonymousAccessPermissionChecker&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> PermissionChecker {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Override&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">boolean&lt;/span> &lt;span style="color:#268bd2">access&lt;/span>(CommandContext commandContext, PermissionLevel defaultCmdRequiredPermissionLevel) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">//...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>META-INF/dubbo/org.apache.dubbo.qos.permission.PermissionChecker:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-properties" data-lang="properties">&lt;span style="display:flex;">&lt;span>qosPermissionChecker&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">com.xxx.XxxPermissionChecker&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs3-V2: Extension Point Development Guide</title><link>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/dubbo-spi/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/en/docs3-v2/java-sdk/reference-manual/spi/description/dubbo-spi/</guid><description>
&lt;h2 id="1-introduction">1 Introduction&lt;/h2>
&lt;p>The full name of SPI is Service Provider Interface, which is a service discovery mechanism. The essence of SPI is to configure the fully qualified name of the interface implementation class in the file, and the service loader reads the configuration file and loads the implementation class. In this way, the implementation class can be dynamically replaced for the interface at runtime. Because of this feature, we can easily provide extended functions for our programs through the SPI mechanism. The SPI mechanism is also used in third-party frameworks. For example, Dubbo loads all components through the SPI mechanism. However, Dubbo does not use Java&amp;rsquo;s native SPI mechanism, but enhances it to better meet the needs. In Dubbo, SPI is a very important module. Based on SPI, we can easily expand Dubbo.
In Dubbo, SPI has two main usages, one is to load fixed extension classes, and the other is to load adaptive extension classes. These two methods will be described in detail below.
Special attention should be paid to: In Dubbo, classes loaded based on SPI extensions are singletons.&lt;/p>
&lt;h3 id="11-load-fixed-extension-classes">1.1 Load fixed extension classes&lt;/h3>
&lt;p>If you were asked to design and load fixed extension classes, what would you do?
A common idea is to read the configuration file in a specific directory, then parse out the full class name, instantiate the class through the reflection mechanism, and then store the class in the collection. If necessary, directly from the collection Take. The implementation in Dubbo is also such an idea.
However, in Dubbo, the implementation is more complete, and it implements the functions of IOC and AOP. IOC means that if this extended class depends on other properties, Dubbo will automatically inject this property. How is this function implemented? A common idea is to get the setter of this extended class
method, call the setter method for property injection. What does AOP refer to? This means that Dubbo can inject its wrapper class into the extension class. For example, DubboProtocol is an extension class of Protocol, and ProtocolListenerWrapper is a wrapper class of DubboProtocol.&lt;/p>
&lt;h3 id="12-load-adaptive-extension-class">1.2 Load adaptive extension class&lt;/h3>
&lt;p>First explain the usage scenarios of adaptive extension classes. For example, we have a requirement that when calling a certain method, we can call different implementation classes based on parameter selection. Somewhat similar to the factory method, different instance objects are constructed based on different parameters.
The idea of implementation in Dubbo is similar to this, but the implementation of Dubbo is more flexible, and its implementation is somewhat similar to the strategy mode. Each extension class is equivalent to a strategy. Based on the URL message bus, the parameters are passed to the ExtensionLoader, and the corresponding extension class is loaded based on the parameters through the ExtensionLoader to realize the dynamic call to the target instance at runtime.&lt;/p>
&lt;h2 id="2-dubbo-spi-source-code-analysis">2. Dubbo SPI source code analysis&lt;/h2>
&lt;h3 id="21-load-fixed-extension-class">2.1 Load fixed extension class&lt;/h3>
&lt;p>In Dubbo, the entry point for SPI to load fixed extension classes is the getExtension method of ExtensionLoader. Next, we will analyze the process of obtaining extension class objects in detail.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> T &lt;span style="color:#268bd2">getExtension&lt;/span>(String name) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (name &lt;span style="color:#719e07">==&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span> &lt;span style="color:#719e07">||&lt;/span> name. &lt;span style="color:#268bd2">length&lt;/span>() &lt;span style="color:#719e07">==&lt;/span> 0)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">throw&lt;/span> &lt;span style="color:#719e07">new&lt;/span> IllegalArgumentException(&lt;span style="color:#2aa198">&amp;#34;Extension name == null&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (&lt;span style="color:#2aa198">&amp;#34;true&amp;#34;&lt;/span>.equals(name)) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Get the default extension implementation class&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> getDefaultExtension();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Holder, as the name suggests, is used to hold the target object&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Holder&lt;span style="color:#719e07">&amp;lt;&lt;/span>Object&lt;span style="color:#719e07">&amp;gt;&lt;/span> holder &lt;span style="color:#719e07">=&lt;/span> cachedInstances. &lt;span style="color:#268bd2">get&lt;/span>(name);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// This logic ensures that only one thread can create a Holder object&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (holder &lt;span style="color:#719e07">==&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> cachedInstances. &lt;span style="color:#268bd2">putIfAbsent&lt;/span>(name, &lt;span style="color:#719e07">new&lt;/span> Holder&lt;span style="color:#719e07">&amp;lt;&lt;/span>Object&lt;span style="color:#719e07">&amp;gt;&lt;/span>());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> holder &lt;span style="color:#719e07">=&lt;/span> cachedInstances. &lt;span style="color:#268bd2">get&lt;/span>(name);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Object instance &lt;span style="color:#719e07">=&lt;/span> holder. &lt;span style="color:#268bd2">get&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// double check&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (instance &lt;span style="color:#719e07">==&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">synchronized&lt;/span> (holder) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> instance &lt;span style="color:#719e07">=&lt;/span> holder. &lt;span style="color:#268bd2">get&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (instance &lt;span style="color:#719e07">==&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// create extension instance&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> instance &lt;span style="color:#719e07">=&lt;/span> createExtension(name);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// set the instance to the holder&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> holder.set(instance);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> (T) instance;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The logic of the above code is relatively simple. First, the cache is checked, and if the cache misses, an extended object is created. Let&amp;rsquo;s take a look at the process of creating an extended object.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">private&lt;/span> T &lt;span style="color:#268bd2">createExtension&lt;/span>(String name, &lt;span style="color:#dc322f">boolean&lt;/span> wrap) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Load all extension classes from the configuration file to get the mapping relationship table from &amp;#34;configuration item name&amp;#34; to &amp;#34;configuration class&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Class&lt;span style="color:#719e07">&amp;lt;?&amp;gt;&lt;/span> clazz &lt;span style="color:#719e07">=&lt;/span> getExtensionClasses().get(name);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// If there is no extension of the interface, or the implementation class of the interface does not allow repetition but actually repeats, an exception is thrown directly&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (clazz &lt;span style="color:#719e07">==&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span> &lt;span style="color:#719e07">||&lt;/span> unacceptableExceptions. &lt;span style="color:#268bd2">contains&lt;/span>(name)) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">throw&lt;/span> findException(name);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">try&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> T instance &lt;span style="color:#719e07">=&lt;/span> (T) EXTENSION_INSTANCES. &lt;span style="color:#268bd2">get&lt;/span>(clazz);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// This code ensures that the extended class will only be constructed once, which is a singleton.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (instance &lt;span style="color:#719e07">==&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> EXTENSION_INSTANCES.putIfAbsent(clazz, clazz.getDeclaredConstructor().newInstance());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> instance &lt;span style="color:#719e07">=&lt;/span> (T) EXTENSION_INSTANCES. &lt;span style="color:#268bd2">get&lt;/span>(clazz);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Inject dependencies into the instance&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> injectExtension(instance);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Automatically wrap if wrapping is enabled.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// For example, I defined the extension of DubboProtocol based on Protocol, but in fact, DubboProtocol is not directly used in Dubbo, but its wrapper class&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// ProtocolListenerWrapper&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (wrap) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> List&lt;span style="color:#719e07">&amp;lt;&lt;/span>Class&lt;span style="color:#719e07">&amp;lt;?&amp;gt;&amp;gt;&lt;/span> wrapperClassesList &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#719e07">new&lt;/span> ArrayList&lt;span style="color:#719e07">&amp;lt;&amp;gt;&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (cachedWrapperClasses &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> wrapperClassesList.addAll(cachedWrapperClasses);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> wrapperClassesList.sort(WrapperComparator. COMPARATOR);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Collections. &lt;span style="color:#268bd2">reverse&lt;/span>(wrapperClassesList);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Loop to create Wrapper instances&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (CollectionUtils. &lt;span style="color:#268bd2">isNotEmpty&lt;/span>(wrapperClassesList)) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">for&lt;/span> (Class&lt;span style="color:#719e07">&amp;lt;?&amp;gt;&lt;/span> wrapperClass : wrapperClassesList) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Wrapper wrapper &lt;span style="color:#719e07">=&lt;/span> wrapperClass. &lt;span style="color:#268bd2">getAnnotation&lt;/span>(Wrapper. &lt;span style="color:#268bd2">class&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">if&lt;/span> (wrapper &lt;span style="color:#719e07">==&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">||&lt;/span> (ArrayUtils.contains(wrapper.matches(), name) &lt;span style="color:#719e07">&amp;amp;&amp;amp;&lt;/span> &lt;span style="color:#719e07">!&lt;/span>ArrayUtils.contains(wrapper.mismatches(), name))) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Pass the current instance as a parameter to the constructor of Wrapper, and create a Wrapper instance through reflection.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Then inject dependencies into the Wrapper instance, and finally assign the Wrapper instance to the instance variable again&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> instance &lt;span style="color:#719e07">=&lt;/span> injectExtension((T) wrapperClass. &lt;span style="color:#268bd2">getConstructor&lt;/span>(type). newInstance(instance));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// initialization&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> initExtension(instance);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> instance;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> } &lt;span style="color:#719e07">catch&lt;/span> (Throwable t) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">throw&lt;/span> &lt;span style="color:#719e07">new&lt;/span> IllegalStateException(&lt;span style="color:#2aa198">&amp;#34;Extension instance (name: &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> name &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34;, class: &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> type &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34;) couldn&amp;#39;t be instantiated: &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> t. &lt;span style="color:#268bd2">getMessage&lt;/span>(), t);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The logic of the createExtension method is a little more complicated, including the following steps:&lt;/p>
&lt;ol>
&lt;li>Get all extension classes through getExtensionClasses&lt;/li>
&lt;li>Create an extended object through reflection&lt;/li>
&lt;li>Inject dependencies into extended objects&lt;/li>
&lt;li>Wrap the extension object in the corresponding Wrapper object&lt;/li>
&lt;li>Initialize the extension object&lt;/li>
&lt;/ol>
&lt;p>Among the above steps, the first step is the key to loading the extension class, and the third and fourth steps are the specific implementation of Dubbo IOC and AOP. In the following chapters, we will focus on analyzing the logic of the getExtensionClasses method and briefly introduce the specific implementation of Dubbo IOC.&lt;/p>
&lt;h3 id="211-get-all-extension-classes">2.1.1 Get all extension classes&lt;/h3>
&lt;p>Before we obtain the extension class by name, we first need to parse out the mapping relationship table from the extension item name to the extension class (Map&amp;lt;name, extension class&amp;gt;) according to the configuration file, and then extract it from the mapping relationship table according to the extension item name The corresponding extension class can be. The code analysis of the relevant process is as follows:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">private&lt;/span> Map&lt;span style="color:#719e07">&amp;lt;&lt;/span>String, Class&lt;span style="color:#719e07">&amp;lt;?&amp;gt;&amp;gt;&lt;/span> getExtensionClasses() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Get the loaded extension class from the cache&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Map&lt;span style="color:#719e07">&amp;lt;&lt;/span>String, Class&lt;span style="color:#719e07">&amp;lt;?&amp;gt;&amp;gt;&lt;/span> classes &lt;span style="color:#719e07">=&lt;/span> cachedClasses. &lt;span style="color:#268bd2">get&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// double check&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (classes &lt;span style="color:#719e07">==&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">synchronized&lt;/span> (cachedClasses) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> classes &lt;span style="color:#719e07">=&lt;/span> cachedClasses. &lt;span style="color:#268bd2">get&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (classes &lt;span style="color:#719e07">==&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// load extension class&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> classes &lt;span style="color:#719e07">=&lt;/span> loadExtensionClasses();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> cachedClasses.set(classes);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> classes;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Here is also to check the cache first, and if the cache misses, lock it through synchronized. After locking, check the cache again and find it empty. At this time, if classes is still null, the extension class is loaded through loadExtensionClasses. Let&amp;rsquo;s analyze the logic of the loadExtensionClasses method.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">private&lt;/span> Map&lt;span style="color:#719e07">&amp;lt;&lt;/span>String, Class&lt;span style="color:#719e07">&amp;lt;?&amp;gt;&amp;gt;&lt;/span> loadExtensionClasses() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Cache the default SPI extension&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> cacheDefaultExtensionName();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Map&lt;span style="color:#719e07">&amp;lt;&lt;/span>String, Class&lt;span style="color:#719e07">&amp;lt;?&amp;gt;&amp;gt;&lt;/span> extensionClasses &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#719e07">new&lt;/span> HashMap&lt;span style="color:#719e07">&amp;lt;&amp;gt;&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Load the files in the specified folder based on the policy&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Currently there are four strategies to read the configuration files in META-INF/services/ META-INF/dubbo/ META-INF/dubbo/internal/ META-INF/dubbo/external/ respectively&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">for&lt;/span> (LoadingStrategy strategy : strategies) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> loadDirectory(extensionClasses, strategy.directory(), type.getName(), strategy.preferExtensionClassLoader(), strategy.overridden(), strategy.excludedPackages());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> loadDirectory(extensionClasses, strategy.directory(), type.getName().replace(&lt;span style="color:#2aa198">&amp;#34;org.apache&amp;#34;&lt;/span>, &lt;span style="color:#2aa198">&amp;#34;com.alibaba&amp;#34;&lt;/span>), strategy.preferExtensionClassLoader(), strategy.overridden(), strategy.excludedPackages());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> extensionClasses;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The loadExtensionClasses method does two things in total, one is to parse the SPI annotations, and the other is to call the loadDirectory method to load the specified folder configuration file. The process of parsing SPI annotations is relatively simple, so there is no need to say more. Let&amp;rsquo;s take a look at what loadDirectory does.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">private&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">loadDirectory&lt;/span>(Map&lt;span style="color:#719e07">&amp;lt;&lt;/span>String, Class&lt;span style="color:#719e07">&amp;lt;?&amp;gt;&amp;gt;&lt;/span> extensionClasses, String dir, String type,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">boolean&lt;/span> extensionLoaderClassLoaderFirst, &lt;span style="color:#dc322f">boolean&lt;/span> overridden, String... excludedPackages) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// fileName = folder path + type fully qualified name&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> String fileName &lt;span style="color:#719e07">=&lt;/span> dir &lt;span style="color:#719e07">+&lt;/span> type;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">try&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Enumeration&lt;span style="color:#719e07">&amp;lt;&lt;/span>java.net. URL&lt;span style="color:#719e07">&amp;gt;&lt;/span> urls &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ClassLoader classLoader &lt;span style="color:#719e07">=&lt;/span> findClassLoader();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// try to load from ExtensionLoader&amp;#39;s ClassLoader first&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (extensionLoaderClassLoaderFirst) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ClassLoader extensionLoaderClassLoader &lt;span style="color:#719e07">=&lt;/span> ExtensionLoader. &lt;span style="color:#268bd2">class&lt;/span>. &lt;span style="color:#268bd2">getClassLoader&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (ClassLoader. &lt;span style="color:#268bd2">getSystemClassLoader&lt;/span>() &lt;span style="color:#719e07">!=&lt;/span> extensionLoaderClassLoader) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> urls &lt;span style="color:#719e07">=&lt;/span> extensionLoaderClassLoader. &lt;span style="color:#268bd2">getResources&lt;/span>(fileName);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Load all files with the same name according to the file name&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (urls &lt;span style="color:#719e07">==&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span> &lt;span style="color:#719e07">||&lt;/span> &lt;span style="color:#719e07">!&lt;/span>urls.hasMoreElements()) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (classLoader &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> urls &lt;span style="color:#719e07">=&lt;/span> classLoader. &lt;span style="color:#268bd2">getResources&lt;/span>(fileName);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> } &lt;span style="color:#719e07">else&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> urls &lt;span style="color:#719e07">=&lt;/span> ClassLoader. &lt;span style="color:#268bd2">getSystemResources&lt;/span>(fileName);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (urls &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">while&lt;/span> (urls. &lt;span style="color:#268bd2">hasMoreElements&lt;/span>()) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> java.net.URL resourceURL &lt;span style="color:#719e07">=&lt;/span> urls.nextElement();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// load resources&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> loadResource(extensionClasses, classLoader, resourceURL, overridden, excludedPackages);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> } &lt;span style="color:#719e07">catch&lt;/span> (Throwable t) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> logger.error(&lt;span style="color:#2aa198">&amp;#34;Exception occurred when loading extension class (interface: &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> type &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34;, description file: &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> fileName &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34;).&amp;#34;&lt;/span>, t);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The loadDirectory method first obtains all resource links through classLoader, and then loads resources through the loadResource method. Let&amp;rsquo;s go ahead and take a look at the implementation of the loadResource method.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">private&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">loadResource&lt;/span>(Map&lt;span style="color:#719e07">&amp;lt;&lt;/span>String, Class&lt;span style="color:#719e07">&amp;lt;?&amp;gt;&amp;gt;&lt;/span> extensionClasses, ClassLoader classLoader,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> java.net.URL resourceURL, &lt;span style="color:#dc322f">boolean&lt;/span> overridden, String... excludedPackages) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">try&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">try&lt;/span> (BufferedReader reader &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#719e07">new&lt;/span> BufferedReader(&lt;span style="color:#719e07">new&lt;/span> InputStreamReader(resourceURL. &lt;span style="color:#268bd2">openStream&lt;/span>(), StandardCharsets. UTF_8))) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> String line;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> String clazz &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Read configuration content line by line&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">while&lt;/span> ((line &lt;span style="color:#719e07">=&lt;/span> reader. &lt;span style="color:#268bd2">readLine&lt;/span>()) &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// locate # characters&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">final&lt;/span> &lt;span style="color:#dc322f">int&lt;/span> ci &lt;span style="color:#719e07">=&lt;/span> line. &lt;span style="color:#268bd2">indexOf&lt;/span>(&lt;span style="color:#2aa198">&amp;#39;#&amp;#39;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (ci &lt;span style="color:#719e07">&amp;gt;=&lt;/span> 0) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Intercept the string before #, the content after # is a comment, which needs to be ignored&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> line &lt;span style="color:#719e07">=&lt;/span> line. &lt;span style="color:#268bd2">substring&lt;/span>(0, ci);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> line &lt;span style="color:#719e07">=&lt;/span> line. &lt;span style="color:#268bd2">trim&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (line. &lt;span style="color:#268bd2">length&lt;/span>() &lt;span style="color:#719e07">&amp;gt;&lt;/span> 0) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">try&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> String name &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Use the equal sign = as the boundary to intercept the key and value&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">int&lt;/span> i &lt;span style="color:#719e07">=&lt;/span> line. &lt;span style="color:#268bd2">indexOf&lt;/span>(&lt;span style="color:#2aa198">&amp;#39;=&amp;#39;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (i &lt;span style="color:#719e07">&amp;gt;&lt;/span> 0) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> name &lt;span style="color:#719e07">=&lt;/span> line.substring(0, i).trim();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> clazz &lt;span style="color:#719e07">=&lt;/span> line.substring(i &lt;span style="color:#719e07">+&lt;/span> 1).trim();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> } &lt;span style="color:#719e07">else&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> clazz &lt;span style="color:#719e07">=&lt;/span> line;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Load the class and cache the class through the loadClass method&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (StringUtils.isNotEmpty(clazz) &lt;span style="color:#719e07">&amp;amp;&amp;amp;&lt;/span> &lt;span style="color:#719e07">!&lt;/span>isExcluded(clazz, excludedPackages)) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> loadClass(extensionClasses, resourceURL, Class. &lt;span style="color:#268bd2">forName&lt;/span>(clazz, &lt;span style="color:#cb4b16">true&lt;/span>, classLoader), name, overridden);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> } &lt;span style="color:#719e07">catch&lt;/span> (Throwable t) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> IllegalStateException e &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#719e07">new&lt;/span> IllegalStateException(&lt;span style="color:#2aa198">&amp;#34;Failed to load extension class (interface: &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> type &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34;, class line: &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> line &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34;) in &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> resourceURL &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34;, cause: &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> t.getMessage(), t);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> exceptions. &lt;span style="color:#268bd2">put&lt;/span>(line, e);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> } &lt;span style="color:#719e07">catch&lt;/span> (Throwable t) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> logger.error(&lt;span style="color:#2aa198">&amp;#34;Exception occurred when loading extension class (interface: &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> type &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34;, class file: &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> resourceURL &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34;) in &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> resourceURL, t);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The loadResource method is used to read and parse configuration files, load classes through reflection, and finally call the loadClass method for other operations. The loadClass method is mainly used to operate the cache. The logic of this method is as follows:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">private&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">loadClass&lt;/span>(Map&lt;span style="color:#719e07">&amp;lt;&lt;/span>String, Class&lt;span style="color:#719e07">&amp;lt;?&amp;gt;&amp;gt;&lt;/span> extensionClasses, java.net.URL resourceURL, Class&lt;span style="color:#719e07">&amp;lt;?&amp;gt;&lt;/span> clazz, String name,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">boolean&lt;/span> overridden) &lt;span style="color:#268bd2">throws&lt;/span> NoSuchMethodException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (&lt;span style="color:#719e07">!&lt;/span>type.isAssignableFrom(clazz)) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">throw&lt;/span> &lt;span style="color:#719e07">new&lt;/span> IllegalStateException(&lt;span style="color:#2aa198">&amp;#34;Error occurred when loading extension class (interface: &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> type &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34;, class line: &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> clazz. &lt;span style="color:#268bd2">getName&lt;/span>() &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34;), class &amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">+&lt;/span> clazz.getName() &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34; is not subtype of interface.&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Check if there are Adaptive annotations on the target class&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (clazz. &lt;span style="color:#268bd2">isAnnotationPresent&lt;/span>(Adaptive. &lt;span style="color:#268bd2">class&lt;/span>)) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">cacheAdaptiveClass&lt;/span>(clazz, overridden);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> } &lt;span style="color:#719e07">else&lt;/span> &lt;span style="color:#719e07">if&lt;/span> (isWrapperClass(clazz)) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// cache wrapper class&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> cacheWrapperClass(clazz);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> } &lt;span style="color:#719e07">else&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Enter here, indicating that this class is just an ordinary extension class&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Check if clazz has a default constructor, if not, throw an exception&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> clazz. &lt;span style="color:#268bd2">getConstructor&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (StringUtils. &lt;span style="color:#268bd2">isEmpty&lt;/span>(name)) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// If name is empty, try to get name from Extension annotation, or use lowercase class name as name&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> name &lt;span style="color:#719e07">=&lt;/span> findAnnotationName(clazz);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (name. &lt;span style="color:#268bd2">length&lt;/span>() &lt;span style="color:#719e07">==&lt;/span> 0) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">throw&lt;/span> &lt;span style="color:#719e07">new&lt;/span> IllegalStateException(&lt;span style="color:#2aa198">&amp;#34;No such extension name for the class &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> clazz. &lt;span style="color:#268bd2">getName&lt;/span>() &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34; in the config &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> resourceURL);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> String&lt;span style="color:#719e07">[]&lt;/span> names &lt;span style="color:#719e07">=&lt;/span> NAME_SEPARATOR. &lt;span style="color:#268bd2">split&lt;/span>(name);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (ArrayUtils. &lt;span style="color:#268bd2">isNotEmpty&lt;/span>(names)) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// If the class has the Activate annotation, use the first element of the names array as the key,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Store the mapping relationship between name and Activate annotation object&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> cacheActivateClass(clazz, names&lt;span style="color:#719e07">[&lt;/span>0&lt;span style="color:#719e07">]&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">for&lt;/span> (String n : names) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Store the mapping relationship from Class to name&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> cacheName(clazz, n);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Store the mapping relationship from name to Class.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// If there are multiple implementation classes corresponding to the same extension, whether overriding is allowed based on the override parameter, if not, an exception is thrown.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> saveInExtensionClass(extensionClasses, clazz, n, overridden);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>As above, the loadClass method operates different caches, such as cachedAdaptiveClass, cachedWrapperClasses and cachedNames, etc. Apart from that, there is no other logic in this method.&lt;/p>
&lt;p>At this point, the analysis of the process of caching class loading is over. There is nothing particularly complicated in the whole process. You can analyze it step by step, and you can debug it if you don’t understand it. Next, let&amp;rsquo;s talk about Dubbo IOC.&lt;/p>
&lt;h3 id="212-dubbo-ioc">2.1.2 Dubbo IOC&lt;/h3>
&lt;p>Dubbo IOC injects dependencies through the setter method. Dubbo first obtains all methods of the instance through reflection, and then traverses the method list to detect whether the method name has the characteristics of a setter method. If so, obtain the dependent object through ObjectFactory, and finally call the setter method through reflection to set the dependency to the target object. The code corresponding to the whole process is as follows:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">private&lt;/span> T &lt;span style="color:#268bd2">injectExtension&lt;/span>(T instance) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (objectFactory &lt;span style="color:#719e07">==&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> instance;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">try&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// traverse all methods of the target class&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">for&lt;/span> (Method method : instance. &lt;span style="color:#268bd2">getClass&lt;/span>(). getMethods()) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Check whether the method starts with set, and the method has only one parameter, and the method access level is public&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (&lt;span style="color:#719e07">!&lt;/span>isSetter(method)) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">continue&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * Detect whether there is DisableInject annotation modification.
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (method. &lt;span style="color:#268bd2">getAnnotation&lt;/span>(DisableInject. &lt;span style="color:#268bd2">class&lt;/span>) != &lt;span style="color:#268bd2">null&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">continue&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> * Detect whether the ScopeModelAware and ExtensionAccessorAware classes are implemented, and if implemented, do not inject
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (method. &lt;span style="color:#268bd2">getDeclaringClass&lt;/span>() &lt;span style="color:#719e07">==&lt;/span> ScopeModelAware. &lt;span style="color:#268bd2">class&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">continue&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (instance &lt;span style="color:#719e07">instanceof&lt;/span> ScopeModelAware &lt;span style="color:#719e07">||&lt;/span> instance &lt;span style="color:#719e07">instanceof&lt;/span> ExtensionAccessorAware) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (ignoredInjectMethodsDesc. &lt;span style="color:#268bd2">contains&lt;/span>(ReflectUtils. &lt;span style="color:#268bd2">getDesc&lt;/span>(method))) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">continue&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Primitive types are not injected&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Class&lt;span style="color:#719e07">&amp;lt;?&amp;gt;&lt;/span> pt &lt;span style="color:#719e07">=&lt;/span> method. &lt;span style="color:#268bd2">getParameterTypes&lt;/span>()&lt;span style="color:#719e07">[&lt;/span>0&lt;span style="color:#719e07">]&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (ReflectUtils. &lt;span style="color:#268bd2">isPrimitives&lt;/span>(pt)) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">continue&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">try&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Get the attribute name, for example, the setName method corresponds to the attribute name name&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> String property &lt;span style="color:#719e07">=&lt;/span> getSetterProperty(method);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Get dependent objects from ObjectFactory&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Object object &lt;span style="color:#719e07">=&lt;/span> objectFactory. &lt;span style="color:#268bd2">getExtension&lt;/span>(pt, property);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (object &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// inject&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> method.invoke(instance, object);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> } &lt;span style="color:#719e07">catch&lt;/span> (Exception e) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> logger.error(&lt;span style="color:#2aa198">&amp;#34;Failed to inject via method &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> method.getName()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34; of interface &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> type. &lt;span style="color:#268bd2">getName&lt;/span>() &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34;: &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> e. &lt;span style="color:#268bd2">getMessage&lt;/span>(), e);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> } &lt;span style="color:#719e07">catch&lt;/span> (Exception e) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> logger. &lt;span style="color:#268bd2">error&lt;/span>(e. &lt;span style="color:#268bd2">getMessage&lt;/span>(), e);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> instance;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In the above code, the type of the objectFactory variable is AdaptiveExtensionFactory, and AdaptiveExtensionFactory internally maintains an ExtensionFactory list for storing other types of ExtensionFactory. Dubbo currently provides two types of ExtensionFactory, namely SpiExtensionFactory and SpringExtensionFactory. The former is used to create adaptive extensions, and the latter is used to obtain the required extensions from Spring&amp;rsquo;s IOC container. The codes of these two classes are not very complicated, so I won&amp;rsquo;t analyze them one by one here.&lt;/p>
&lt;p>Dubbo IOC currently only supports setter injection. Generally speaking, the logic is relatively simple and easy to understand.&lt;/p>
&lt;h3 id="22-load-adaptive-extension-class">2.2 Load adaptive extension class&lt;/h3>
&lt;p>The meaning of adaptive extension class is that, based on parameters, a specific target class is dynamically selected at runtime and then executed.
In Dubbo, many extensions are loaded through the SPI mechanism, such as Protocol, Cluster, LoadBalance, etc. Sometimes, some extensions do not want to be loaded during the framework startup phase, but want to be loaded according to runtime parameters when the extension method is called. This sounds contradictory. If the extension is not loaded, the extension methods cannot be called (except static methods). If the extension method is not called, the extension cannot be loaded. For this contradictory problem, Dubbo has solved it well through the adaptive expansion mechanism. The implementation logic of the self-adaptive expansion mechanism is relatively complicated. First, Dubbo will generate code with proxy functions for the expansion interface. Then compile this code through javassist or jdk to get the Class class. Finally, the proxy class is created through reflection, and the whole process is more complicated.&lt;/p>
&lt;p>The entry point for loading adaptive extension classes is the getAdaptiveExtension method of ExtensionLoader.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> T &lt;span style="color:#268bd2">getAdaptiveExtension&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Get the adaptive extension from the cache&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Object instance &lt;span style="color:#719e07">=&lt;/span> cachedAdaptiveInstance. &lt;span style="color:#268bd2">get&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (instance &lt;span style="color:#719e07">==&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// If there is an exception, throw it directly&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (createAdaptiveInstanceError &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">throw&lt;/span> &lt;span style="color:#719e07">new&lt;/span> IllegalStateException(&lt;span style="color:#2aa198">&amp;#34;Failed to create adaptive instance: &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> createAdaptiveInstanceError.toString(),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> createAdaptiveInstanceError);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">synchronized&lt;/span> (cachedAdaptiveInstance) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> instance &lt;span style="color:#719e07">=&lt;/span> cachedAdaptiveInstance. &lt;span style="color:#268bd2">get&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// double check&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (instance &lt;span style="color:#719e07">==&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">try&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// create adaptive extension&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// There are two cases here: one is that there is an Adaptive class, and the other is that an Adaptive class needs to be generated&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> instance &lt;span style="color:#719e07">=&lt;/span> createAdaptiveExtension();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> cachedAdaptiveInstance.set(instance);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> } &lt;span style="color:#719e07">catch&lt;/span> (Throwable t) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> createAdaptiveInstanceError &lt;span style="color:#719e07">=&lt;/span> t;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">throw&lt;/span> &lt;span style="color:#719e07">new&lt;/span> IllegalStateException(&lt;span style="color:#2aa198">&amp;#34;Failed to create adaptive instance: &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> t.toString(), t);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> (T) instance;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The getAdaptiveExtension method will first check the cache, and if the cache misses, call the createAdaptiveExtension method to create an adaptive extension. Next, let&amp;rsquo;s look at the code of the createAdaptiveExtension method.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">private&lt;/span> T &lt;span style="color:#268bd2">createAdaptiveExtension&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">try&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Get the adaptive extension class and instantiate it through reflection&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> injectExtension((T) getAdaptiveExtensionClass(). newInstance());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> } &lt;span style="color:#719e07">catch&lt;/span> (Exception e) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">throw&lt;/span> &lt;span style="color:#719e07">new&lt;/span> IllegalStateException(&lt;span style="color:#2aa198">&amp;#34;Can not create adaptive extension ...&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The code of the createAdaptiveExtension method is relatively small, but it contains three logics, which are as follows:&lt;/p>
&lt;ol>
&lt;li>Call the getAdaptiveExtensionClass method to obtain the adaptive extension Class object&lt;/li>
&lt;li>Instantiation via reflection&lt;/li>
&lt;li>Call the injectExtension method to inject dependencies into the extension instance&lt;/li>
&lt;/ol>
&lt;p>The first two logics are easy to understand, and the third logic is used to inject dependencies into adaptive extension objects. This logic may seem redundant, but it is necessary to exist. Here is a brief explanation. As mentioned earlier, there are two types of adaptive extensions in Dubbo, one is manually coded and the other is automatically generated. There may be some dependencies in the hand-coded Adaptive extension, while the automatically generated Adaptive extension will not depend on other classes. The purpose of calling the injectExtension method here is to inject dependencies for the hand-coded adaptive extension, which requires everyone to pay attention. Regarding the injectExtension method, it has been analyzed in the previous article, so I won’t go into details here. Next, analyze the logic of the getAdaptiveExtensionClass method.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">private&lt;/span> Class&lt;span style="color:#719e07">&amp;lt;?&amp;gt;&lt;/span> getAdaptiveExtensionClass() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Get all extension classes through SPI&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> getExtensionClasses();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Check the cache, if the cache is not empty, return the cache directly&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (cachedAdaptiveClass &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> cachedAdaptiveClass;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Create an adaptive extension class&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> cachedAdaptiveClass &lt;span style="color:#719e07">=&lt;/span> createAdaptiveExtensionClass();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The getAdaptiveExtensionClass method also contains three logics, as follows:&lt;/p>
&lt;ol>
&lt;li>Call getExtensionClasses to get all extension classes&lt;/li>
&lt;li>Check the cache, if the cache is not empty, return the cache&lt;/li>
&lt;li>If the cache is empty, call createAdaptiveExtensionClass to create an adaptive extension class&lt;/li>
&lt;/ol>
&lt;p>These three logics seem unremarkable, and there seems to be no need to talk about them. But there are some details hidden in this bland code that need to be explained. First, let’s start with the first logic. The getExtensionClasses method is used to get all the implementation classes of an interface. For example, this method can obtain DubboProtocol, HttpProtocol, InjvmProtocol and other implementation classes of the Protocol interface. In the process of obtaining the implementation class, if an implementation class is modified by the Adaptive annotation, then the class will be assigned to the cachedAdaptiveClass variable. At this point, the condition of the second step in the above steps is satisfied (the cache is not empty), just return the cachedAdaptiveClass directly. If all implementation classes are not modified by Adaptive annotations, then execute the logic of the third step to create adaptive extension classes. The relevant code is as follows:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">private&lt;/span> Class&lt;span style="color:#719e07">&amp;lt;?&amp;gt;&lt;/span> createAdaptiveExtensionClass() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Build adaptive extension code&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> String code &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#719e07">new&lt;/span> AdaptiveClassCodeGenerator(type, cachedDefaultName).generate();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ClassLoader classLoader &lt;span style="color:#719e07">=&lt;/span> findClassLoader();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Get the compiler implementation class&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> org.apache.dubbo.common.compiler.Compiler compiler &lt;span style="color:#719e07">=&lt;/span> ExtensionLoader.getExtensionLoader(org.apache.dubbo.common.compiler.Compiler.class).getAdaptiveExtension();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Compile the code and generate Class&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> compiler.compile(code, classLoader);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The createAdaptiveExtensionClass method is used to generate an adaptive extension class. This method first generates the source code of the adaptive extension class, and then compiles the source code through a Compiler instance (Dubbo uses javassist as the compiler by default) to obtain a proxy class Class instance. Next, we will focus on the logic of proxy class code generation, and analyze other logic by yourself.&lt;/p>
&lt;h3 id="221-adaptive-extension-class-code-generation">2.2.1 Adaptive extension class code generation&lt;/h3>
&lt;p>AdaptiveClassCodeGenerator#generate method generates extension class code&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> String &lt;span style="color:#268bd2">generate&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// If there is no method in the interface modified by the @Adaptive annotation, an exception is thrown directly&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (&lt;span style="color:#719e07">!&lt;/span>hasAdaptiveMethod()) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">throw&lt;/span> &lt;span style="color:#719e07">new&lt;/span> IllegalStateException(&lt;span style="color:#2aa198">&amp;#34;No adaptive method exist on extension &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> type.getName() &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34;, refuse to create the adaptive class!&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> StringBuilder code &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#719e07">new&lt;/span> StringBuilder();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Generate package name, import, method, etc.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> code.append(generatePackageInfo());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> code.append(generateImports());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> code.append(generateClassDeclaration());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Method&lt;span style="color:#719e07">[]&lt;/span> methods &lt;span style="color:#719e07">=&lt;/span> type. &lt;span style="color:#268bd2">getMethods&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">for&lt;/span> (Method method : methods) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> code.append(generateMethod(method));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> code.append(&lt;span style="color:#2aa198">&amp;#34;}&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (logger. &lt;span style="color:#268bd2">isDebugEnabled&lt;/span>()) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> logger. &lt;span style="color:#268bd2">debug&lt;/span>(code. &lt;span style="color:#268bd2">toString&lt;/span>());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> code. &lt;span style="color:#268bd2">toString&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="222-generation-method">2.2.2 Generation method&lt;/h4>
&lt;p>In the above code, the logic of the generation method is the most critical, let&amp;rsquo;s analyze it in detail.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">private&lt;/span> String &lt;span style="color:#268bd2">generateMethod&lt;/span>(Method method) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> String methodReturnType &lt;span style="color:#719e07">=&lt;/span> method. &lt;span style="color:#268bd2">getReturnType&lt;/span>(). getCanonicalName();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> String methodName &lt;span style="color:#719e07">=&lt;/span> method. &lt;span style="color:#268bd2">getName&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// generate method content&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> String methodContent &lt;span style="color:#719e07">=&lt;/span> generateMethodContent(method);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> String methodArgs &lt;span style="color:#719e07">=&lt;/span> generateMethodArguments(method);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> String methodThrows &lt;span style="color:#719e07">=&lt;/span> generateMethodThrows(method);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> String. &lt;span style="color:#268bd2">format&lt;/span>(CODE_METHOD_DECLARATION, methodReturnType, methodName, methodArgs, methodThrows, methodContent);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>generateMethodContent Analysis&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">private&lt;/span> String &lt;span style="color:#268bd2">generateMethodContent&lt;/span>(Method method) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// This method must be decorated with @Adaptive annotation&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Adaptive adaptiveAnnotation &lt;span style="color:#719e07">=&lt;/span> method. &lt;span style="color:#268bd2">getAnnotation&lt;/span>(Adaptive. &lt;span style="color:#268bd2">class&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">StringBuilder&lt;/span> code &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#719e07">new&lt;/span> StringBuilder(512);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (adaptiveAnnotation &lt;span style="color:#719e07">==&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Without @Adaptive annotation modification, exception information is generated&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> generateUnsupported(method);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> } &lt;span style="color:#719e07">else&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Get the index of the URL on the parameter list&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">int&lt;/span> urlTypeIndex &lt;span style="color:#719e07">=&lt;/span> getUrlTypeIndex(method);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (urlTypeIndex &lt;span style="color:#719e07">!=&lt;/span> &lt;span style="color:#719e07">-&lt;/span>1) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Generate a null check for the URL if it exists on the parameter list&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> code.append(generateUrlNullCheck(urlTypeIndex));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> } &lt;span style="color:#719e07">else&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// If there is no parameter of URL type in the parameter list, then it depends on whether the parameter object on the parameter list contains the getUrl method&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// If there is, generate a URL null check&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> code.append(generateUrlAssignmentIndirectly(method));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// parse the value attribute on the Adaptive annotation&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> String&lt;span style="color:#719e07">[]&lt;/span> value &lt;span style="color:#719e07">=&lt;/span> getMethodAdaptiveValue(adaptiveAnnotation);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// If there is a parameter of type Invocation on the parameter list, generate a null check and get the methodName.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">boolean&lt;/span> hasInvocation &lt;span style="color:#719e07">=&lt;/span> hasInvocationArgument(method);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> code.append(generateInvocationArgumentNullCheck(method));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// This logic is mainly to generate extName (that is, the extension)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Divided into multiple situations:&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// 1. Does defaultExtName exist?&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// 2. Whether there is an invocation type parameter in the parameter&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// 3. Whether to generate a proxy for the protocol&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Why should the protocol be considered separately? Because there is a method to get the protocol value in the URL&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> code.append(generateExtNameAssignment(value, hasInvocation));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// check extName == null?&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> code.append(generateExtNameNullCheck(value));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// generate get extension (using ExtensionLoader.getExtension method)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> code.append(generateExtensionAssignment());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// generate return statement&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> code.append(generateReturnAndInvocation(method));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> code. &lt;span style="color:#268bd2">toString&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The above logic mainly does the following things:&lt;/p>
&lt;ol>
&lt;li>Check whether the Adaptive annotation is modified on the method&lt;/li>
&lt;li>When generating code for a method, there must be a URL on the parameter list (or a URL in the parameter object)&lt;/li>
&lt;li>Use ExtensionLoader.getExtension to get the extension&lt;/li>
&lt;li>Execute the corresponding method&lt;/li>
&lt;/ol>
&lt;h3 id="223-attach-an-example-of-dynamically-generated-code">2.2.3 Attach an example of dynamically generated code&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">package&lt;/span> org.apache.dubbo.common.extension.adaptive;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.common.extension.ExtensionLoader;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">HasAdaptiveExt$Adaptive&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> org.apache.dubbo.common.extension.adaptive.HasAdaptiveExt {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> java.lang.String &lt;span style="color:#268bd2">echo&lt;/span>(org.apache.dubbo.common.URL arg0,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> java. lang. String arg1) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// URL null check&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (arg0 &lt;span style="color:#719e07">==&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">throw&lt;/span> &lt;span style="color:#719e07">new&lt;/span> IllegalArgumentException(&lt;span style="color:#2aa198">&amp;#34;url == null&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> org.apache.dubbo.common.URL url &lt;span style="color:#719e07">=&lt;/span> arg0;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// get the extension&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> String extName &lt;span style="color:#719e07">=&lt;/span> url. &lt;span style="color:#268bd2">getParameter&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;has. adaptive. ext&amp;#34;&lt;/span>, &lt;span style="color:#2aa198">&amp;#34;adaptive&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// extension null check&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">if&lt;/span> (extName &lt;span style="color:#719e07">==&lt;/span> &lt;span style="color:#cb4b16">null&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">throw&lt;/span> &lt;span style="color:#719e07">new&lt;/span> IllegalStateException(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#2aa198">&amp;#34;Failed to get extension (org.apache.dubbo.common.extension.adaptive.HasAdaptiveExt) name from url (&amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> url.toString() &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34;) use keys([has.adaptive.ext])&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// get extension&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> org.apache.dubbo.common.extension.adaptive.HasAdaptiveExt extension &lt;span style="color:#719e07">=&lt;/span> (org.apache.dubbo.common.extension.adaptive.HasAdaptiveExt) ExtensionLoader.getExtensionLoader(org.apache.dubbo.common.extension.adaptive.HasAdaptiveExt.class)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .getExtension(extName);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">// Execute the corresponding method&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> extension.echo(arg0, arg1);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="3-spi-extension-example">3. SPI extension example&lt;/h2>
&lt;h3 id="31-load-fixed-extension-class">3.1 Load fixed extension class&lt;/h3>
&lt;h3 id="311-write-spi-interface-and-implementation-class">3.1.1 Write SPI interface and implementation class&lt;/h3>
&lt;p>Whether it is Java SPI or SPI implemented in Dubbo, you need to write an interface. However, the interface in Dubbo needs to be decorated with @SPI annotation.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@SPI&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">interface&lt;/span> &lt;span style="color:#268bd2">DemoSpi&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">say&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">DemoSpiImpl&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> DemoSpi {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">say&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="312-put-the-implementation-class-in-a-specific-directory">3.1.2 Put the implementation class in a specific directory&lt;/h4>
&lt;p>From the above code, we can see that when dubbo loads the extension class, it will read from four directories. We create a new file named after the DemoSpi interface in the META-INF/dubbo directory, the content is as follows:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>demoSpiImpl = com.xxx.xxx.DemoSpiImpl (full class name for the implementation class of the DemoSpi interface)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="313-use">3.1.3 Use&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">DubboSPITest&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Test&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">sayHello&lt;/span>() &lt;span style="color:#268bd2">throws&lt;/span> Exception {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ExtensionLoader&lt;span style="color:#719e07">&amp;lt;&lt;/span>DemoSpi&lt;span style="color:#719e07">&amp;gt;&lt;/span> extensionLoader &lt;span style="color:#719e07">=&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ExtensionLoader. &lt;span style="color:#268bd2">getExtensionLoader&lt;/span>(DemoSpi. &lt;span style="color:#268bd2">class&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">DemoSpi&lt;/span> dmeoSpi &lt;span style="color:#719e07">=&lt;/span> extensionLoader. &lt;span style="color:#268bd2">getExtension&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;demoSpiImpl&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> optimusPrime. &lt;span style="color:#268bd2">sayHello&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="32-load-adaptive-extension-class">3.2 Load adaptive extension class&lt;/h3>
&lt;p>This takes Protocol as an example to illustrate&lt;/p>
&lt;h3 id="321-protocol-interface-extract-some-core-methods">3.2.1 Protocol interface (extract some core methods)&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@SPI&lt;/span>(&lt;span style="color:#2aa198">&amp;#34;dubbo&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">interface&lt;/span> &lt;span style="color:#268bd2">Protocol&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Adaptive&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> Exporter&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> &lt;span style="color:#268bd2">export&lt;/span>(Invoker&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> invoker) &lt;span style="color:#268bd2">throws&lt;/span> RpcException;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Adaptive&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> Invoker&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> &lt;span style="color:#268bd2">refer&lt;/span>(Class&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> type, URL url) &lt;span style="color:#268bd2">throws&lt;/span> RpcException;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">DubboProtocol&lt;/span> &lt;span style="color:#268bd2">extends&lt;/span> AbstractProtocol {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>  …
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Override&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> Invoker&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> &lt;span style="color:#268bd2">refer&lt;/span>(Class&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> type, URL url) &lt;span style="color:#268bd2">throws&lt;/span> RpcException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> protocolBindingRefer(type, url);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Override&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> Exporter&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> &lt;span style="color:#268bd2">export&lt;/span>(Invoker&lt;span style="color:#719e07">&amp;lt;&lt;/span>T&lt;span style="color:#719e07">&amp;gt;&lt;/span> invoker) &lt;span style="color:#268bd2">throws&lt;/span> RpcException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>  …
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> exporter;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="322-put-the-implementation-class-in-a-specific-directory">3.2.2 Put the implementation class in a specific directory&lt;/h3>
&lt;p>In dubbo, the configuration path is META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>dubbo=org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>It should be noted that in dubbo, DubboProtocol is not used directly, but its wrapper class is used.&lt;/p>
&lt;h3 id="323-use">3.2.3 Use&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#268bd2">class&lt;/span> &lt;span style="color:#268bd2">DubboAdaptiveTest&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Test&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">public&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">sayHello&lt;/span>() &lt;span style="color:#268bd2">throws&lt;/span> Exception {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> URL url &lt;span style="color:#719e07">=&lt;/span> URL.valueOf(&lt;span style="color:#2aa198">&amp;#34;dubbo://localhost/test&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Protocol adaptiveProtocol &lt;span style="color:#719e07">=&lt;/span> ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> adaptiveProtocol. &lt;span style="color:#268bd2">refer&lt;/span>(type, url);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item></channel></rss>