<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Dubbo as a lightweight RPC framework solves component communication issues on Apache Dubbo</title><link>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/</link><description>Recent content in Dubbo as a lightweight RPC framework solves component communication issues on Apache Dubbo</description><generator>Hugo</generator><language>en</language><atom:link href="https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/index.xml" rel="self" type="application/rss+xml"/><item><title>Generic Implementation</title><link>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/generic-impl/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/generic-impl/</guid><description>&lt;div class="alert alert-warning" role="alert">
&lt;h4 class="alert-heading">Note&lt;/h4>

 Please distinguish between the previous document on &lt;a href="https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/generic/">Generic Invocation&lt;/a>, which is for consumers, and Generic Implementation, which is for providers.

&lt;/div>

&lt;p>The generic interface implementation method is mainly used in scenarios where the server side does not have API interfaces and model class metadata. All POJOs in parameters and return values are represented using Map, usually for framework integration. For example, to implement a generic remote service Mock framework, you can handle all service requests by implementing the GenericService interface.&lt;/p></description></item><item><title>Echo Testing</title><link>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/echo-service/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/echo-service/</guid><description>&lt;h2 id="feature-description">Feature Description&lt;/h2>
&lt;p>Echo testing is used to detect whether a service is available. The echo test follows the normal request process, allowing the entire call to be tested for smooth operation and can be used for monitoring. In an echo test, the client sends a request containing a specific value (such as a string). The server should respond with the same value to verify that the request has been successfully received and processed. If the response does not match the request, it indicates that the service is not functioning properly and further investigation is needed. It requires that the Dubbo server is running and that there is a network connection between the server and the client. On the client side, the Dubbo client must be configured to connect to the server, which will send requests to the server, and then the server should return the same response as the request.&lt;/p></description></item><item><title>Dynamically Specify IP Call</title><link>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/specify-ip/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/specify-ip/</guid><description>&lt;h2 id="feature-description">Feature Description&lt;/h2>
&lt;p>When initiating an RPC request, it is necessary to specify the server for this call. Common scenarios include message callbacks, traffic isolation, etc.&lt;/p>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;h3 id="plugin-dependency">Plugin Dependency&lt;/h3>
&lt;p>First, add the following plugin dependency to your project&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-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dependency&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;groupId&amp;gt;&lt;/span>org.apache.dubbo.extensions&lt;span style="color:#268bd2">&amp;lt;/groupId&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;artifactId&amp;gt;&lt;/span>dubbo-cluster-specify-address-dubbo3&lt;span style="color:#268bd2">&amp;lt;/artifactId&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;version&amp;gt;&lt;/span>3.3.0&lt;span style="color:#268bd2">&amp;lt;/version&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;/dependency&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>For Dubbo 2 version&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-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dependency&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;groupId&amp;gt;&lt;/span>org.apache.dubbo.extensions&lt;span style="color:#268bd2">&amp;lt;/groupId&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;artifactId&amp;gt;&lt;/span>dubbo-cluster-specify-address-dubbo2&lt;span style="color:#268bd2">&amp;lt;/artifactId&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;version&amp;gt;&lt;/span>1.0.0&lt;span style="color:#268bd2">&amp;lt;/version&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;/dependency&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="call-example">Call Example&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>ReferenceConfig&lt;span style="color:#719e07">&amp;lt;&lt;/span>DemoService&lt;span style="color:#719e07">&amp;gt;&lt;/span> referenceConfig &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#719e07">new&lt;/span> ReferenceConfig&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:#586e75">// ... init&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>DemoService demoService &lt;span style="color:#719e07">=&lt;/span> referenceConfig.get();
&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">// for invoke&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">// 1. find 10.10.10.10:20880 exist&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">// 2. if not exist, create a invoker to 10.10.10.10:20880 if `needToCreate` is true (only support in Dubbo 3.x&amp;#39;s implementation)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>UserSpecifiedAddressUtil.setAddress(&lt;span style="color:#719e07">new&lt;/span> Address(&lt;span style="color:#2aa198">&amp;#34;10.10.10.10&amp;#34;&lt;/span>, 20880, &lt;span style="color:#cb4b16">true&lt;/span>));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>demoService.sayHello(&lt;span style="color:#2aa198">&amp;#34;world&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>&lt;span style="color:#586e75">// for invoke&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">// 1. find 10.10.10.10:any exist&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">// 2. if not exist, create a invoker to 10.10.10.10:20880 if `needToCreate` is true (only support in Dubbo 3.x&amp;#39;s implementation)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>UserSpecifiedAddressUtil.setAddress(&lt;span style="color:#719e07">new&lt;/span> Address(&lt;span style="color:#2aa198">&amp;#34;10.10.10.10&amp;#34;&lt;/span>, 0, &lt;span style="color:#cb4b16">true&lt;/span>));
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>demoService.sayHello(&lt;span style="color:#2aa198">&amp;#34;world&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="parameter-description">Parameter Description&lt;/h3>
&lt;p>The parameters for specifying IP calls revolve around the &lt;code>Address&lt;/code> object. The parameter types are as follows:&lt;/p></description></item><item><title>Direct Connection Provider</title><link>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/explicit-target/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/explicit-target/</guid><description>&lt;p>In development and testing environments, it is often necessary to bypass the registry and only test specific service providers. In this case, point-to-point direct connection may be required. The point-to-point direct connection method will ignore the provider list from the registry on a service interface basis. Configuring point-to-point for interface A will not affect interface B from obtaining the list from the registry.&lt;/p>
&lt;p>&lt;img alt="/user-guide/images/dubbo-directly.jpg" src="https://deploy-preview-3202--dubbo.netlify.app/imgs/user/dubbo-directly.jpg">&lt;/p>
&lt;p>If point-to-point communication is needed in a production environment, you can configure the &lt;code>reference&lt;/code> node to point to the provider URL, bypassing the registry. Multiple addresses can be separated by semicolons, configured as follows:&lt;/p></description></item><item><title>Event Notifications Triggered by Calls</title><link>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/events-notify/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/events-notify/</guid><description>&lt;h2 id="feature-description">Feature Description&lt;/h2>
&lt;p>The events &lt;code>oninvoke&lt;/code>, &lt;code>onreturn&lt;/code>, and &lt;code>onthrow&lt;/code> will be triggered before a call, after a call, and when an exception occurs, respectively. You can configure which class and method to notify when these events happen.&lt;/p>
&lt;h2 id="use-cases">Use Cases&lt;/h2>
&lt;p>Before calling the service method, we can log the start time, after the call, calculate the total time consumed, and in case of exceptions, we can trigger alerts or print error logs, or log request and response logs before and after the service call.&lt;/p></description></item><item><title>Server Callback to Client</title><link>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/callback-parameter/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/callback-parameter/</guid><description>&lt;h2 id="feature-description">Feature Description&lt;/h2>
&lt;p>The callback parameter method is similar to calling a local callback or listener; you only need to declare which parameter is a callback type in the Spring configuration file. Dubbo will generate a reverse proxy based on a long connection, allowing the server to invoke client logic. You can refer to the &lt;a href="https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-callback">example code in the dubbo project&lt;/a>.&lt;/p>
&lt;h2 id="use-case">Use Case&lt;/h2>
&lt;p>The callback function informs the client of execution results or sends notifications, functioning similarly to asynchronous calls when method execution times are long, such as in approval workflows where the client is notified of approval results.&lt;/p></description></item><item><title>Service Explanation (Local Mock)</title><link>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/local-mock/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/local-mock/</guid><description>&lt;h2 id="feature-description">Feature Description&lt;/h2>
&lt;p>In Dubbo3, there is a mechanism for lightweight service downgrading, that is, local mocking.&lt;/p>
&lt;p>Mock is a subset of Stub, facilitating service providers to implement fault tolerance logic on the client side. It is often necessary to handle exceptions during &lt;code>RpcException&lt;/code> (e.g., network failures, timeouts), while fault tolerance is not needed for business exceptions (e.g., login username/password errors). Using Stub may require capturing and depending on &lt;code>RpcException&lt;/code>, whereas Mock does not, since its agreement is to only execute when &lt;code>RpcException&lt;/code> occurs.&lt;/p></description></item><item><title>Local Stub</title><link>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/local-stub/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/local-stub/</guid><description>&lt;h2 id="feature-description">Feature Description:&lt;/h2>
&lt;p>After invoking a remote service, the client typically only has the interface, while the implementation resides entirely on the server. However, sometimes the provider wants to execute part of the logic on the client side as well.&lt;/p>
&lt;p>&lt;img alt="/user-guide/images/stub.jpg" src="https://deploy-preview-3202--dubbo.netlify.app/imgs/user/stub.jpg">&lt;/p>
&lt;h2 id="usage-scenarios">Usage Scenarios&lt;/h2>
&lt;p>For scenarios such as creating ThreadLocal caches, validating parameters in advance, or simulating fault tolerance data after a failed call, the API needs to have a Stub. The client generates a Proxy instance, which is passed to the Stub through the constructor &lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>, and then the Stub is exposed to the user. The Stub can decide whether to invoke the Proxy.&lt;/p></description></item><item><title>Local Call</title><link>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/local-call/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/local-call/</guid><description>&lt;h2 id="feature-description">Feature Description&lt;/h2>
&lt;p>Local calls use the injvm protocol, which is a pseudo-protocol that does not open a port or initiate remote calls; it directly associates within the JVM but executes the Dubbo filter chain.&lt;/p>
&lt;h2 id="usage-scenarios">Usage Scenarios&lt;/h2>
&lt;p>When we need to call a remote service that is not yet developed, we can implement a similar service locally using the injvm protocol, allowing us to invoke our local implementation of the service.&lt;/p></description></item><item><title>Concurrency Control</title><link>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/concurrency-control/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/concurrency-control/</guid><description>&lt;h2 id="function-description">Function Description&lt;/h2>
&lt;p>Multiple concurrency control features help users manage their applications and services.&lt;/p>
&lt;h2 id="use-cases">Use Cases&lt;/h2>
&lt;p>Limit the number of concurrent requests from the same client to the same service, preventing malicious requests from overloading the server, ensuring service stability, and preventing excessive resource usage.&lt;/p>
&lt;p>Control the maximum number of concurrent requests for certain services, ensuring the availability of resources for other services. System overload and ensuring system stability.&lt;/p>
&lt;p>Allow for smoother scaling of services when demand increases.&lt;/p></description></item><item><title>Connection Control</title><link>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/config-connections/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/config-connections/</guid><description>&lt;h2 id="function-description">Function Description&lt;/h2>
&lt;p>The connection control feature allows users to manage and control the number of incoming and outgoing connections to the server, limit the number of connections, and set timeouts, ensuring the stability and performance of the Dubbo system. It also allows users to configure different levels of access control based on IP address, port, and protocol to protect the system from malicious traffic and reduce the risk of service interruptions. Additionally, it provides a way to monitor current traffic and connection status.&lt;/p></description></item><item><title>Host Configuration</title><link>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/set-host/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/set-host/</guid><description>&lt;h2 id="background">Background&lt;/h2>
&lt;p>In Dubbo, when a Provider starts, it does two main things: it starts the server and registers the service with the registry. When starting the server, it needs to bind the socket, and when registering the service with the registry, it also needs to send the socket&amp;rsquo;s unique identifier as the service address.&lt;/p>
&lt;ol>
&lt;li>What is the default &lt;code>host&lt;/code> when &lt;code>host&lt;/code> is not set in &lt;code>dubbo&lt;/code>?&lt;/li>
&lt;li>How do we specify the service&amp;rsquo;s &lt;code>host&lt;/code> in &lt;code>dubbo&lt;/code>, can we use a hostname or domain instead of an IP address as &lt;code>host&lt;/code>?&lt;/li>
&lt;li>When using Docker, sometimes port mapping needs to be set, in this case, how should we set the socket bound during server startup and the socket registered with the registry to use different port numbers?&lt;/li>
&lt;/ol>
&lt;h2 id="example">Example&lt;/h2>
&lt;h4 id="what-is-the-default-host-when-host-is-not-set-in-dubbo">What is the default host when host is not set in dubbo&lt;/h4>
&lt;p>The general dubbo protocol configuration is as follows:&lt;/p></description></item><item><title>Result Cache Invocation</title><link>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/result-cache/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/result-cache/</guid><description>&lt;h2 id="function-description">Function Description&lt;/h2>
&lt;p>Dubbo supports server-side and client-side result caching.&lt;/p>
&lt;h4 id="cache-types">Cache Types&lt;/h4>
&lt;p>Currently, versions 3.0 and above of Dubbo support the following built-in caching strategies:&lt;/p>
&lt;ul>
&lt;li>&lt;code>lru&lt;/code> removes excess cache based on the least recently used principle, keeping the hottest data cached.&lt;/li>
&lt;li>&lt;code>lfu&lt;/code> implements cache strategy based on the principle of evicting the least frequently used.&lt;/li>
&lt;li>&lt;code>expiring&lt;/code> implements cache strategy based on expiration time.&lt;/li>
&lt;li>&lt;code>threadlocal&lt;/code> caches in the current thread, for example in a page render when many portals are needed to query user information, using thread cache can reduce such unnecessary accesses.&lt;/li>
&lt;li>&lt;code>jcache&lt;/code> integrates with &lt;a href="http://jcp.org/en/jsr/detail?id=107%27">JSR107&lt;/a>, bridging various cache implementations.&lt;/li>
&lt;/ul>
&lt;p>Cache types are extensible &lt;a href="https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/reference-manual/spi/description/cache">Cache Extension&lt;/a>&lt;/p></description></item><item><title>Route Status Collection</title><link>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/router-snapshot/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/router-snapshot/</guid><description>&lt;h2 id="function-description">Function Description&lt;/h2>
&lt;p>The route status collection feature can be used to identify any potential issues that may affect service performance, to identify any potential bottlenecks or problems that may hinder the efficient use of services, ensuring smooth operation of services, and that users do not encounter any issues when trying to access services. It allows users to check whether the route is enabled or disabled, ensuring that only authorized services are used and access is limited to authorized personnel.&lt;/p></description></item><item><title>Service Reference Configuration Object Cache</title><link>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/reference-config-cache/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/reference-config-cache/</guid><description>&lt;h2 id="function-description">Function Description&lt;/h2>
&lt;p>&lt;code>ReferenceConfig&lt;/code> instances are heavy because they encapsulate the connections to the registry and the providers, necessitating caching. Otherwise, repeatedly generating &lt;code>ReferenceConfig&lt;/code> can lead to performance issues and memory and connection leaks. This problem is often overlooked in API-oriented programming.&lt;/p>
&lt;p>Therefore, starting from version &lt;code>2.4.0&lt;/code>, Dubbo provides a simple utility class &lt;code>ReferenceConfigCache&lt;/code> for caching &lt;code>ReferenceConfig&lt;/code> instances.&lt;/p>
&lt;h2 id="usage-scenarios">Usage Scenarios&lt;/h2>
&lt;p>In scenarios such as gateways where subscriptions are dynamically created, the &lt;code>ReferenceConfig&lt;/code> itself is heavy and creates many intermediate objects, while the proxy can be reused. Hence, &lt;code>ReferenceConfigCache&lt;/code> can cache these properties.&lt;/p></description></item><item><title>Parameter Validation</title><link>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/parameter-validation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/parameter-validation/</guid><description>&lt;h2 id="feature-description">Feature Description&lt;/h2>
&lt;p>The parameter validation feature is implemented based on &lt;a href="https://jcp.org/en/jsr/detail?id=303">JSR303&lt;/a>. Users only need to specify validation annotations from the JSR303 standard and implement validation through a declared filter.&lt;/p>
&lt;h4 id="maven-dependency">Maven Dependency&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-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dependency&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;groupId&amp;gt;&lt;/span>javax.validation&lt;span style="color:#268bd2">&amp;lt;/groupId&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;artifactId&amp;gt;&lt;/span>validation-api&lt;span style="color:#268bd2">&amp;lt;/artifactId&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;version&amp;gt;&lt;/span>1.0.0.GA&lt;span style="color:#268bd2">&amp;lt;/version&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;/dependency&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dependency&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;groupId&amp;gt;&lt;/span>org.hibernate&lt;span style="color:#268bd2">&amp;lt;/groupId&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;artifactId&amp;gt;&lt;/span>hibernate-validator&lt;span style="color:#268bd2">&amp;lt;/artifactId&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;version&amp;gt;&lt;/span>4.2.0.Final&lt;span style="color:#268bd2">&amp;lt;/version&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;/dependency&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="usage-scenario">Usage Scenario&lt;/h2>
&lt;p>The server addresses various interface parameter validation issues when providing interface services externally.&lt;/p>
&lt;blockquote>
&lt;p>Reference Case
&lt;a href="https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-validation">https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-validation&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;h2 id="usage-method">Usage Method&lt;/h2>
&lt;h3 id="parameter-annotation-example">Parameter Annotation Example&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">import&lt;/span> java.io.Serializable;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> java.util.Date;
&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> javax.validation.constraints.Future;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> javax.validation.constraints.Max;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> javax.validation.constraints.Min;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> javax.validation.constraints.NotNull;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> javax.validation.constraints.Past;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> javax.validation.constraints.Pattern;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> javax.validation.constraints.Size;
&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">ValidationParameter&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> Serializable {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">private&lt;/span> &lt;span style="color:#268bd2">static&lt;/span> &lt;span style="color:#268bd2">final&lt;/span> &lt;span style="color:#dc322f">long&lt;/span> serialVersionUID &lt;span style="color:#719e07">=&lt;/span> 7158911668568000392L;
&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">@NotNull&lt;/span> &lt;span style="color:#586e75">// Cannot be null&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Size&lt;/span>(min &lt;span style="color:#719e07">=&lt;/span> 1, max &lt;span style="color:#719e07">=&lt;/span> 20) &lt;span style="color:#586e75">// Length or size range&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">private&lt;/span> String 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:#268bd2">@NotNull&lt;/span>(groups &lt;span style="color:#719e07">=&lt;/span> ValidationService.Save.class) &lt;span style="color:#586e75">// Cannot be null when saving, can be null when updating, indicating no update to this field&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Pattern&lt;/span>(regexp &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">&amp;#34;^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">private&lt;/span> String email;
&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">@Min&lt;/span>(18) &lt;span style="color:#586e75">// Minimum value&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@Max&lt;/span>(100) &lt;span style="color:#586e75">// Maximum value&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">int&lt;/span> age;
&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">@Past&lt;/span> &lt;span style="color:#586e75">// Must be a past date&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">private&lt;/span> Date loginDate;
&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">@Future&lt;/span> &lt;span style="color:#586e75">// Must be a future date&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">private&lt;/span> Date expiryDate;
&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> String &lt;span style="color:#268bd2">getName&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&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> 
&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">setName&lt;/span>(String name) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">this&lt;/span>.name &lt;span style="color:#719e07">=&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> 
&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">getEmail&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> email;
&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:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">setEmail&lt;/span>(String email) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">this&lt;/span>.email &lt;span style="color:#719e07">=&lt;/span> email;
&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:#dc322f">int&lt;/span> &lt;span style="color:#268bd2">getAge&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> age;
&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:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">setAge&lt;/span>(&lt;span style="color:#dc322f">int&lt;/span> age) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">this&lt;/span>.age &lt;span style="color:#719e07">=&lt;/span> age;
&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> Date &lt;span style="color:#268bd2">getLoginDate&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> loginDate;
&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:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">setLoginDate&lt;/span>(Date loginDate) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">this&lt;/span>.loginDate &lt;span style="color:#719e07">=&lt;/span> loginDate;
&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> Date &lt;span style="color:#268bd2">getExpiryDate&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> expiryDate;
&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:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">setExpiryDate&lt;/span>(Date expiryDate) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">this&lt;/span>.expiryDate &lt;span style="color:#719e07">=&lt;/span> expiryDate;
&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="group-validation-example">Group Validation Example&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">interface&lt;/span> &lt;span style="color:#268bd2">ValidationService&lt;/span> { &lt;span style="color:#586e75">// Default can differentiate validation scenarios by service interface, e.g., @NotNull(groups = ValidationService.class) &lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@interface&lt;/span> Save{} &lt;span style="color:#586e75">// Interface name same as method, capitalized first letter, used to differentiate validation scenarios, e.g., @NotNull(groups = ValidationService.Save.class), optional&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">save&lt;/span>(ValidationParameter parameter);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">update&lt;/span>(ValidationParameter parameter);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="related-validation-example">Related Validation Example&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">import&lt;/span> javax.validation.GroupSequence;
&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">interface&lt;/span> &lt;span style="color:#268bd2">ValidationService&lt;/span> { 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@GroupSequence&lt;/span>(Update.class) &lt;span style="color:#586e75">// Validate Update group rules simultaneously&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@interface&lt;/span> Save{}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">save&lt;/span>(ValidationParameter parameter);
&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">@interface&lt;/span> Update{} 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">update&lt;/span>(ValidationParameter parameter);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="parameter-validation-example">Parameter Validation Example&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">import&lt;/span> javax.validation.constraints.Min;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> javax.validation.constraints.NotNull;
&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">interface&lt;/span> &lt;span style="color:#268bd2">ValidationService&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">save&lt;/span>(&lt;span style="color:#268bd2">@NotNull&lt;/span> ValidationParameter parameter); &lt;span style="color:#586e75">// Validate parameter is not null&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">delete&lt;/span>(&lt;span style="color:#268bd2">@Min&lt;/span>(1) &lt;span style="color:#dc322f">int&lt;/span> id); &lt;span style="color:#586e75">// Directly validate basic type parameter&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="validate-parameters-on-client">Validate Parameters on Client&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-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:reference&lt;/span> id=&lt;span style="color:#2aa198">&amp;#34;validationService&amp;#34;&lt;/span> interface=&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.examples.validation.api.ValidationService&amp;#34;&lt;/span> validation=&lt;span style="color:#2aa198">&amp;#34;true&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="validate-parameters-on-server">Validate Parameters on Server&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-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;dubbo:service&lt;/span> interface=&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.examples.validation.api.ValidationService&amp;#34;&lt;/span> ref=&lt;span style="color:#2aa198">&amp;#34;validationService&amp;#34;&lt;/span> validation=&lt;span style="color:#2aa198">&amp;#34;true&amp;#34;&lt;/span> &lt;span style="color:#268bd2">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>&lt;strong>Dubbo supports hibernate-validator version &amp;lt;=6.x by default. If using hibernate-validator version 7.x, declare the validation parameter as jvalidationNew.&lt;/strong>&lt;/p></description></item><item><title>Reactive Programming</title><link>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/reactive/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3202--dubbo.netlify.app/en/overview/mannual/java-sdk/tasks/framework/more/reactive/</guid><description>&lt;div class="alert alert-warning" role="alert">
&lt;h4 class="alert-heading">Outdated Risk Reminder&lt;/h4>

 Please note that the Reactive usage methods described in this document may be outdated. Always refer to the latest reactive examples in apache/dubbo-samples for usage.

&lt;/div>

&lt;h2 id="feature-description">Feature Description&lt;/h2>
&lt;p>This feature is based on the Triple protocol and implemented using Project Reactor, supported from version &lt;code>3.1.0&lt;/code> onwards. Users only need to write an IDL file and specify the corresponding Generator for the protobuf plugin to generate and use Stub code that supports the reactive API.&lt;/p></description></item></channel></rss>