blob: d00660af8a6f65c351facbc3ae94dacfd458d995 [file] [log] [blame]
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Apache Dubbo – 快速入门</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/quick-start/</link><description>Recent content in 快速入门 on Apache Dubbo</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><atom:link href="https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/quick-start/index.xml" rel="self" type="application/rss+xml"/><item><title>Overview: 1 - 零基础快速部署一个微服务应用</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/quick-start/brief/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/quick-start/brief/</guid><description>
&lt;h2 id="背景">背景&lt;/h2>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/architecture.png" alt="arch-service-discovery">&lt;/p>
&lt;p>Dubbo 作为一款微服务框架,最重要的是向用户提供跨进程的 RPC 远程调用能力。如上图所示,Dubbo 的服务消费者(Consumer)通过一系列的工作将请求发送给服务提供者(Provider)。&lt;/p>
&lt;p>为了实现这样一个目标,Dubbo 引入了注册中心(Registry)组件,通过注册中心,服务消费者可以感知到服务提供者的连接方式,从而将请求发送给正确的服务提供者。&lt;/p>
&lt;h2 id="目标">目标&lt;/h2>
&lt;p>了解微服务调用的方式以及 Dubbo 的能力&lt;/p>
&lt;h2 id="难度">难度&lt;/h2>
&lt;p>低&lt;/p>
&lt;h2 id="环境要求">环境要求&lt;/h2>
&lt;ul>
&lt;li>
&lt;p>系统:Windows、Linux、MacOS&lt;/p>
&lt;/li>
&lt;li>
&lt;p>JDK 8 及以上(推荐使用 JDK17)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Git&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Docker (可选)&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="动手实践">动手实践&lt;/h2>
&lt;p>本章将通过几个简单的命令,一步一步教你如何部署并运行一个最简单的 Dubbo 用例。&lt;/p>
&lt;h3 id="1-获取测试工程">1. 获取测试工程&lt;/h3>
&lt;p>在开始整个教程之前,我们需要先获取测试工程的代码。Dubbo 的所有测试用例代码都存储在 &lt;a href="https://github.com/apache/dubbo-samples">apache/dubbo-samples&lt;/a> 这个仓库中,以下这个命令可以帮你获取 Samples 仓库的所有代码。&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-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>git clone --depth&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">1&lt;/span> --branch master git@github.com:apache/dubbo-samples.git
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="2-认识-dubbo-samples-项目结构">2. 认识 Dubbo Samples 项目结构&lt;/h3>
&lt;p>在将 &lt;a href="https://github.com/apache/dubbo-samples">apache/dubbo-samples&lt;/a> 这个仓库 clone 到本地以后,本小节将就仓库的具体组织方式做说明。&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-gdscript3" data-lang="gdscript3">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── codestyle &lt;span style="color:#719e07">//&lt;/span> 开发使用的 style 配置文件
&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:#2aa198">1&lt;/span>&lt;span style="color:#719e07">-&lt;/span>basic &lt;span style="color:#719e07">//&lt;/span> 基础的入门用例
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── &lt;span style="color:#2aa198">2&lt;/span>&lt;span style="color:#719e07">-&lt;/span>advanced &lt;span style="color:#719e07">//&lt;/span> 高级用法
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── &lt;span style="color:#2aa198">3&lt;/span>&lt;span style="color:#719e07">-&lt;/span>extensions &lt;span style="color:#719e07">//&lt;/span> 扩展使用示例
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── &lt;span style="color:#2aa198">4&lt;/span>&lt;span style="color:#719e07">-&lt;/span>governance &lt;span style="color:#719e07">//&lt;/span> 服务治理用例
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── &lt;span style="color:#2aa198">10&lt;/span>&lt;span style="color:#719e07">-&lt;/span>task &lt;span style="color:#719e07">//&lt;/span> Dubbo 学习系列示例
&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:#2aa198">99&lt;/span>&lt;span style="color:#719e07">-&lt;/span>integration &lt;span style="color:#719e07">//&lt;/span> 集成测试使用
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── test &lt;span style="color:#719e07">//&lt;/span> 集成测试使用
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>└── tools &lt;span style="color:#719e07">//&lt;/span> 三方组件快速启动工具
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>如上表所示,&lt;a href="https://github.com/apache/dubbo-samples">apache/dubbo-samples&lt;/a> 主要由三个部分组成:代码风格文件、测试代码、集成测试。&lt;/p>
&lt;ol>
&lt;li>
&lt;p>代码风格文件是开发 Dubbo 代码的时候可以使用,其中包括了 IntelliJ IDEA 的配置文件。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>测试代码即本教材所需要的核心内容。目前包括了 5 个部分的内容:面向初学者的 basic 入门用例、面向开发人员的 advanced 高级用法、面向中间件维护者的 extensions Dubbo 周边扩展使用示例、面向生产的 governance 服务治理用例以及 Dubbo 学习系列。本文将基于 basic 入门用例中最简单的 Dubbo API 使用方式进行讲解。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>集成测试是 Dubbo 的质量保证体系中重要的一环,Dubbo 的每个版本都会对所有的 samples 进行回归验证,保证 Dubbo 的所有变更都不会影响 samples 的使用。&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h3 id="3-启动一个简易的注册中心">3. 启动一个简易的注册中心&lt;/h3>
&lt;p>从这一小节开始,将正式通过三个命令部署一个微服务应用。&lt;/p>
&lt;p>从 &lt;a href="#%E8%83%8C%E6%99%AF">背景&lt;/a> 一节中可知,运行起 Dubbo 应用的一个大前提是部署一个注册中心,为了让本教程更易于上手,我们提供了一个基于 Apache Zookeeper 注册中心的简易启动器,如果您需要在生产环境部署注册中心,请参考&lt;a href="https://dubbo.apache.org/">生产环境初始化&lt;/a>一文部署高可用的注册中心。&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-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>Windows:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Linux / MacOS:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw clean compile exec:java -pl tools/embedded-zookeeper
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>注:需要开一个独立的 terminal 运行,命令将会保持一直执行的状态。
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Docker:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker run --name some-zookeeper -p 2181:2181 --restart always -d zookeeper
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>在执行完上述命令以后,等待一会出现如下图所示的日志即代表注册中心启动完毕,可以继续执行后续任务。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-01-19-15-55-23-image.png" alt="registry">&lt;/p>
&lt;h3 id="4-启动服务提供者">4. 启动服务提供者&lt;/h3>
&lt;p>在启动了注册中心之后,下一步是启动一个对外提供服务的服务提供者。在 dubbo-samples 中也提供了对应的示例,可以通过以下命令快速拉起。&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-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>Windows:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.mainClass&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.samples.provider.Application&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>Linux / MacOS:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.mainClass&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.samples.provider.Application&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>注:需要开一个独立的 terminal 运行,命令将会保持一直执行的状态。
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>在执行完上述命令以后,等待一会出现如下图所示的日志(&lt;code>DubboBootstrap awaiting&lt;/code>)即代表服务提供者启动完毕,标志着该服务提供者可以对外提供服务了。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-01-19-15-56-09-image.png" alt="provider">&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>[19/01/23 03:55:49:049 CST] org.apache.dubbo.samples.provider.Application.main() INFO bootstrap.DubboBootstrap: [DUBBO] DubboBootstrap awaiting ..., dubbo version: 3.2.0-beta.3, current host: 169.254.44.42
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="5-启动服务消费者">5. 启动服务消费者&lt;/h3>
&lt;p>最后一步是启动一个服务消费者来调用服务提供者,也即是 RPC 调用的核心,为服务消费者提供调用服务提供者的桥梁。&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-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>Windows:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.mainClass&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.samples.client.Application&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>Linux / MacOS:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.mainClass&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.samples.client.Application&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>在执行完上述命令以后,等待一会出现如下图所示的日志(&lt;code>hi, dubbo&lt;/code>),打印出的数据就是服务提供者处理之后返回的,标志着一次服务调用的成功。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-01-19-16-30-14-image.png" alt="consumer">&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>Receive result ======&amp;gt; hi, dubbo
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="延伸阅读">延伸阅读&lt;/h2>
&lt;h3 id="1-消费端是怎么找到服务端的">1. 消费端是怎么找到服务端的?&lt;/h3>
&lt;p>在本用例中的步骤 3 启动了一个 Zookeeper 的注册中心,服务提供者会向注册中心中写入自己的地址,供服务消费者获取。&lt;/p>
&lt;p>Dubbo 会在 Zookeeper 的 &lt;code>/dubbo/interfaceName&lt;/code> 和 &lt;code>/services/appName&lt;/code> 下写入服务提供者的连接信息。&lt;/p>
&lt;p>如下所示是 Zookeeper 上的数据示例:&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-gdscript3" data-lang="gdscript3">&lt;span style="display:flex;">&lt;span>[zk: localhost:&lt;span style="color:#2aa198">2181&lt;/span>(CONNECTED) &lt;span style="color:#2aa198">5&lt;/span>] ls &lt;span style="color:#719e07">/&lt;/span>dubbo&lt;span style="color:#719e07">/&lt;/span>org&lt;span style="color:#719e07">.&lt;/span>apache&lt;span style="color:#719e07">.&lt;/span>dubbo&lt;span style="color:#719e07">.&lt;/span>samples&lt;span style="color:#719e07">.&lt;/span>api&lt;span style="color:#719e07">.&lt;/span>GreetingsService&lt;span style="color:#719e07">/&lt;/span>providers
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[dubbo&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>A&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">2&lt;/span>F&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">2&lt;/span>F30&lt;span style="color:#719e07">.&lt;/span>&lt;span style="color:#2aa198">221.146&lt;/span>&lt;span style="color:#719e07">.&lt;/span>&lt;span style="color:#2aa198">35&lt;/span>&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>A20880&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">2&lt;/span>Forg&lt;span style="color:#719e07">.&lt;/span>apache&lt;span style="color:#719e07">.&lt;/span>dubbo&lt;span style="color:#719e07">.&lt;/span>samples&lt;span style="color:#719e07">.&lt;/span>api&lt;span style="color:#719e07">.&lt;/span>GreetingsService&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>Fanyhost&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>Dtrue&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">26&lt;/span>application&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>Dfirst&lt;span style="color:#719e07">-&lt;/span>dubbo&lt;span style="color:#719e07">-&lt;/span>provider&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">26&lt;/span>background&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>Dfalse&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">26&lt;/span>deprecated&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>Dfalse&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">26&lt;/span>dubbo&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>D2&lt;span style="color:#719e07">.&lt;/span>&lt;span style="color:#2aa198">0.2&lt;/span>&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">26&lt;/span>dynamic&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>Dtrue&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">26&lt;/span>environment&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>Dproduct&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">26&lt;/span>generic&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>Dfalse&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">26&lt;/span>interface&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>Dorg&lt;span style="color:#719e07">.&lt;/span>apache&lt;span style="color:#719e07">.&lt;/span>dubbo&lt;span style="color:#719e07">.&lt;/span>samples&lt;span style="color:#719e07">.&lt;/span>api&lt;span style="color:#719e07">.&lt;/span>GreetingsService&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">26&lt;/span>ipv6&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>Dfd00&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>A1&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>A5&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>A5200&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>A3218&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>A774a&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>A4f67&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>A2341&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">26&lt;/span>methods&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>DsayHi&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">26&lt;/span>pid&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>D85639&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">26&lt;/span>release&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>D3&lt;span style="color:#719e07">.&lt;/span>&lt;span style="color:#2aa198">1.4&lt;/span>&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">26&lt;/span>service&lt;span style="color:#719e07">-&lt;/span>name&lt;span style="color:#719e07">-&lt;/span>mapping&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>Dtrue&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">26&lt;/span>side&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>Dprovider&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">26&lt;/span>timestamp&lt;span style="color:#719e07">%&lt;/span>&lt;span style="color:#2aa198">3&lt;/span>D1674960780647]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[zk: localhost:&lt;span style="color:#2aa198">2181&lt;/span>(CONNECTED) &lt;span style="color:#2aa198">2&lt;/span>] ls &lt;span style="color:#719e07">/&lt;/span>services&lt;span style="color:#719e07">/&lt;/span>first&lt;span style="color:#719e07">-&lt;/span>dubbo&lt;span style="color:#719e07">-&lt;/span>provider
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[&lt;span style="color:#2aa198">30.221&lt;/span>&lt;span style="color:#719e07">.&lt;/span>&lt;span style="color:#2aa198">146.35&lt;/span>:&lt;span style="color:#2aa198">20880&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[zk: localhost:&lt;span style="color:#2aa198">2181&lt;/span>(CONNECTED) &lt;span style="color:#2aa198">3&lt;/span>] get &lt;span style="color:#719e07">/&lt;/span>services&lt;span style="color:#719e07">/&lt;/span>first&lt;span style="color:#719e07">-&lt;/span>dubbo&lt;span style="color:#719e07">-&lt;/span>provider&lt;span style="color:#719e07">/&lt;/span>&lt;span style="color:#2aa198">30.221&lt;/span>&lt;span style="color:#719e07">.&lt;/span>&lt;span style="color:#2aa198">146.35&lt;/span>:&lt;span style="color:#2aa198">20880&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{&lt;span style="color:#2aa198">&amp;#34;name&amp;#34;&lt;/span>:&lt;span style="color:#2aa198">&amp;#34;first-dubbo-provider&amp;#34;&lt;/span>,&lt;span style="color:#2aa198">&amp;#34;id&amp;#34;&lt;/span>:&lt;span style="color:#2aa198">&amp;#34;30.221.146.35:20880&amp;#34;&lt;/span>,&lt;span style="color:#2aa198">&amp;#34;address&amp;#34;&lt;/span>:&lt;span style="color:#2aa198">&amp;#34;30.221.146.35&amp;#34;&lt;/span>,&lt;span style="color:#2aa198">&amp;#34;port&amp;#34;&lt;/span>:&lt;span style="color:#2aa198">20880&lt;/span>,&lt;span style="color:#2aa198">&amp;#34;sslPort&amp;#34;&lt;/span>:null,&lt;span style="color:#2aa198">&amp;#34;payload&amp;#34;&lt;/span>:{&lt;span style="color:#2aa198">&amp;#34;@class&amp;#34;&lt;/span>:&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.registry.zookeeper.ZookeeperInstance&amp;#34;&lt;/span>,&lt;span style="color:#2aa198">&amp;#34;id&amp;#34;&lt;/span>:&lt;span style="color:#2aa198">&amp;#34;30.221.146.35:20880&amp;#34;&lt;/span>,&lt;span style="color:#2aa198">&amp;#34;name&amp;#34;&lt;/span>:&lt;span style="color:#2aa198">&amp;#34;first-dubbo-provider&amp;#34;&lt;/span>,&lt;span style="color:#2aa198">&amp;#34;metadata&amp;#34;&lt;/span>:{&lt;span style="color:#2aa198">&amp;#34;dubbo.endpoints&amp;#34;&lt;/span>:&lt;span style="color:#2aa198">&amp;#34;[{&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">port&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">:20880,&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">protocol&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">:&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">dubbo&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">}]&amp;#34;&lt;/span>,&lt;span style="color:#2aa198">&amp;#34;dubbo.metadata-service.url-params&amp;#34;&lt;/span>:&lt;span style="color:#2aa198">&amp;#34;{&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">connections&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">:&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">1&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">,&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">version&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">:&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">1.0.0&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">,&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">dubbo&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">:&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">2.0.2&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">,&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">release&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">:&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">3.1.4&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">,&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">side&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">:&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">provider&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">,&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">ipv6&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">:&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">fd00:1:5:5200:3218:774a:4f67:2341&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">,&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">port&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">:&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">20880&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">,&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">protocol&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">:&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">dubbo&lt;/span>&lt;span style="color:#cb4b16">\&amp;#34;&lt;/span>&lt;span style="color:#2aa198">}&amp;#34;&lt;/span>,&lt;span style="color:#2aa198">&amp;#34;dubbo.metadata.revision&amp;#34;&lt;/span>:&lt;span style="color:#2aa198">&amp;#34;871fbc9cb2730caea9b0d858852d5ede&amp;#34;&lt;/span>,&lt;span style="color:#2aa198">&amp;#34;dubbo.metadata.storage-type&amp;#34;&lt;/span>:&lt;span style="color:#2aa198">&amp;#34;local&amp;#34;&lt;/span>,&lt;span style="color:#2aa198">&amp;#34;ipv6&amp;#34;&lt;/span>:&lt;span style="color:#2aa198">&amp;#34;fd00:1:5:5200:3218:774a:4f67:2341&amp;#34;&lt;/span>,&lt;span style="color:#2aa198">&amp;#34;timestamp&amp;#34;&lt;/span>:&lt;span style="color:#2aa198">&amp;#34;1674960780647&amp;#34;&lt;/span>}},&lt;span style="color:#2aa198">&amp;#34;registrationTimeUTC&amp;#34;&lt;/span>:&lt;span style="color:#2aa198">1674960781893&lt;/span>,&lt;span style="color:#2aa198">&amp;#34;serviceType&amp;#34;&lt;/span>:&lt;span style="color:#2aa198">&amp;#34;DYNAMIC&amp;#34;&lt;/span>,&lt;span style="color:#2aa198">&amp;#34;uriSpec&amp;#34;&lt;/span>:null}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>更多关于 Dubbo 服务发现模型的细节,可以参考&lt;a href="https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/concepts-and-architecture/service-discovery/">服务发现&lt;/a>一文。&lt;/p>
&lt;h3 id="2-消费端是如何发起请求的">2. 消费端是如何发起请求的?&lt;/h3>
&lt;p>在 Dubbo 的调用模型中,起到连接服务消费者和服务提供者的桥梁是接口。&lt;/p>
&lt;p>服务提供者通过对指定接口进行实现,服务消费者通过 Dubbo 去订阅这个接口。服务消费者调用接口的过程中 Dubbo 会将请求封装成网络请求,然后发送到服务提供者进行实际的调用。&lt;/p>
&lt;p>在本用例中,定义了一个 &lt;code>GreetingsService&lt;/code> 的接口,这个接口有一个名为 &lt;code>sayHi&lt;/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:#586e75">// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/api/GreetingsService.java&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">package&lt;/span> org.apache.dubbo.samples.api;
&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">GreetingsService&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:#268bd2">sayHi&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>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>服务消费者通过 Dubbo 的 API 可以获取这个 &lt;code>GreetingsService&lt;/code> 接口的代理,然后就可以按照普通的接口调用方式进行调用。&lt;strong>得益于 Dubbo 的动态代理机制,这一切都像本地调用一样。&lt;/strong>&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:#586e75">// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/client/Application.java&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">// 获取订阅到的 Stub&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>GreetingsService service &lt;span style="color:#719e07">=&lt;/span> reference.get();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">// 像普通的 java 接口一样调用&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>String message &lt;span style="color:#719e07">=&lt;/span> service.sayHi(&lt;span style="color:#2aa198">&amp;#34;dubbo&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="3-服务端可以部署多个吗">3. 服务端可以部署多个吗?&lt;/h3>
&lt;p>可以,本小节将演示如何启动一个服务端&lt;strong>集群&lt;/strong>。&lt;/p>
&lt;p>1)启动一个注册中心,可以参考动手实践中第 3 小节的&lt;a href="#3-%E5%90%AF%E5%8A%A8%E4%B8%80%E4%B8%AA%E7%AE%80%E6%98%93%E7%9A%84%E6%B3%A8%E5%86%8C%E4%B8%AD%E5%BF%83">教程&lt;/a>&lt;/p>
&lt;p>2)修改服务提供者返回的数据,让第一个启动的服务提供者返回 &lt;code>hi, dubbo. I am provider 1.&lt;/code>&lt;/p>
&lt;p>修改 &lt;code>1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java&lt;/code> 文件的第 25 行如下所示。&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:#586e75">// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java&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">package&lt;/span> org.apache.dubbo.samples.provider;
&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.samples.api.GreetingsService;
&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">GreetingsServiceImpl&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> GreetingsService {
&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> String &lt;span style="color:#268bd2">sayHi&lt;/span>(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:#2aa198">&amp;#34;hi, &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;. I am provider 1.&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>3)启动第一个服务提供者,可以参考动手实践中第 4 小节的&lt;a href="#4-%E5%90%AF%E5%8A%A8%E6%9C%8D%E5%8A%A1%E6%8F%90%E4%BE%9B%E8%80%85">教程&lt;/a>&lt;/p>
&lt;p>4)修改服务提供者返回的数据,让第二个启动的服务提供者返回 &lt;code>hi, dubbo. I am provider 2.&lt;/code>&lt;/p>
&lt;p>修改 &lt;code>1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java&lt;/code> 文件的第 25 行如下所示。&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:#586e75">// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java&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">package&lt;/span> org.apache.dubbo.samples.provider;
&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.samples.api.GreetingsService;
&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">GreetingsServiceImpl&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> GreetingsService {
&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> String &lt;span style="color:#268bd2">sayHi&lt;/span>(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:#2aa198">&amp;#34;hi, &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;. I am provider 2.&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>4)启动第二个服务提供者,可以参考动手实践中第 4 小节的&lt;a href="#4-%E5%90%AF%E5%8A%A8%E6%9C%8D%E5%8A%A1%E6%8F%90%E4%BE%9B%E8%80%85">教程&lt;/a>&lt;/p>
&lt;p>5)启动服务消费者,可以参考动手实践中第 5 小节的&lt;a href="#5-%E5%90%AF%E5%8A%A8%E6%9C%8D%E5%8A%A1%E6%B6%88%E8%B4%B9%E8%80%85">教程&lt;/a>。多次启动消费者可以看到返回的结果是不一样的。&lt;/p>
&lt;p>在 dubbo-samples 中也提供了一个会定时发起调用的消费端应用&lt;code>org.apache.dubbo.samples.client.AlwaysApplication&lt;/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-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>Windows:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.mainClass&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.samples.client.AlwaysApplication&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>Linux / MacOS:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.mainClass&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.samples.client.AlwaysApplication&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>启动后可以看到类似以下的日志,消费端会随机调用到不同的服务提供者,返回的结果也是远端的服务提供者觉得其结果。&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>Sun Jan 29 11:23:37 CST 2023 Receive result ======&amp;gt; hi, dubbo. I am provider 1.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Sun Jan 29 11:23:38 CST 2023 Receive result ======&amp;gt; hi, dubbo. I am provider 2.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Sun Jan 29 11:23:39 CST 2023 Receive result ======&amp;gt; hi, dubbo. I am provider 2.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Sun Jan 29 11:23:40 CST 2023 Receive result ======&amp;gt; hi, dubbo. I am provider 1.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Sun Jan 29 11:23:41 CST 2023 Receive result ======&amp;gt; hi, dubbo. I am provider 1.
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="4-这个用例复杂吗">4. 这个用例复杂吗?&lt;/h3>
&lt;p>不,Dubbo 只需要简单的配置就可以实现稳定、高效的远程调用。&lt;/p>
&lt;p>以下是一个服务提供者的简单示例,通过定义若干个配置就可以启动。&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:#586e75">// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/Application.java&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>ServiceConfig&lt;span style="color:#719e07">&amp;lt;&lt;/span>GreetingsService&lt;span style="color:#719e07">&amp;gt;&lt;/span> service &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#719e07">new&lt;/span> ServiceConfig&lt;span style="color:#719e07">&amp;lt;&amp;gt;&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>service.setInterface(GreetingsService.class);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>service.setRef(&lt;span style="color:#719e07">new&lt;/span> GreetingsServiceImpl());
&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">// 启动 Dubbo&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>DubboBootstrap.getInstance()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .application(&lt;span style="color:#2aa198">&amp;#34;first-dubbo-provider&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .registry(&lt;span style="color:#719e07">new&lt;/span> RegistryConfig(ZOOKEEPER_ADDRESS))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .protocol(&lt;span style="color:#719e07">new&lt;/span> ProtocolConfig(&lt;span style="color:#2aa198">&amp;#34;dubbo&amp;#34;&lt;/span>, &lt;span style="color:#719e07">-&lt;/span>1))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .service(service)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .start();
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>以下是一个服务消费者的简单示例,通过定义若干个配置启动后就可以获取到对应的代理对象,之后用户完全不需要感知这个对象背后的复杂实现,&lt;strong>一切只需要和本地调用一样就行了&lt;/strong>。&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:#586e75">// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/client/Application.java&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>ReferenceConfig&lt;span style="color:#719e07">&amp;lt;&lt;/span>GreetingsService&lt;span style="color:#719e07">&amp;gt;&lt;/span> reference &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>reference.setInterface(GreetingsService.class);
&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">// 启动 Dubbo&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>DubboBootstrap.getInstance()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .application(&lt;span style="color:#2aa198">&amp;#34;first-dubbo-consumer&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .registry(&lt;span style="color:#719e07">new&lt;/span> RegistryConfig(ZOOKEEPER_ADDRESS))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .reference(reference)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .start();
&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">// 获取订阅到的 Stub&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>GreetingsService service &lt;span style="color:#719e07">=&lt;/span> reference.get();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#586e75">// 像普通的 java 接口一样调用&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>String message &lt;span style="color:#719e07">=&lt;/span> service.sayHi(&lt;span style="color:#2aa198">&amp;#34;dubbo&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="更多">更多&lt;/h2>
&lt;p>本用例介绍了一个 RPC 远程调用的基础流程,通过启动注册中心、服务提供者、服务消费者三个节点来模拟一个微服务的部署架构。&lt;/p>
&lt;p>下一个教程中,将就服务提供者和服务消费者分别都做了什么配置进行讲解,&lt;a href="../api/">从零告诉你如何搭建一个微服务应用&lt;/a>。&lt;/p></description></item><item><title>Overview: 2 - 基于 Dubbo API 开发微服务应用</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/quick-start/api/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/quick-start/api/</guid><description>
&lt;h2 id="目标">目标&lt;/h2>
&lt;p>从零上手开发基于 Dubbo 的微服务&lt;/p>
&lt;h2 id="难度">难度&lt;/h2>
&lt;p>低&lt;/p>
&lt;h2 id="环境要求">环境要求&lt;/h2>
&lt;ul>
&lt;li>
&lt;p>系统:Windows、Linux、MacOS&lt;/p>
&lt;/li>
&lt;li>
&lt;p>JDK 8 及以上(推荐使用 JDK17)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Git&lt;/p>
&lt;/li>
&lt;li>
&lt;p>IntelliJ IDEA(可选)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Docker (可选)&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="动手实践">动手实践&lt;/h2>
&lt;p>本章将通过手把手的教程一步一步教你如何从零开发一个微服务应用。&lt;/p>
&lt;h3 id="1-启动注册中心">1. 启动注册中心&lt;/h3>
&lt;p>对于一个微服务化的应用来说,注册中心是不可或缺的一个组件。只有通过注册中心,消费端才可以成功发现服务端的地址信息,进而进行调用。&lt;/p>
&lt;p>为了让本教程更易于上手,我们提供了一个基于 Apache Zookeeper 注册中心的简易启动器,如果您需要在生产环境部署注册中心,请参考&lt;a href="https://dubbo.apache.org/">生产环境初始化&lt;/a>一文部署高可用的注册中心。&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-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>Windows:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>git clone --depth&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">1&lt;/span> --branch master git@github.com:apache/dubbo-samples.git
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#b58900">cd&lt;/span> dubbo-samples
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Linux / MacOS:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>git clone --depth&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">1&lt;/span> --branch master git@github.com:apache/dubbo-samples.git
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#b58900">cd&lt;/span> dubbo-samples
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw clean compile exec:java -pl tools/embedded-zookeeper
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Docker:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker run --name some-zookeeper --restart always -d zookeeper
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="2-初始化项目">2. 初始化项目&lt;/h3>
&lt;p>从本小节开始,将基于 IntelliJ IDEA 进行工程的搭建以及测试。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-01-31-10-50-33-image.png" alt="img">&lt;/p>
&lt;p>如上图所示,可以建立一个基础的项目。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-01-31-15-42-11-image.png" alt="img">&lt;/p>
&lt;p>在初始化完项目之后,需要在 &lt;code>src/main/java&lt;/code> 目录下创建 &lt;code>org.apache.dubbo.samples.api&lt;/code> 、&lt;code>org.apache.dubbo.samples.client&lt;/code> 和 &lt;code>org.apache.dubbo.samples.provider&lt;/code> 三个 package。&lt;/p>
&lt;p>后续我们将在 &lt;code>api&lt;/code> 下创建对应的接口,在 &lt;code>client&lt;/code> 下创建对应客户端订阅服务的功能,在 &lt;code>provider&lt;/code> 下创建对应服务端的实现以及发布服务的功能。&lt;/p>
&lt;p>上述三个 package 分别对应了应用共同依赖的 api、消费端应用的模块、服务端应用的模块。在实际部署中需要拆成三个工程,消费端和服务的共同依赖 api 模块。从简单出发,本教程将在同一个工程中进行开发,区分多个启动类。&lt;/p>
&lt;h3 id="3-添加-maven-依赖">3. 添加 Maven 依赖&lt;/h3>
&lt;p>在初始化完项目以后,我们需要先添加 Dubbo 相关的 maven 依赖。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-01-31-10-51-06-image.png" alt="img">&lt;/p>
&lt;p>编辑 &lt;code>pom.xml&lt;/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-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;dependencies&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.apache.dubbo&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&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.2.0-beta.4&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>&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.apache.curator&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>curator-x-discovery&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.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;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.zookeeper&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>zookeeper&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.8.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;exclusions&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;exclusion&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>io.netty&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>netty-handler&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;/exclusion&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;exclusion&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>io.netty&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>netty-transport-native-epoll&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;/exclusion&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;/exclusions&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;/dependencies&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>在这份配置中,定义了 dubbo 和 zookeeper(以及对应的连接器 curator)的依赖。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-01-31-16-06-15-image.png" alt="img">&lt;/p>
&lt;p>添加了上述的配置以后,可以通过 IDEA 的 &lt;code>Maven - Reload All Maven Projects&lt;/code> 刷新依赖。&lt;/p>
&lt;h3 id="4-定义服务接口">4. 定义服务接口&lt;/h3>
&lt;p>服务接口 Dubbo 中沟通消费端和服务端的桥梁。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-01-31-15-42-43-image.png" alt="img">&lt;/p>
&lt;p>在 &lt;code>org.apache.dubbo.samples.api&lt;/code> 下建立 &lt;code>GreetingsService&lt;/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:#719e07">package&lt;/span> org.apache.dubbo.samples.api;
&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">GreetingsService&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:#268bd2">sayHi&lt;/span>(String name);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>在 &lt;code>GreetingsService&lt;/code> 中,定义了 &lt;code>sayHi&lt;/code> 这个方法。后续服务端发布的服务,消费端订阅的服务都是围绕着 &lt;code>GreetingsService&lt;/code> 接口展开的。&lt;/p>
&lt;h3 id="5-定义服务端的实现">5. 定义服务端的实现&lt;/h3>
&lt;p>定义了服务接口之后,可以在服务端这一侧定义对应的实现,这部分的实现相对于消费端来说是远端的实现,本地没有相关的信息。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-01-31-15-43-34-image.png" alt="img">&lt;/p>
&lt;p>在 &lt;code>org.apache.dubbo.samples.provider&lt;/code> 下建立 &lt;code>GreetingsServiceImpl&lt;/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:#719e07">package&lt;/span> org.apache.dubbo.samples.provider;
&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.samples.api.GreetingsService;
&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">GreetingsServiceImpl&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> GreetingsService {
&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> String &lt;span style="color:#268bd2">sayHi&lt;/span>(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:#2aa198">&amp;#34;hi, &amp;#34;&lt;/span> &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;/code>&lt;/pre>&lt;/div>&lt;p>在 &lt;code>GreetingsServiceImpl&lt;/code> 中,实现了 &lt;code>GreetingsService&lt;/code> 接口,对于 &lt;code>sayHi&lt;/code> 方法返回 &lt;code>hi, name&lt;/code>。&lt;/p>
&lt;h3 id="6-服务端发布服务">6. 服务端发布服务&lt;/h3>
&lt;p>在实现了服务之后,本小节将通过 Dubbo 的 API 在网络上发布这个服务。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-01-31-15-44-22-image.png" alt="img">&lt;/p>
&lt;p>在 &lt;code>org.apache.dubbo.samples.provider&lt;/code> 下建立 &lt;code>Application&lt;/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:#719e07">package&lt;/span> org.apache.dubbo.samples.provider;
&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.config.ProtocolConfig;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.config.RegistryConfig;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.config.ServiceConfig;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.config.bootstrap.DubboBootstrap;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.samples.api.GreetingsService;
&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">Application&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">static&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">main&lt;/span>(String&lt;span style="color:#719e07">[]&lt;/span> args) {
&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> ServiceConfig&lt;span style="color:#719e07">&amp;lt;&lt;/span>GreetingsService&lt;span style="color:#719e07">&amp;gt;&lt;/span> service &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#719e07">new&lt;/span> ServiceConfig&lt;span style="color:#719e07">&amp;lt;&amp;gt;&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> service.setInterface(GreetingsService.class);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> service.setRef(&lt;span style="color:#719e07">new&lt;/span> GreetingsServiceImpl());
&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">// 启动 Dubbo&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> DubboBootstrap.getInstance()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .application(&lt;span style="color:#2aa198">&amp;#34;first-dubbo-provider&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .registry(&lt;span style="color:#719e07">new&lt;/span> RegistryConfig(&lt;span style="color:#2aa198">&amp;#34;zookeeper://127.0.0.1:2181&amp;#34;&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .protocol(&lt;span style="color:#719e07">new&lt;/span> ProtocolConfig(&lt;span style="color:#2aa198">&amp;#34;dubbo&amp;#34;&lt;/span>, &lt;span style="color:#719e07">-&lt;/span>1))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .service(service)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .start()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .await();
&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>在 &lt;code>org.apache.dubbo.samples.provider.Application&lt;/code> 中做了两部分的功能:首先是基于 &lt;code>ServiceConfig&lt;/code> 定义了发布的服务信息,包括接口的信息以及对应的实现类对象;然后是配置 Dubbo 启动器,传入了应用名,注册中心地址,协议的信息以及服务的信息等。&lt;/p>
&lt;p>注:DubboBootstrap 中的&lt;code>registry&lt;/code> 、&lt;code>protocol&lt;/code> 和 &lt;code>service&lt;/code> 可以多次传入。&lt;/p>
&lt;h3 id="7-消费端订阅并调用">7. 消费端订阅并调用&lt;/h3>
&lt;p>对于消费端,可以通过 Dubbo 的 API 可以进行消费端订阅。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-01-31-15-55-09-image.png" alt="img">&lt;/p>
&lt;p>在 &lt;code>org.apache.dubbo.samples.client&lt;/code> 下建立 &lt;code>Application&lt;/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:#719e07">package&lt;/span> org.apache.dubbo.samples.client;
&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> java.io.IOException;
&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.config.ReferenceConfig;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.config.RegistryConfig;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.config.bootstrap.DubboBootstrap;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.samples.api.GreetingsService;
&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">Application&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">static&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">main&lt;/span>(String&lt;span style="color:#719e07">[]&lt;/span> args) &lt;span style="color:#268bd2">throws&lt;/span> IOException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ReferenceConfig&lt;span style="color:#719e07">&amp;lt;&lt;/span>GreetingsService&lt;span style="color:#719e07">&amp;gt;&lt;/span> reference &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> reference.setInterface(GreetingsService.class);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> DubboBootstrap.getInstance()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .application(&lt;span style="color:#2aa198">&amp;#34;first-dubbo-consumer&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .registry(&lt;span style="color:#719e07">new&lt;/span> RegistryConfig(&lt;span style="color:#2aa198">&amp;#34;zookeeper://127.0.0.1:2181&amp;#34;&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .reference(reference);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> GreetingsService service &lt;span style="color:#719e07">=&lt;/span> reference.get();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> String message &lt;span style="color:#719e07">=&lt;/span> service.sayHi(&lt;span style="color:#2aa198">&amp;#34;dubbo&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.out.println(&lt;span style="color:#2aa198">&amp;#34;Receive result ======&amp;gt; &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> message);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.in.read();
&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>在 &lt;code>org.apache.dubbo.samples.client.Application&lt;/code> 中做了三部分的功能:&lt;/p>
&lt;p>首先是基于 &lt;code>ReferenceConfig&lt;/code> 定义了订阅的服务信息,包括接口的信息。&lt;/p>
&lt;p>其次是配置 Dubbo 启动器,传入了应用名,注册中心地址,协议的信息以及服务的信息等。&lt;/p>
&lt;p>最后是获取到动态代理的对象并进行调用。&lt;/p>
&lt;p>注:DubboBootstrap 中支持 &lt;code>service&lt;/code> 和 &lt;code>reference&lt;/code> 可以同时传入,意味着一个应用可以同时即是消费端、也是服务端。&lt;/p>
&lt;h3 id="8-启动应用">8. 启动应用&lt;/h3>
&lt;p>截止第 7 步,代码就已经开发完成了,本小节将启动整个项目并进行验证。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-01-31-15-52-26-image.png" alt="img">&lt;/p>
&lt;p>首先是启动 &lt;code>org.apache.dubbo.samples.provider.Application&lt;/code> ,等待一会出现如下图所示的日志(&lt;code>DubboBootstrap awaiting&lt;/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-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>[DUBBO] DubboBootstrap awaiting ..., dubbo version: 3.2.0-beta.4, current host: 169.254.44.42
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>然后是启动&lt;code>org.apache.dubbo.samples.client.Application&lt;/code> ,等待一会出现如下图所示的日志(&lt;code>hi, dubbo&lt;/code> )即代表服务消费端启动完毕并调用到服务端成功获取结果。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-01-31-15-54-42-image.png" alt="img">&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>Receive result ======&amp;gt; hi, dubbo
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="延伸阅读">延伸阅读&lt;/h2>
&lt;h3 id="1-dubbo-的配置介绍">1. Dubbo 的配置介绍&lt;/h3>
&lt;p>Dubbo 的主要配置入口有&lt;code>ReferenceConfig&lt;/code> 、&lt;code>ServiceConfig&lt;/code> 和 &lt;code>DubboBootstrap&lt;/code> ,更多的细节可以参考 &lt;a href="https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/config/api/">API 配置 | Apache Dubbo&lt;/a> 一文。&lt;/p>
&lt;h3 id="2-除了-api-方式其他的使用方式">2. 除了 API 方式其他的使用方式&lt;/h3>
&lt;p>Dubbo 除了 API 方式还支持 Spring XML、Annotation、Spring Boot 等配置方式,在下一个教程中将就 Spring Boot 配置方式讲解如何进行快速开发。&lt;/p>
&lt;p>关于 XML 和 Annotation 的细节可以参考 &lt;a href="https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/config/xml/">XML 配置 | Apache Dubbo&lt;/a>、&lt;a href="https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/config/annotation/">Annotation 配置 | Apache Dubbo&lt;/a> 疑问。&lt;/p>
&lt;h2 id="更多">更多&lt;/h2>
&lt;p>本教程介绍了如何基于 Dubbo 的纯 API 开发一个微服务应用。下一个教程中,将介绍&lt;a href="../spring-boot/">如何基于 Spring Boot 开发微服务项目&lt;/a>。&lt;/p></description></item><item><title>Overview: 3 - 基于 Spring Boot Starter 开发微服务应用</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/quick-start/spring-boot/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/quick-start/spring-boot/</guid><description>
&lt;h2 id="目标">目标&lt;/h2>
&lt;p>从零上手开发基于 dubbo-spring-boot-starter 开发微服务,了解 Dubbo x Spring Boot 配置方式。&lt;/p>
&lt;h2 id="难度">难度&lt;/h2>
&lt;p>低&lt;/p>
&lt;h2 id="环境要求">环境要求&lt;/h2>
&lt;ul>
&lt;li>
&lt;p>系统:Windows、Linux、MacOS&lt;/p>
&lt;/li>
&lt;li>
&lt;p>JDK 8 及以上(推荐使用 JDK17)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Git&lt;/p>
&lt;/li>
&lt;li>
&lt;p>IntelliJ IDEA(可选)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Docker (可选)&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="项目介绍">项目介绍&lt;/h2>
&lt;p>在本任务中,将分为 3 个子模块进行独立开发,模拟生产环境下的部署架构。&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>. // apache/dubbo-samples/1-basic/dubbo-samples-spring-boot
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── dubbo-samples-spring-boot-interface // 共享 API 模块
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── dubbo-samples-spring-boot-consumer // 消费端模块
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>└── dubbo-samples-spring-boot-provider // 服务端模块
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>如上所示,共有 3 个模块,其中 &lt;code>interface&lt;/code> 模块被 &lt;code>consumer&lt;/code> 和 &lt;code>provider&lt;/code> 两个模块共同依赖,存储 RPC 通信使用的 API 接口。&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>. // apache/dubbo-samples/1-basic/dubbo-samples-spring-boot
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── dubbo-samples-spring-boot-interface // 共享 API 模块
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   ├── pom.xml
&lt;/span>&lt;/span>&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>│   └── org
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   └── apache
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   └── dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   └── springboot
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   └── demo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   └── DemoService.java // API 接口
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── dubbo-samples-spring-boot-consumer // 消费端模块
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   ├── pom.xml
&lt;/span>&lt;/span>&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>│   │   │   └── org
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   │   └── apache
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   │   └── dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   │   └── springboot
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   │   └── demo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   │   └── consumer
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   │   ├── ConsumerApplication.java // 消费端启动类
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   │   └── Task.java // 消费端模拟调用任务
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   └── resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   └── application.yml // Spring Boot 配置文件
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── dubbo-samples-spring-boot-provider // 服务端模块
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   ├── pom.xml
&lt;/span>&lt;/span>&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>│   │   └── org
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   └── apache
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   └── dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   └── springboot
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   └── demo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   └── provider
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   ├── DemoServiceImpl.java // 服务端实现类
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   │   └── ProviderApplication.java // 服务端启动类
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   └── resources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│   └── application.yml // Spring Boot 配置文件
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>└── pom.xml
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>如上为本教程接下来会使用到的项目的文件结构。&lt;/p>
&lt;h2 id="快速部署基于-samples-直接启动">快速部署(基于 Samples 直接启动)&lt;/h2>
&lt;p>本章将通过几个简单的命令,一步一步教你如何部署并运行一个基于 Dubbo x Spring Boot 的用例。&lt;/p>
&lt;p>注:本章部署的代码细节可以在 &lt;a href="https://github.com/apache/dubbo-samples">apache/dubbo-samples&lt;/a> 这个仓库中 &lt;code>1-basic/dubbo-samples-spring-boot&lt;/code> 中找到,在下一章中也将展开进行讲解。&lt;/p>
&lt;h3 id="1-获取测试工程">1. 获取测试工程&lt;/h3>
&lt;p>在开始整个教程之前,我们需要先获取测试工程的代码。Dubbo 的所有测试用例代码都存储在 &lt;a href="https://github.com/apache/dubbo-samples">apache/dubbo-samples&lt;/a> 这个仓库中,以下这个命令可以帮你获取 Samples 仓库的所有代码。&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-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>git clone --depth&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">1&lt;/span> --branch master git@github.com:apache/dubbo-samples.git
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="2-启动一个简易的注册中心">2. 启动一个简易的注册中心&lt;/h3>
&lt;p>对于一个微服务化的应用来说,注册中心是不可或缺的一个组件。只有通过注册中心,消费端才可以成功发现服务端的地址信息,进而进行调用。&lt;/p>
&lt;p>为了让本教程更易于上手,我们提供了一个基于 Apache Zookeeper 注册中心的简易启动器,如果您需要在生产环境部署注册中心,请参考&lt;a href="https://dubbo.apache.org/">生产环境初始化&lt;/a>一文部署高可用的注册中心。&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-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>Windows:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Linux / MacOS:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw clean compile exec:java -pl tools/embedded-zookeeper
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Docker:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker run --name some-zookeeper -p 2181:2181 --restart always -d zookeeper
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="3-本地打包-api-模块">3. 本地打包 API 模块&lt;/h3>
&lt;p>为了成功编译服务端、消费端模块,需要先在本地打包安装 &lt;code>dubbo-samples-spring-boot-interface&lt;/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-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>./mvnw clean install -pl 1-basic/dubbo-samples-spring-boot
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw clean install -pl 1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-interface
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="4-启动服务提供者">4. 启动服务提供者&lt;/h3>
&lt;p>在启动了注册中心之后,下一步是启动一个对外提供服务的服务提供者。在 dubbo-samples 中也提供了对应的示例,可以通过以下命令快速拉起。&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-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>Windows:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-provider -Dexec.mainClass&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.springboot.demo.provider.ProviderApplication&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>Linux / MacOS:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-provider -Dexec.mainClass&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.springboot.demo.provider.ProviderApplication&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>注:需要开一个独立的 terminal 运行,命令将会保持一直执行的状态。
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>在执行完上述命令以后,等待一会出现如下所示的日志(&lt;code>Current Spring Boot Application is await&lt;/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-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>2023-02-08 17:13:00.357 INFO 80600 --- [lication.main()] o.a.d.c.d.DefaultApplicationDeployer : [DUBBO] Dubbo Application[1.1](dubbo-springboot-demo-provider) is ready., dubbo version: 3.2.0-beta.4, current host: 30.221.128.96
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>2023-02-08 17:13:00.369 INFO 80600 --- [lication.main()] o.a.d.s.d.provider.ProviderApplication : Started ProviderApplication in 9.114 seconds (JVM running for 26.522)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>2023-02-08 17:13:00.387 INFO 80600 --- [pool-1-thread-1] .b.c.e.AwaitingNonWebApplicationListener : [Dubbo] Current Spring Boot Application is await...
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="5-启动服务消费者">5. 启动服务消费者&lt;/h3>
&lt;p>最后一步是启动一个服务消费者来调用服务提供者,也即是 RPC 调用的核心,为服务消费者提供调用服务提供者的桥梁。&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-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>Windows:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-consumer -Dexec.mainClass&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.springboot.demo.consumer.ConsumerApplication&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>Linux / MacOS:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-consumer -Dexec.mainClass&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.springboot.demo.consumer.ConsumerApplication&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>在执行完上述命令以后,等待一会出现如下所示的日志(&lt;code>Hello world&lt;/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-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>2023-02-08 17:14:33.045 INFO 80740 --- [lication.main()] o.a.d.s.d.consumer.ConsumerApplication : Started ConsumerApplication in 11.052 seconds (JVM running for 31.62)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Receive result ======&amp;gt; Hello world
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>2023-02-08 17:14:33.146 INFO 80740 --- [pool-1-thread-1] .b.c.e.AwaitingNonWebApplicationListener : [Dubbo] Current Spring Boot Application is await...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Wed Feb 08 17:14:34 CST 2023 Receive result ======&amp;gt; Hello world
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Wed Feb 08 17:14:35 CST 2023 Receive result ======&amp;gt; Hello world
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Wed Feb 08 17:14:36 CST 2023 Receive result ======&amp;gt; Hello world
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Wed Feb 08 17:14:37 CST 2023 Receive result ======&amp;gt; Hello world
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="动手实践从零代码开发版">动手实践(从零代码开发版)&lt;/h2>
&lt;p>本章将通过手把手的教程一步一步教你如何从零开发一个微服务应用。&lt;/p>
&lt;h3 id="1-启动注册中心">1. 启动注册中心&lt;/h3>
&lt;p>对于一个微服务化的应用来说,注册中心是不可或缺的一个组件。只有通过注册中心,消费端才可以成功发现服务端的地址信息,进而进行调用。&lt;/p>
&lt;p>为了让本教程更易于上手,我们提供了一个基于 Apache Zookeeper 注册中心的简易启动器,如果您需要在生产环境部署注册中心,请参考&lt;a href="https://dubbo.apache.org/">生产环境初始化&lt;/a>一文部署高可用的注册中心。&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-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>Windows:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>git clone --depth&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">1&lt;/span> --branch master git@github.com:apache/dubbo-samples.git
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#b58900">cd&lt;/span> dubbo-samples
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Linux / MacOS:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>git clone --depth&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">1&lt;/span> --branch master git@github.com:apache/dubbo-samples.git
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#b58900">cd&lt;/span> dubbo-samples
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw clean compile exec:java -pl tools/embedded-zookeeper
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Docker:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker run --name some-zookeeper -p 2181:2181 --restart always -d zookeeper
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="2-初始化项目">2. 初始化项目&lt;/h3>
&lt;p>从本小节开始,将基于 IntelliJ IDEA 进行工程的搭建以及测试。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-25-27-image.png" alt="img">&lt;/p>
&lt;p>如上图所示,可以建立一个基础的项目。&lt;/p>
&lt;p>搭建了基础项目之后,我们还需要创建 &lt;code>dubbo-spring-boot-demo-interface&lt;/code> 、&lt;code>dubbo-spring-boot-demo-provider&lt;/code> 和 &lt;code>dubbo-spring-boot-demo-consumer&lt;/code> 三个子模块。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-27-17-image.png" alt="img">&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-26-57-image.png" alt="img">&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-27-45-image.png" alt="img">&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-28-26-image.png" alt="img">&lt;/p>
&lt;p>创建了三个子模块之后,需要创建一下几个文件夹:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>在 &lt;code>dubbo-spring-boot-demo-consumer/src/main/java&lt;/code> 下创建 &lt;code>org.apache.dubbo.springboot.demo.consumer&lt;/code> package&lt;/p>
&lt;/li>
&lt;li>
&lt;p>在 &lt;code>dubbo-spring-boot-demo-interface/src/main/java&lt;/code> 下创建 &lt;code>org.apache.dubbo.springboot.demo&lt;/code> package&lt;/p>
&lt;/li>
&lt;li>
&lt;p>在 &lt;code>dubbo-spring-boot-demo-provider/src/main/java&lt;/code> 下创建 &lt;code>org.apache.dubbo.springboot.demo.provider&lt;/code> package&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-32-50-image.png" alt="img">&lt;/p>
&lt;p>最终的文件夹参考如上图所示。&lt;/p>
&lt;h3 id="3-添加-maven-依赖">3. 添加 Maven 依赖&lt;/h3>
&lt;p>在初始化完项目以后,我们需要先添加 Dubbo 相关的 maven 依赖。&lt;/p>
&lt;p>对于多模块项目,首先需要在父项目的 &lt;code>pom.xml&lt;/code> 里面配置依赖信息。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-53-18-image.png" alt="img">&lt;/p>
&lt;p>编辑 &lt;code>./pom.xml&lt;/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-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;properties&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;dubbo.version&amp;gt;&lt;/span>3.2.0-beta.4&lt;span style="color:#268bd2">&amp;lt;/dubbo.version&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;spring-boot.version&amp;gt;&lt;/span>2.7.8&lt;span style="color:#268bd2">&amp;lt;/spring-boot.version&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;maven.compiler.source&amp;gt;&lt;/span>17&lt;span style="color:#268bd2">&amp;lt;/maven.compiler.source&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;maven.compiler.target&amp;gt;&lt;/span>17&lt;span style="color:#268bd2">&amp;lt;/maven.compiler.target&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;project.build.sourceEncoding&amp;gt;&lt;/span>UTF-8&lt;span style="color:#268bd2">&amp;lt;/project.build.sourceEncoding&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;/properties&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:#268bd2">&amp;lt;dependencyManagement&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;dependencies&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">&amp;lt;!-- Spring Boot --&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.springframework.boot&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>spring-boot-dependencies&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>${spring-boot.version}&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;type&amp;gt;&lt;/span>pom&lt;span style="color:#268bd2">&amp;lt;/type&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;scope&amp;gt;&lt;/span>import&lt;span style="color:#268bd2">&amp;lt;/scope&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>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">&amp;lt;!-- Dubbo --&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.apache.dubbo&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-bom&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>${dubbo.version}&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;type&amp;gt;&lt;/span>pom&lt;span style="color:#268bd2">&amp;lt;/type&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;scope&amp;gt;&lt;/span>import&lt;span style="color:#268bd2">&amp;lt;/scope&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>&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.apache.dubbo&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-dependencies-zookeeper-curator5&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>${dubbo.version}&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;type&amp;gt;&lt;/span>pom&lt;span style="color:#268bd2">&amp;lt;/type&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;/dependencies&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;/dependencyManagement&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>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;build&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;pluginManagement&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;plugins&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;plugin&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.springframework.boot&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>spring-boot-maven-plugin&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>${spring-boot.version}&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;/plugin&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;/plugins&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;/pluginManagement&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;/build&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>然后在 &lt;code>dubbo-spring-boot-consumer&lt;/code> 和 &lt;code>dubbo-spring-boot-provider&lt;/code> 两个模块 &lt;code>pom.xml&lt;/code> 中进行具体依赖的配置。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-52-53-image.png" alt="img">&lt;/p>
&lt;p>编辑 &lt;code>./dubbo-spring-boot-consumer/pom.xml&lt;/code> 和 &lt;code>./dubbo-spring-boot-provider/pom.xml&lt;/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-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;dependencies&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.apache.dubbo&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-samples-spring-boot-interface&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>${project.parent.version}&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>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">&amp;lt;!-- dubbo --&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.apache.dubbo&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-spring-boot-starter&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;/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.apache.dubbo&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-dependencies-zookeeper-curator5&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;type&amp;gt;&lt;/span>pom&lt;span style="color:#268bd2">&amp;lt;/type&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;exclusions&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;exclusion&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>slf4j-reload4j&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;groupId&amp;gt;&lt;/span>org.slf4j&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;/exclusion&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;/exclusions&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>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">&amp;lt;!-- spring boot starter --&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.springframework.boot&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>spring-boot-starter&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;/dependency&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:#268bd2">&amp;lt;/dependencies&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>在这份配置中,定义了 dubbo 和 zookeeper(以及对应的连接器 curator)的依赖。&lt;/p>
&lt;p>添加了上述的配置以后,可以通过 IDEA 的 &lt;code>Maven - Reload All Maven Projects&lt;/code> 刷新依赖。&lt;/p>
&lt;h3 id="4-定义服务接口">4. 定义服务接口&lt;/h3>
&lt;p>服务接口 Dubbo 中沟通消费端和服务端的桥梁。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-57-29-image.png" alt="img">&lt;/p>
&lt;p>在 &lt;code>dubbo-spring-boot-demo-interface&lt;/code> 模块的 &lt;code>org.apache.dubbo.samples.api&lt;/code> 下建立 &lt;code>DemoService&lt;/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:#719e07">package&lt;/span> org.apache.dubbo.springboot.demo;
&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">DemoService&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:#268bd2">sayHello&lt;/span>(String name);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>在 &lt;code>DemoService&lt;/code> 中,定义了 &lt;code>sayHello&lt;/code> 这个方法。后续服务端发布的服务,消费端订阅的服务都是围绕着 &lt;code>DemoService&lt;/code> 接口展开的。&lt;/p>
&lt;h3 id="5-定义服务端的实现">5. 定义服务端的实现&lt;/h3>
&lt;p>定义了服务接口之后,可以在服务端这一侧定义对应的实现,这部分的实现相对于消费端来说是远端的实现,本地没有相关的信息。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-17-59-46-image.png" alt="img">&lt;/p>
&lt;p>在&lt;code>dubbo-spring-boot-demo-provider&lt;/code> 模块的 &lt;code>org.apache.dubbo.samples.provider&lt;/code> 下建立 &lt;code>DemoServiceImpl&lt;/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:#719e07">package&lt;/span> org.apache.dubbo.springboot.demo.provider;
&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.config.annotation.DubboService;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.springboot.demo.DemoService;
&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">@DubboService&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">DemoServiceImpl&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> DemoService {
&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> String &lt;span style="color:#268bd2">sayHello&lt;/span>(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:#2aa198">&amp;#34;Hello &amp;#34;&lt;/span> &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;/code>&lt;/pre>&lt;/div>&lt;p>在 &lt;code>DemoServiceImpl&lt;/code> 中,实现了 &lt;code>DemoService&lt;/code> 接口,对于 &lt;code>sayHello&lt;/code> 方法返回 &lt;code>Hello name&lt;/code>。&lt;/p>
&lt;p>注:在&lt;code>DemoServiceImpl&lt;/code> 类中添加了 &lt;code>@DubboService&lt;/code> 注解,通过这个配置可以基于 Spring Boot 去发布 Dubbo 服务。&lt;/p>
&lt;h3 id="6-配置服务端-yaml-配置文件">6. 配置服务端 Yaml 配置文件&lt;/h3>
&lt;p>从本步骤开始至第 7 步,将会通过 Spring Boot 的方式配置 Dubbo 的一些基础信息。&lt;/p>
&lt;p>首先,我们先创建服务端的配置文件。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-18-00-24-image.png" alt="img">&lt;/p>
&lt;p>在 &lt;code>dubbo-spring-boot-demo-provider&lt;/code> 模块的 &lt;code>resources&lt;/code> 资源文件夹下建立 &lt;code>application.yml&lt;/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-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">dubbo&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">application&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">name&lt;/span>: dubbo-springboot-demo-provider
&lt;/span>&lt;/span>&lt;span style="display:flex;">&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">name&lt;/span>: dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">port&lt;/span>: -&lt;span style="color:#2aa198">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">registry&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">address&lt;/span>: zookeeper://${zookeeper.address:127.0.0.1}:2181
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>在这个配置文件中,定义了 Dubbo 的应用名、Dubbo 协议信息、Dubbo 使用的注册中心地址。&lt;/p>
&lt;h3 id="7-配置消费端-yaml-配置文件">7. 配置消费端 Yaml 配置文件&lt;/h3>
&lt;p>同样的,我们需要创建消费端的配置文件。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-18-01-03-image.png" alt="img">&lt;/p>
&lt;p>在 &lt;code>dubbo-spring-boot-demo-consumer&lt;/code> 模块的 &lt;code>resources&lt;/code> 资源文件夹下建立 &lt;code>application.yml&lt;/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-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">dubbo&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">application&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">name&lt;/span>: dubbo-springboot-demo-consumer
&lt;/span>&lt;/span>&lt;span style="display:flex;">&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">name&lt;/span>: dubbo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">port&lt;/span>: -&lt;span style="color:#2aa198">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">registry&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">address&lt;/span>: zookeeper://${zookeeper.address:127.0.0.1}:2181
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>在这个配置文件中,定义了 Dubbo 的应用名、Dubbo 协议信息、Dubbo 使用的注册中心地址。&lt;/p>
&lt;h3 id="8-基于-spring-配置服务端启动类">8. 基于 Spring 配置服务端启动类&lt;/h3>
&lt;p>除了配置 Yaml 配置文件之外,我们还需要创建基于 Spring Boot 的启动类。&lt;/p>
&lt;p>首先,我们先创建服务端的启动类。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-18-01-38-image.png" alt="img">&lt;/p>
&lt;p>在 &lt;code>dubbo-spring-boot-demo-provider&lt;/code> 模块的 &lt;code>org.apache.dubbo.springboot.demo.provider&lt;/code> 下建立 &lt;code>Application&lt;/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:#719e07">package&lt;/span> org.apache.dubbo.springboot.demo.provider;
&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.config.spring.context.annotation.EnableDubbo;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.springframework.boot.SpringApplication;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.springframework.boot.autoconfigure.SpringBootApplication;
&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">@SpringBootApplication&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@EnableDubbo&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">ProviderApplication&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">static&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">main&lt;/span>(String&lt;span style="color:#719e07">[]&lt;/span> args) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> SpringApplication.run(ProviderApplication.class, args);
&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>在这个启动类中,配置了一个 &lt;code>ProviderApplication&lt;/code> 去读取我们前面第 6 步中定义的 &lt;code>application.yml&lt;/code> 配置文件并启动应用。&lt;/p>
&lt;h3 id="9-基于-spring-配置消费端启动类">9. 基于 Spring 配置消费端启动类&lt;/h3>
&lt;p>同样的,我们需要创建消费端的启动类。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-18-02-11-image.png" alt="img">&lt;/p>
&lt;p>在 &lt;code>dubbo-spring-boot-demo-consumer&lt;/code> 模块的 &lt;code>org.apache.dubbo.springboot.demo.consumer&lt;/code> 下建立 &lt;code>Application&lt;/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:#719e07">package&lt;/span> org.apache.dubbo.springboot.demo.consumer;
&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.config.spring.context.annotation.EnableDubbo;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.springframework.boot.SpringApplication;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.springframework.boot.autoconfigure.SpringBootApplication;
&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">@SpringBootApplication&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">@EnableDubbo&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">ConsumerApplication&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">static&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">main&lt;/span>(String&lt;span style="color:#719e07">[]&lt;/span> args) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> SpringApplication.run(ConsumerApplication.class, args);
&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>在这个启动类中,配置了一个 &lt;code>ConsumerApplication&lt;/code> 去读取我们前面第 7 步中定义的 &lt;code>application.yml&lt;/code> 配置文件并启动应用。&lt;/p>
&lt;h3 id="10-配置消费端请求任务">10. 配置消费端请求任务&lt;/h3>
&lt;p>除了配置消费端的启动类,我们在 Spring Boot 模式下还可以基于 &lt;code>CommandLineRunner&lt;/code>去创建&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-18-02-33-image.png" alt="img">&lt;/p>
&lt;p>在 &lt;code>dubbo-spring-boot-demo-consumer&lt;/code> 模块的 &lt;code>org.apache.dubbo.springboot.demo.consumer&lt;/code> 下建立 &lt;code>Task&lt;/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:#719e07">package&lt;/span> org.apache.dubbo.springboot.demo.consumer;
&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> 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> org.apache.dubbo.config.annotation.DubboReference;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.springboot.demo.DemoService;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.springframework.boot.CommandLineRunner;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.springframework.stereotype.Component;
&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">@Component&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">Task&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> CommandLineRunner {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">@DubboReference&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">private&lt;/span> DemoService demoService;
&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">void&lt;/span> &lt;span style="color:#268bd2">run&lt;/span>(String... args) &lt;span style="color:#268bd2">throws&lt;/span> Exception {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> String result &lt;span style="color:#719e07">=&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> System.out.println(&lt;span style="color:#2aa198">&amp;#34;Receive result ======&amp;gt; &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&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 style="color:#719e07">new&lt;/span> Thread(()&lt;span style="color:#719e07">-&amp;gt;&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">while&lt;/span> (&lt;span style="color:#cb4b16">true&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> Thread.sleep(1000);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.out.println(&lt;span style="color:#719e07">new&lt;/span> Date() &lt;span style="color:#719e07">+&lt;/span> &lt;span style="color:#2aa198">&amp;#34; Receive result ======&amp;gt; &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&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 style="color:#719e07">catch&lt;/span> (InterruptedException e) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> e.printStackTrace();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Thread.currentThread().interrupt();
&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> }).start();
&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>在 &lt;code>Task&lt;/code> 类中,通过&lt;code>@DubboReference&lt;/code> 从 Dubbo 获取了一个 RPC 订阅,这个 &lt;code>demoService&lt;/code> 可以像本地调用一样直接调用。在 &lt;code>run&lt;/code>方法中创建了一个线程进行调用。&lt;/p>
&lt;h3 id="11-启动应用">11. 启动应用&lt;/h3>
&lt;p>截止第 10 步,代码就已经开发完成了,本小节将启动整个项目并进行验证。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-18-03-59-image.png" alt="img">&lt;/p>
&lt;p>首先是启动 &lt;code>org.apache.dubbo.samples.provider.Application&lt;/code> ,等待一会出现如下图所示的日志(&lt;code>Current Spring Boot Application is await&lt;/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-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>[Dubbo] Current Spring Boot Application is await...
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>然后是启动&lt;code>org.apache.dubbo.samples.client.Application&lt;/code> ,等待一会出现如下图所示的日志(&lt;code>Hello world&lt;/code> )即代表服务消费端启动完毕并调用到服务端成功获取结果。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-18-05-02-image.png" alt="img">&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>Receive result ======&amp;gt; Hello world
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="延伸阅读">延伸阅读&lt;/h2>
&lt;h3 id="1-dubbo-的-spring-配置介绍">1. Dubbo 的 Spring 配置介绍&lt;/h3>
&lt;p>Dubbo 的主要配置入口有 yaml 的配置内容、&lt;code>@DubboReference&lt;/code> 和&lt;code>@DubboService&lt;/code> 等,更多的细节可以参考 &lt;a href="https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/config/annotation/">Annotation 配置 | Apache Dubbo&lt;/a> 一文。&lt;/p>
&lt;h2 id="更多">更多&lt;/h2>
&lt;p>本教程介绍了如何基于 Dubbo x Spring Boot 开发一个微服务应用。在下一节中,将介绍&lt;a href="../spring-xml/">另外一种 Dubbo 的配置方式 —— Dubbo x Spring XML&lt;/a>。&lt;/p></description></item><item><title>Overview: 4 - 基于 Spring XML 开发微服务应用</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/quick-start/spring-xml/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/quick-start/spring-xml/</guid><description>
&lt;h2 id="目标">目标&lt;/h2>
&lt;p>从零上手开发基于 Dubbo x Spring XML 的微服务开发,了解 Dubbo x Spring XML 配置方式。&lt;/p>
&lt;h2 id="难度">难度&lt;/h2>
&lt;p>低&lt;/p>
&lt;h2 id="环境要求">环境要求&lt;/h2>
&lt;ul>
&lt;li>
&lt;p>系统:Windows、Linux、MacOS&lt;/p>
&lt;/li>
&lt;li>
&lt;p>JDK 8 及以上(推荐使用 JDK17)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Git&lt;/p>
&lt;/li>
&lt;li>
&lt;p>IntelliJ IDEA(可选)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Docker (可选)&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="快速部署基于-samples-直接启动">快速部署(基于 Samples 直接启动)&lt;/h2>
&lt;p>本章将通过几个简单的命令,一步一步教你如何部署并运行一个基于 Dubbo x Spring XML 的用例。&lt;/p>
&lt;p>注:本章部署的代码细节可以在 &lt;a href="https://github.com/apache/dubbo-samples">apache/dubbo-samples&lt;/a> 这个仓库中 &lt;code>1-basic/dubbo-samples-spring-xml&lt;/code> 中找到,在下一章中也将展开进行讲解。&lt;/p>
&lt;h3 id="1-获取测试工程">1. 获取测试工程&lt;/h3>
&lt;p>在开始整个教程之前,我们需要先获取测试工程的代码。Dubbo 的所有测试用例代码都存储在 &lt;a href="https://github.com/apache/dubbo-samples">apache/dubbo-samples&lt;/a> 这个仓库中,以下这个命令可以帮你获取 Samples 仓库的所有代码。&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-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>git clone --depth&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">1&lt;/span> --branch master git@github.com:apache/dubbo-samples.git
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="2-启动一个简易的注册中心">2. 启动一个简易的注册中心&lt;/h3>
&lt;p>对于一个微服务化的应用来说,注册中心是不可或缺的一个组件。只有通过注册中心,消费端才可以成功发现服务端的地址信息,进而进行调用。&lt;/p>
&lt;p>为了让本教程更易于上手,我们提供了一个基于 Apache Zookeeper 注册中心的简易启动器,如果您需要在生产环境部署注册中心,请参考&lt;a href="https://dubbo.apache.org/">生产环境初始化&lt;/a>一文部署高可用的注册中心。&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-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>Windows:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Linux / MacOS:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw clean compile exec:java -pl tools/embedded-zookeeper
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Docker:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker run --name some-zookeeper -p 2181:2181 --restart always -d zookeeper
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="3-启动服务提供者">3. 启动服务提供者&lt;/h3>
&lt;p>在启动了注册中心之后,下一步是启动一个对外提供服务的服务提供者。在 dubbo-samples 中也提供了对应的示例,可以通过以下命令快速拉起。&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-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>Windows:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-spring-xml -Dexec.mainClass&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.samples.provider.Application&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>Linux / MacOS:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-spring-xml -Dexec.mainClass&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.samples.provider.Application&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>注:需要开一个独立的 terminal 运行,命令将会保持一直执行的状态。
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>在执行完上述命令以后,等待一会出现如下所示的日志(&lt;code>Dubbo Application[1.1](demo-provider) is ready.&lt;/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-gdscript3" data-lang="gdscript3">&lt;span style="display:flex;">&lt;span>[&lt;span style="color:#2aa198">08&lt;/span>&lt;span style="color:#719e07">/&lt;/span>&lt;span style="color:#2aa198">02&lt;/span>&lt;span style="color:#719e07">/&lt;/span>&lt;span style="color:#2aa198">23&lt;/span> &lt;span style="color:#2aa198">03&lt;/span>:&lt;span style="color:#2aa198">26&lt;/span>:&lt;span style="color:#2aa198">52&lt;/span>:&lt;span style="color:#2aa198">052&lt;/span> CST] org&lt;span style="color:#719e07">.&lt;/span>apache&lt;span style="color:#719e07">.&lt;/span>dubbo&lt;span style="color:#719e07">.&lt;/span>samples&lt;span style="color:#719e07">.&lt;/span>provider&lt;span style="color:#719e07">.&lt;/span>Application&lt;span style="color:#719e07">.&lt;/span>main() INFO metadata&lt;span style="color:#719e07">.&lt;/span>ConfigurableMetadataServiceExporter: [DUBBO] The MetadataService exports urls : [dubbo:&lt;span style="color:#719e07">//&lt;/span>&lt;span style="color:#2aa198">30.221&lt;/span>&lt;span style="color:#719e07">.&lt;/span>&lt;span style="color:#2aa198">128.96&lt;/span>:&lt;span style="color:#2aa198">20880&lt;/span>&lt;span style="color:#719e07">/&lt;/span>org&lt;span style="color:#719e07">.&lt;/span>apache&lt;span style="color:#719e07">.&lt;/span>dubbo&lt;span style="color:#719e07">.&lt;/span>metadata&lt;span style="color:#719e07">.&lt;/span>MetadataService?anyhost&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#268bd2">true&lt;/span>&lt;span style="color:#719e07">&amp;amp;&lt;/span>application&lt;span style="color:#719e07">=&lt;/span>demo&lt;span style="color:#719e07">-&lt;/span>provider&lt;span style="color:#719e07">&amp;amp;&lt;/span>background&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#268bd2">false&lt;/span>&lt;span style="color:#719e07">&amp;amp;&lt;/span>bind&lt;span style="color:#719e07">.&lt;/span>ip&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">30.221&lt;/span>&lt;span style="color:#719e07">.&lt;/span>&lt;span style="color:#2aa198">128.96&lt;/span>&lt;span style="color:#719e07">&amp;amp;&lt;/span>bind&lt;span style="color:#719e07">.&lt;/span>port&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">20880&lt;/span>&lt;span style="color:#719e07">&amp;amp;&lt;/span>connections&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">1&lt;/span>&lt;span style="color:#719e07">&amp;amp;&lt;/span>corethreads&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">2&lt;/span>&lt;span style="color:#719e07">&amp;amp;&lt;/span>delay&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">0&lt;/span>&lt;span style="color:#719e07">&amp;amp;&lt;/span>deprecated&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#268bd2">false&lt;/span>&lt;span style="color:#719e07">&amp;amp;&lt;/span>dubbo&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">2.0&lt;/span>&lt;span style="color:#719e07">.&lt;/span>&lt;span style="color:#2aa198">2&lt;/span>&lt;span style="color:#719e07">&amp;amp;&lt;/span>dynamic&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#268bd2">true&lt;/span>&lt;span style="color:#719e07">&amp;amp;&lt;/span>executes&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">100&lt;/span>&lt;span style="color:#719e07">&amp;amp;&lt;/span>generic&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#268bd2">false&lt;/span>&lt;span style="color:#719e07">&amp;amp;&lt;/span>getAndListenInstanceMetadata&lt;span style="color:#719e07">.&lt;/span>&lt;span style="color:#2aa198">1.&lt;/span>callback&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#268bd2">true&lt;/span>&lt;span style="color:#719e07">&amp;amp;&lt;/span>getAndListenInstanceMetadata&lt;span style="color:#719e07">.&lt;/span>&lt;span style="color:#719e07">return&lt;/span>&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#268bd2">true&lt;/span>&lt;span style="color:#719e07">&amp;amp;&lt;/span>getAndListenInstanceMetadata&lt;span style="color:#719e07">.&lt;/span>sent&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#268bd2">true&lt;/span>&lt;span style="color:#719e07">&amp;amp;&lt;/span>group&lt;span style="color:#719e07">=&lt;/span>demo&lt;span style="color:#719e07">-&lt;/span>provider&lt;span style="color:#719e07">&amp;amp;&lt;/span>interface&lt;span style="color:#719e07">=&lt;/span>org&lt;span style="color:#719e07">.&lt;/span>apache&lt;span style="color:#719e07">.&lt;/span>dubbo&lt;span style="color:#719e07">.&lt;/span>metadata&lt;span style="color:#719e07">.&lt;/span>MetadataService&lt;span style="color:#719e07">&amp;amp;&lt;/span>ipv6&lt;span style="color:#719e07">=&lt;/span>fd00:&lt;span style="color:#2aa198">1&lt;/span>:&lt;span style="color:#2aa198">5&lt;/span>:&lt;span style="color:#2aa198">5200&lt;/span>:&lt;span style="color:#2aa198">4&lt;/span>d53:&lt;span style="color:#2aa198">9&lt;/span>f5:a545:&lt;span style="color:#2aa198">804&lt;/span>d&lt;span style="color:#719e07">&amp;amp;&lt;/span>methods&lt;span style="color:#719e07">=&lt;/span>exportInstanceMetadata,getAndListenInstanceMetadata,getExportedServiceURLs,getExportedURLs,getExportedURLs,getExportedURLs,getExportedURLs,getExportedURLs,getInstanceMetadataChangedListenerMap,getMetadataInfo,getMetadataInfos,getMetadataURL,getServiceDefinition,getServiceDefinition,getSubscribedURLs,isMetadataService,serviceName,toSortedStrings,toSortedStrings,version&lt;span style="color:#719e07">&amp;amp;&lt;/span>pid&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">70803&lt;/span>&lt;span style="color:#719e07">&amp;amp;&lt;/span>register&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#268bd2">false&lt;/span>&lt;span style="color:#719e07">&amp;amp;&lt;/span>release&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">3.1&lt;/span>&lt;span style="color:#719e07">.&lt;/span>&lt;span style="color:#2aa198">6&lt;/span>&lt;span style="color:#719e07">&amp;amp;&lt;/span>revision&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">3.1&lt;/span>&lt;span style="color:#719e07">.&lt;/span>&lt;span style="color:#2aa198">6&lt;/span>&lt;span style="color:#719e07">&amp;amp;&lt;/span>side&lt;span style="color:#719e07">=&lt;/span>provider&lt;span style="color:#719e07">&amp;amp;&lt;/span>threadpool&lt;span style="color:#719e07">=&lt;/span>cached&lt;span style="color:#719e07">&amp;amp;&lt;/span>threads&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">100&lt;/span>&lt;span style="color:#719e07">&amp;amp;&lt;/span>timestamp&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">1675841212727&lt;/span>&lt;span style="color:#719e07">&amp;amp;&lt;/span>version&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">1.0&lt;/span>&lt;span style="color:#719e07">.&lt;/span>&lt;span style="color:#2aa198">0&lt;/span>], dubbo version: &lt;span style="color:#2aa198">3.1&lt;/span>&lt;span style="color:#719e07">.&lt;/span>&lt;span style="color:#2aa198">6&lt;/span>, current host: &lt;span style="color:#2aa198">30.221&lt;/span>&lt;span style="color:#719e07">.&lt;/span>&lt;span style="color:#2aa198">128.96&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[&lt;span style="color:#2aa198">08&lt;/span>&lt;span style="color:#719e07">/&lt;/span>&lt;span style="color:#2aa198">02&lt;/span>&lt;span style="color:#719e07">/&lt;/span>&lt;span style="color:#2aa198">23&lt;/span> &lt;span style="color:#2aa198">03&lt;/span>:&lt;span style="color:#2aa198">26&lt;/span>:&lt;span style="color:#2aa198">52&lt;/span>:&lt;span style="color:#2aa198">052&lt;/span> CST] org&lt;span style="color:#719e07">.&lt;/span>apache&lt;span style="color:#719e07">.&lt;/span>dubbo&lt;span style="color:#719e07">.&lt;/span>samples&lt;span style="color:#719e07">.&lt;/span>provider&lt;span style="color:#719e07">.&lt;/span>Application&lt;span style="color:#719e07">.&lt;/span>main() INFO metadata&lt;span style="color:#719e07">.&lt;/span>ServiceInstanceMetadataUtils: [DUBBO] Start registering instance address to registry&lt;span style="color:#719e07">.&lt;/span>, dubbo version: &lt;span style="color:#2aa198">3.1&lt;/span>&lt;span style="color:#719e07">.&lt;/span>&lt;span style="color:#2aa198">6&lt;/span>, current host: &lt;span style="color:#2aa198">30.221&lt;/span>&lt;span style="color:#719e07">.&lt;/span>&lt;span style="color:#2aa198">128.96&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[&lt;span style="color:#2aa198">08&lt;/span>&lt;span style="color:#719e07">/&lt;/span>&lt;span style="color:#2aa198">02&lt;/span>&lt;span style="color:#719e07">/&lt;/span>&lt;span style="color:#2aa198">23&lt;/span> &lt;span style="color:#2aa198">03&lt;/span>:&lt;span style="color:#2aa198">26&lt;/span>:&lt;span style="color:#2aa198">52&lt;/span>:&lt;span style="color:#2aa198">052&lt;/span> CST] org&lt;span style="color:#719e07">.&lt;/span>apache&lt;span style="color:#719e07">.&lt;/span>dubbo&lt;span style="color:#719e07">.&lt;/span>samples&lt;span style="color:#719e07">.&lt;/span>provider&lt;span style="color:#719e07">.&lt;/span>Application&lt;span style="color:#719e07">.&lt;/span>main() INFO metadata&lt;span style="color:#719e07">.&lt;/span>MetadataInfo: [DUBBO] metadata revision changed: null &lt;span style="color:#719e07">-&amp;gt;&lt;/span> &lt;span style="color:#2aa198">602&lt;/span>d44cc6d653b9cd42ab23c3948b5ab, app: demo&lt;span style="color:#719e07">-&lt;/span>provider, services: &lt;span style="color:#2aa198">1&lt;/span>, dubbo version: &lt;span style="color:#2aa198">3.1&lt;/span>&lt;span style="color:#719e07">.&lt;/span>&lt;span style="color:#2aa198">6&lt;/span>, current host: &lt;span style="color:#2aa198">30.221&lt;/span>&lt;span style="color:#719e07">.&lt;/span>&lt;span style="color:#2aa198">128.96&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[&lt;span style="color:#2aa198">08&lt;/span>&lt;span style="color:#719e07">/&lt;/span>&lt;span style="color:#2aa198">02&lt;/span>&lt;span style="color:#719e07">/&lt;/span>&lt;span style="color:#2aa198">23&lt;/span> &lt;span style="color:#2aa198">03&lt;/span>:&lt;span style="color:#2aa198">26&lt;/span>:&lt;span style="color:#2aa198">52&lt;/span>:&lt;span style="color:#2aa198">052&lt;/span> CST] org&lt;span style="color:#719e07">.&lt;/span>apache&lt;span style="color:#719e07">.&lt;/span>dubbo&lt;span style="color:#719e07">.&lt;/span>samples&lt;span style="color:#719e07">.&lt;/span>provider&lt;span style="color:#719e07">.&lt;/span>Application&lt;span style="color:#719e07">.&lt;/span>main() INFO deploy&lt;span style="color:#719e07">.&lt;/span>DefaultApplicationDeployer: [DUBBO] Dubbo Application[&lt;span style="color:#2aa198">1.1&lt;/span>](demo&lt;span style="color:#719e07">-&lt;/span>provider) is ready&lt;span style="color:#719e07">.&lt;/span>, dubbo version: &lt;span style="color:#2aa198">3.1&lt;/span>&lt;span style="color:#719e07">.&lt;/span>&lt;span style="color:#2aa198">6&lt;/span>, current host: &lt;span style="color:#2aa198">30.221&lt;/span>&lt;span style="color:#719e07">.&lt;/span>&lt;span style="color:#2aa198">128.96&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="4-启动服务消费者">4. 启动服务消费者&lt;/h3>
&lt;p>最后一步是启动一个服务消费者来调用服务提供者,也即是 RPC 调用的核心,为服务消费者提供调用服务提供者的桥梁。&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-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>Windows:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-spring-xml -Dexec.mainClass&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.samples.client.Application&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>Linux / MacOS:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-spring-xml -Dexec.mainClass&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.samples.client.Application&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>在执行完上述命令以后,等待一会出现如下所示的日志(&lt;code>hi, dubbo&lt;/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-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>[08/02/23 03:28:23:023 CST] org.apache.dubbo.samples.client.Application.main() INFO deploy.DefaultApplicationDeployer: [DUBBO] Dubbo Application[1.1](demo-consumer) is ready., dubbo version: 3.1.6, current host: 30.221.128.96
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Receive result ======&amp;gt; hi, dubbo
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="动手实践从零代码开发版">动手实践(从零代码开发版)&lt;/h2>
&lt;p>本章将通过手把手的教程一步一步教你如何从零开发一个微服务应用。&lt;/p>
&lt;h3 id="1-启动注册中心">1. 启动注册中心&lt;/h3>
&lt;p>对于一个微服务化的应用来说,注册中心是不可或缺的一个组件。只有通过注册中心,消费端才可以成功发现服务端的地址信息,进而进行调用。&lt;/p>
&lt;p>为了让本教程更易于上手,我们提供了一个基于 Apache Zookeeper 注册中心的简易启动器,如果您需要在生产环境部署注册中心,请参考&lt;a href="https://dubbo.apache.org/">生产环境初始化&lt;/a>一文部署高可用的注册中心。&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-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>Windows:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>git clone --depth&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">1&lt;/span> --branch master git@github.com:apache/dubbo-samples.git
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#b58900">cd&lt;/span> dubbo-samples
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Linux / MacOS:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>git clone --depth&lt;span style="color:#719e07">=&lt;/span>&lt;span style="color:#2aa198">1&lt;/span> --branch master git@github.com:apache/dubbo-samples.git
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#b58900">cd&lt;/span> dubbo-samples
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./mvnw clean compile exec:java -pl tools/embedded-zookeeper
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Docker:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker run --name some-zookeeper -p 2181:2181 --restart always -d zookeeper
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="2-初始化项目">2. 初始化项目&lt;/h3>
&lt;p>从本小节开始,将基于 IntelliJ IDEA 进行工程的搭建以及测试。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-15-32-16-image.png" alt="img">&lt;/p>
&lt;p>如上图所示,可以建立一个基础的项目。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-15-33-20-image.png" alt="img">&lt;/p>
&lt;p>在初始化完项目之后,需要在 &lt;code>src/main/java&lt;/code> 目录下创建 &lt;code>org.apache.dubbo.samples.api&lt;/code> 、&lt;code>org.apache.dubbo.samples.client&lt;/code> 和 &lt;code>org.apache.dubbo.samples.provider&lt;/code> 三个 package。&lt;/p>
&lt;p>后续我们将在 &lt;code>api&lt;/code> 下创建对应的接口,在 &lt;code>client&lt;/code> 下创建对应客户端订阅服务的功能,在 &lt;code>provider&lt;/code> 下创建对应服务端的实现以及发布服务的功能。&lt;/p>
&lt;p>上述三个 package 分别对应了应用共同依赖的 api、消费端应用的模块、服务端应用的模块。在实际部署中需要拆成三个工程,消费端和服务的共同依赖 api 模块。从简单出发,本教程将在同一个工程中进行开发,区分多个启动类。&lt;/p>
&lt;h3 id="3-添加-maven-依赖">3. 添加 Maven 依赖&lt;/h3>
&lt;p>在初始化完项目以后,我们需要先添加 Dubbo 相关的 maven 依赖。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-15-36-57-image.png" alt="img">&lt;/p>
&lt;p>编辑 &lt;code>pom.xml&lt;/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-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;dependencies&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.apache.dubbo&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&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.1.6&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>&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.springframework&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>spring-context&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>5.3.25&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>&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.apache.curator&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>curator-x-discovery&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>5.2.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;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.zookeeper&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>zookeeper&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.8.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;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;/dependencies&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>在这份配置中,定义了 dubbo 和 zookeeper(以及对应的连接器 curator)的依赖。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-15-36-31-image.png" alt="img">&lt;/p>
&lt;p>添加了上述的配置以后,可以通过 IDEA 的 &lt;code>Maven - Reload All Maven Projects&lt;/code> 刷新依赖。&lt;/p>
&lt;h3 id="4-定义服务接口">4. 定义服务接口&lt;/h3>
&lt;p>服务接口 Dubbo 中沟通消费端和服务端的桥梁。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-15-37-31-image.png" alt="img">&lt;/p>
&lt;p>在 &lt;code>org.apache.dubbo.samples.api&lt;/code> 下建立 &lt;code>GreetingsService&lt;/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:#719e07">package&lt;/span> org.apache.dubbo.samples.api;
&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">GreetingsService&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:#268bd2">sayHi&lt;/span>(String name);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>在 &lt;code>GreetingsService&lt;/code> 中,定义了 &lt;code>sayHi&lt;/code> 这个方法。后续服务端发布的服务,消费端订阅的服务都是围绕着 &lt;code>GreetingsService&lt;/code> 接口展开的。&lt;/p>
&lt;h3 id="5-定义服务端的实现">5. 定义服务端的实现&lt;/h3>
&lt;p>定义了服务接口之后,可以在服务端这一侧定义对应的实现,这部分的实现相对于消费端来说是远端的实现,本地没有相关的信息。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-15-38-04-image.png" alt="img">&lt;/p>
&lt;p>在 &lt;code>org.apache.dubbo.samples.provider&lt;/code> 下建立 &lt;code>GreetingsServiceImpl&lt;/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:#719e07">package&lt;/span> org.apache.dubbo.samples.provider;
&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.samples.api.GreetingsService;
&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">GreetingsServiceImpl&lt;/span> &lt;span style="color:#268bd2">implements&lt;/span> GreetingsService {
&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> String &lt;span style="color:#268bd2">sayHi&lt;/span>(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:#2aa198">&amp;#34;hi, &amp;#34;&lt;/span> &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;/code>&lt;/pre>&lt;/div>&lt;p>在 &lt;code>GreetingsServiceImpl&lt;/code> 中,实现了 &lt;code>GreetingsService&lt;/code> 接口,对于 &lt;code>sayHi&lt;/code> 方法返回 &lt;code>hi, name&lt;/code>。&lt;/p>
&lt;h3 id="6-配置服务端-xml-配置文件">6. 配置服务端 XML 配置文件&lt;/h3>
&lt;p>从本步骤开始至第 7 步,将会通过 Spring XML 的方式配置 Dubbo 服务的信息。&lt;/p>
&lt;p>首先,我们先创建服务端的配置文件。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-15-40-07-image.png" alt="img">&lt;/p>
&lt;p>在 &lt;code>resources&lt;/code> 资源文件夹下建立 &lt;code>dubbo-demo-provider.xml&lt;/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-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;beans&lt;/span> xmlns:xsi=&lt;span style="color:#2aa198">&amp;#34;http://www.w3.org/2001/XMLSchema-instance&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> xmlns:dubbo=&lt;span style="color:#2aa198">&amp;#34;http://dubbo.apache.org/schema/dubbo&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> xmlns=&lt;span style="color:#2aa198">&amp;#34;http://www.springframework.org/schema/beans&amp;#34;&lt;/span> xmlns:context=&lt;span style="color:#2aa198">&amp;#34;http://www.springframework.org/schema/context&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> xsi:schemaLocation=&lt;span style="color:#2aa198">&amp;#34;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#2aa198"> http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd&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:#268bd2">&amp;lt;context:property-placeholder/&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">&amp;lt;!-- 定义应用名 --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;dubbo:application&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;demo-provider&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>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">&amp;lt;!-- 定义注册中心地址 --&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> address=&lt;span style="color:#2aa198">&amp;#34;zookeeper://127.0.0.1:2181&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>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">&amp;lt;!-- 定义实现类对应的 bean --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;bean&lt;/span> id=&lt;span style="color:#2aa198">&amp;#34;greetingsService&amp;#34;&lt;/span> class=&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.samples.provider.GreetingsServiceImpl&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;!-- 定义服务信息,引用上面的 bean --&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> interface=&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.samples.api.GreetingsService&amp;#34;&lt;/span> ref=&lt;span style="color:#2aa198">&amp;#34;greetingsService&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>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;/beans&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>在这个配置文件中,定义了 Dubbo 的应用名、Dubbo 使用的注册中心地址、发布服务的 spring bean 以及通过 Dubbo 去发布这个 bean。&lt;/p>
&lt;h3 id="7-配置消费端-xml-配置文件">7. 配置消费端 XML 配置文件&lt;/h3>
&lt;p>同样的,我们需要创建消费端的配置文件。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-15-40-59-image.png" alt="img">&lt;/p>
&lt;p>在 &lt;code>resources&lt;/code> 资源文件夹下建立 &lt;code>dubbo-demo-consumer.xml&lt;/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-xml" data-lang="xml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&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:#268bd2">&amp;lt;beans&lt;/span> xmlns:xsi=&lt;span style="color:#2aa198">&amp;#34;http://www.w3.org/2001/XMLSchema-instance&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> xmlns:dubbo=&lt;span style="color:#2aa198">&amp;#34;http://dubbo.apache.org/schema/dubbo&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> xmlns=&lt;span style="color:#2aa198">&amp;#34;http://www.springframework.org/schema/beans&amp;#34;&lt;/span> xmlns:context=&lt;span style="color:#2aa198">&amp;#34;http://www.springframework.org/schema/context&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> xsi:schemaLocation=&lt;span style="color:#2aa198">&amp;#34;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#2aa198"> http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd&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:#268bd2">&amp;lt;context:property-placeholder/&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">&amp;lt;!-- 定义应用名 --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;dubbo:application&lt;/span> name=&lt;span style="color:#2aa198">&amp;#34;demo-provider&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>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">&amp;lt;!-- 定义注册中心地址 --&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> address=&lt;span style="color:#2aa198">&amp;#34;zookeeper://127.0.0.1:2181&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>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#586e75">&amp;lt;!-- 定义订阅信息,Dubbo 会在 Spring Context 中创建对应的 bean --&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> id=&lt;span style="color:#2aa198">&amp;#34;greetingsService&amp;#34;&lt;/span> interface=&lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.samples.api.GreetingsService&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>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;/beans&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>在这个配置文件中,定义了 Dubbo 的应用名、Dubbo 使用的注册中心地址、订阅的服务信息。&lt;/p>
&lt;h3 id="8-基于-spring-配置服务端启动类">8. 基于 Spring 配置服务端启动类&lt;/h3>
&lt;p>除了配置 XML 配置文件之外,我们还需要创建基于 Spring Context 的启动类。&lt;/p>
&lt;p>首先,我们先创建服务端的启动类。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-15-46-49-image.png" alt="img">&lt;/p>
&lt;p>在 &lt;code>org.apache.dubbo.samples.provider&lt;/code> 下建立 &lt;code>Application&lt;/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:#719e07">package&lt;/span> org.apache.dubbo.samples.provider;
&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> java.util.concurrent.CountDownLatch;
&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.springframework.context.support.ClassPathXmlApplicationContext;
&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">Application&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">static&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">main&lt;/span>(String&lt;span style="color:#719e07">[]&lt;/span> args) &lt;span style="color:#268bd2">throws&lt;/span> InterruptedException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ClassPathXmlApplicationContext context &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#719e07">new&lt;/span> ClassPathXmlApplicationContext(&lt;span style="color:#2aa198">&amp;#34;dubbo-demo-provider.xml&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> context.start();
&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:#719e07">new&lt;/span> CountDownLatch(1).await();
&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>在这个启动类中,配置了一个 &lt;code>ClassPathXmlApplicationContext&lt;/code> 去读取我们前面第 6 步中定义的 &lt;code>dubbo-demo-provider.xml&lt;/code> 配置文件。&lt;/p>
&lt;h3 id="9-基于-spring-配置消费端启动类">9. 基于 Spring 配置消费端启动类&lt;/h3>
&lt;p>同样的,我们需要创建消费端的启动类。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-15-48-26-image.png" alt="img">&lt;/p>
&lt;p>在 &lt;code>org.apache.dubbo.samples.client&lt;/code> 下建立 &lt;code>Application&lt;/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:#719e07">package&lt;/span> org.apache.dubbo.samples.client;
&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> java.io.IOException;
&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.samples.api.GreetingsService;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.springframework.context.support.ClassPathXmlApplicationContext;
&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">Application&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">static&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">main&lt;/span>(String&lt;span style="color:#719e07">[]&lt;/span> args) &lt;span style="color:#268bd2">throws&lt;/span> IOException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ClassPathXmlApplicationContext context &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#719e07">new&lt;/span> ClassPathXmlApplicationContext(&lt;span style="color:#2aa198">&amp;#34;dubbo-demo-consumer.xml&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> context.start();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> GreetingsService greetingsService &lt;span style="color:#719e07">=&lt;/span> (GreetingsService) context.getBean(&lt;span style="color:#2aa198">&amp;#34;greetingsService&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> String message &lt;span style="color:#719e07">=&lt;/span> greetingsService.sayHi(&lt;span style="color:#2aa198">&amp;#34;dubbo&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.out.println(&lt;span style="color:#2aa198">&amp;#34;Receive result ======&amp;gt; &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> message);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.in.read();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.exit(0);
&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>在这个启动类中,主要执行了三个功能:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>配置了一个 &lt;code>ClassPathXmlApplicationContext&lt;/code> 去读取我们前面第 7 步中定义的 &lt;code>dubbo-demo-consumer.xml&lt;/code> 配置文件&lt;/p>
&lt;/li>
&lt;li>
&lt;p>从 Spring Context 中获取名字为 &lt;code>greetingsService&lt;/code> 的由 Dubbo 创建的 bean&lt;/p>
&lt;/li>
&lt;li>
&lt;p>通过这个 bean 对远端发起调用&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h3 id="10-启动应用">10. 启动应用&lt;/h3>
&lt;p>截止第 9 步,代码就已经开发完成了,本小节将启动整个项目并进行验证。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-16-01-29-image.png" alt="img">&lt;/p>
&lt;p>首先是启动 &lt;code>org.apache.dubbo.samples.provider.Application&lt;/code> ,等待一会出现如下图所示的日志(&lt;code>Dubbo Application[1.1](demo-provider) is ready&lt;/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-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>[DUBBO] Dubbo Application[1.1](demo-provider) is ready., dubbo version: 3.1.6, current host: 30.221.128.96
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>然后是启动&lt;code>org.apache.dubbo.samples.client.Application&lt;/code> ,等待一会出现如下图所示的日志(&lt;code>hi, dubbo&lt;/code> )即代表服务消费端启动完毕并调用到服务端成功获取结果。&lt;/p>
&lt;p>&lt;img src="https://dubbo.apache.org/imgs/docs3-v2/java-sdk/quickstart/2023-02-08-16-02-50-image.png" alt="img">&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>Receive result ======&amp;gt; hi, dubbo
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="延伸阅读">延伸阅读&lt;/h2>
&lt;h3 id="1-dubbo-的-xml-配置介绍">1. Dubbo 的 XML 配置介绍&lt;/h3>
&lt;p>Dubbo 的主要配置入口有&lt;code>dubbo:application&lt;/code> 、&lt;code>dubbo:registry&lt;/code> 、 &lt;code>dubbo:reference&lt;/code> 和 &lt;code>dubbo:service&lt;/code> 等,更多的细节可以参考 &lt;a href="https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/config/xml/">XML 配置 | Apache Dubbo&lt;/a> 一文。&lt;/p>
&lt;h2 id="更多">更多&lt;/h2>
&lt;p>本教程介绍了如何基于 Dubbo x Spring XML 开发一个微服务应用。至此,Dubbo 基于 API、Spring Boot、Spring XML 三种主要的启动方式都已经介绍完毕。&lt;/p>
&lt;p>在下一节中,将介绍&lt;a href="../idl/">基于 Protobuf IDL 配置的微服务开发方式&lt;/a>。&lt;/p></description></item><item><title>Overview: 5 - IDL 定义跨语言服务</title><link>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/quick-start/idl/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dubbo.apache.org/zh-cn/overview/mannual/java-sdk/quick-start/idl/</guid><description>
&lt;p>使用 IDL 定义服务具有更好的跨语言友好性,对于 Dubbo3 新用户而言,我们推荐使用这种方式。
然而 Triple 协议并不是和 IDL 强绑定的,也可以使用 Java Interface + Pojo 的方式定义服务并启用 Triple 协议,具体可参见&lt;a href="https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple/src/main/java/org/apache/dubbo/sample/tri/pojo">示例&lt;/a>。&lt;/p>
&lt;p>更多 Triple 和 IDL 使用方式,请参考&lt;a href="https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-triple">官方示例&lt;/a>&lt;/p>
&lt;h3 id="前置条件">前置条件&lt;/h3>
&lt;ul>
&lt;li>&lt;a href="https://jdk.java.net/">JDK&lt;/a> 版本 &amp;gt;= 8&lt;/li>
&lt;li>已安装 &lt;a href="https://maven.apache.org/">Maven&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="创建工程">创建工程&lt;/h3>
&lt;ol>
&lt;li>
&lt;p>首先创建一个空的 maven 工程&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>$ mvn archetype:generate \
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> -DgroupId=org.apache.dubbo \
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> -DartifactId=tri-stub-demo \
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> -DarchetypeArtifactId=maven-archetype-quickstart \
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> -DarchetypeVersion=1.4 \
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> -DarchetypeGroupId=org.apache.maven.archetypes \
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> -Dversion=1.0-SNAPSHOT
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>切换到工程目录&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>$ cd tri-stub-demo
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>在 &lt;code>pom.xml&lt;/code> 中设置 JDK 版本,添加 Dubbo 依赖和插件&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;properties&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;project.build.sourceEncoding&amp;gt;&lt;/span>UTF-8&lt;span style="color:#268bd2">&amp;lt;/project.build.sourceEncoding&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;maven.compiler.source&amp;gt;&lt;/span>1.8&lt;span style="color:#268bd2">&amp;lt;/maven.compiler.source&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;maven.compiler.target&amp;gt;&lt;/span>1.8&lt;span style="color:#268bd2">&amp;lt;/maven.compiler.target&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;dubbo.version&amp;gt;&lt;/span>3.1.7&lt;span style="color:#268bd2">&amp;lt;/dubbo.version&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;/properties&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:#268bd2">&amp;lt;dependencies&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>junit&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>junit&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.13&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;scope&amp;gt;&lt;/span>test&lt;span style="color:#268bd2">&amp;lt;/scope&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.apache.dubbo&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&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>${dubbo.version}&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.apache.dubbo&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-dependencies-zookeeper-curator5&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;type&amp;gt;&lt;/span>pom&lt;span style="color:#268bd2">&amp;lt;/type&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>${dubbo.version}&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>com.google.protobuf&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>protobuf-java&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.19.4&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;/dependencies&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:#268bd2">&amp;lt;build&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;extensions&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;extension&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>kr.motd.maven&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>os-maven-plugin&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.6.1&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;/extension&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;/extensions&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;plugins&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;plugin&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.xolstice.maven.plugins&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>protobuf-maven-plugin&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>0.6.1&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;configuration&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;protocArtifact&amp;gt;&lt;/span>com.google.protobuf:protoc:3.19.4:exe:${os.detected.classifier}&lt;span style="color:#268bd2">&amp;lt;/protocArtifact&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;protocPlugins&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;protocPlugin&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;id&amp;gt;&lt;/span>dubbo&lt;span style="color:#268bd2">&amp;lt;/id&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&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-compiler&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>${dubbo.version}&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;mainClass&amp;gt;&lt;/span>org.apache.dubbo.gen.tri.Dubbo3TripleGenerator&lt;span style="color:#268bd2">&amp;lt;/mainClass&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;/protocPlugin&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;/protocPlugins&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;/configuration&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;executions&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;execution&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;goals&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;goal&amp;gt;&lt;/span>compile&lt;span style="color:#268bd2">&amp;lt;/goal&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;/goals&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;/execution&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;/executions&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;/plugin&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#268bd2">&amp;lt;/plugins&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">&amp;lt;/build&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>添加接口定义文件&lt;code>src/main/proto/hello.proto&lt;/code>,Dubbo 使用 &lt;a href="https://developers.google.com/protocol-buffers">Protobuf&lt;/a> 作为 IDL&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-protobuf" data-lang="protobuf">&lt;span style="display:flex;">&lt;span>syntax &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">&amp;#34;proto3&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">option&lt;/span> java_multiple_files &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#cb4b16">true&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">option&lt;/span> java_package &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">&amp;#34;org.apache.dubbo.hello&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">option&lt;/span> java_outer_classname &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">&amp;#34;HelloWorldProto&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">option&lt;/span> objc_class_prefix &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">&amp;#34;HLW&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">package&lt;/span> helloworld;
&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">message&lt;/span> &lt;span style="color:#268bd2">HelloRequest&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">string&lt;/span> name &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">1&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">message&lt;/span> &lt;span style="color:#268bd2">HelloReply&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#dc322f">string&lt;/span> &lt;span style="color:#268bd2">message&lt;/span> &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#2aa198">1&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">service&lt;/span> Greeter{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">rpc&lt;/span> greet(HelloRequest) &lt;span style="color:#719e07">returns&lt;/span> (HelloReply);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>编译 IDL&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>$ mvn clean install
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>编译成功后,可以看到&lt;code>target/generated-sources/protobuf/java&lt;/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-fallback" data-lang="fallback">&lt;span style="display:flex;">&lt;span>$ ls org/apache/dubbo/hello/
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>DubboGreeterTriple.java HelloReply.java HelloRequest.java HelloWorldProto.java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Greeter.java HelloReplyOrBuilder.java HelloRequestOrBuilder.java
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>添加服务端接口实现&lt;code>src/main/java/org/apache/dubbo/GreeterImpl.java&lt;/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:#719e07">package&lt;/span> org.apache.dubbo;
&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.hello.DubboGreeterTriple;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.hello.HelloReply;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.hello.HelloRequest;
&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">GreeterImpl&lt;/span> &lt;span style="color:#268bd2">extends&lt;/span> DubboGreeterTriple.GreeterImplBase {
&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> HelloReply &lt;span style="color:#268bd2">greet&lt;/span>(HelloRequest request) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#719e07">return&lt;/span> HelloReply.newBuilder()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .setMessage(&lt;span style="color:#2aa198">&amp;#34;Hello,&amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> request.getName() &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> .build();
&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;/li>
&lt;li>
&lt;p>添加服务端启动类 &lt;code>src/main/java/org/apache/dubbo/MyDubboServer.java&lt;/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:#719e07">package&lt;/span> org.apache.dubbo;
&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.constants.CommonConstants;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.config.ApplicationConfig;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.config.ProtocolConfig;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.config.RegistryConfig;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.config.ServiceConfig;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.config.bootstrap.DubboBootstrap;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.hello.Greeter;
&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> java.io.IOException;
&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">MyDubboServer&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">static&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">main&lt;/span>(String&lt;span style="color:#719e07">[]&lt;/span> args) &lt;span style="color:#268bd2">throws&lt;/span> IOException {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ServiceConfig&lt;span style="color:#719e07">&amp;lt;&lt;/span>Greeter&lt;span style="color:#719e07">&amp;gt;&lt;/span> service &lt;span style="color:#719e07">=&lt;/span> &lt;span style="color:#719e07">new&lt;/span> ServiceConfig&lt;span style="color:#719e07">&amp;lt;&amp;gt;&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> service.setInterface(Greeter.class);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> service.setRef(&lt;span style="color:#719e07">new&lt;/span> GreeterImpl());
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> DubboBootstrap bootstrap &lt;span style="color:#719e07">=&lt;/span> DubboBootstrap.getInstance();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> bootstrap.application(&lt;span style="color:#719e07">new&lt;/span> ApplicationConfig(&lt;span style="color:#2aa198">&amp;#34;tri-stub-server&amp;#34;&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .registry(&lt;span style="color:#719e07">new&lt;/span> RegistryConfig(&lt;span style="color:#2aa198">&amp;#34;zookeeper://127.0.0.1:2181&amp;#34;&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .protocol(&lt;span style="color:#719e07">new&lt;/span> ProtocolConfig(CommonConstants.TRIPLE, 50051))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .service(service)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .start();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.out.println(&lt;span style="color:#2aa198">&amp;#34;Dubbo triple stub server started&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.in.read();
&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;/li>
&lt;li>
&lt;p>添加客户端启动类&lt;code>src/main/java/org/apache/dubbo/MyDubboClient.java&lt;/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:#719e07">package&lt;/span> org.apache.dubbo;
&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.constants.CommonConstants;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.config.ApplicationConfig;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.config.ReferenceConfig;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.config.RegistryConfig;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.config.bootstrap.DubboBootstrap;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.hello.Greeter;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.hello.HelloReply;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#719e07">import&lt;/span> org.apache.dubbo.hello.HelloRequest;
&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">MyDubboClient&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">static&lt;/span> &lt;span style="color:#dc322f">void&lt;/span> &lt;span style="color:#268bd2">main&lt;/span>(String&lt;span style="color:#719e07">[]&lt;/span> args) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> DubboBootstrap bootstrap &lt;span style="color:#719e07">=&lt;/span> DubboBootstrap.getInstance();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ReferenceConfig&lt;span style="color:#719e07">&amp;lt;&lt;/span>Greeter&lt;span style="color:#719e07">&amp;gt;&lt;/span> ref &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> ref.setInterface(Greeter.class);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ref.setProtocol(CommonConstants.TRIPLE);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ref.setProxy(CommonConstants.NATIVE_STUB);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ref.setTimeout(3000);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> bootstrap.application(&lt;span style="color:#719e07">new&lt;/span> ApplicationConfig(&lt;span style="color:#2aa198">&amp;#34;tri-stub-client&amp;#34;&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .registry(&lt;span style="color:#719e07">new&lt;/span> RegistryConfig(&lt;span style="color:#2aa198">&amp;#34;zookeeper://127.0.0.1:2181&amp;#34;&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .reference(ref)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .start();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Greeter greeter &lt;span style="color:#719e07">=&lt;/span> ref.get();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> HelloRequest request &lt;span style="color:#719e07">=&lt;/span> HelloRequest.newBuilder().setName(&lt;span style="color:#2aa198">&amp;#34;Demo&amp;#34;&lt;/span>).build();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> HelloReply reply &lt;span style="color:#719e07">=&lt;/span> greeter.greet(request);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> System.out.println(&lt;span style="color:#2aa198">&amp;#34;Received reply:&amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> reply);
&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;/li>
&lt;li>
&lt;p>编译代码&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>$ mvn clean install
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>启动服务端&lt;/p>
&lt;/li>
&lt;/ol>
&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>$ mvn org.codehaus.mojo:exec-maven-plugin:3.0.0:java -Dexec.mainClass=&amp;#34;org.apache.dubbo.MyDubboServer&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Dubbo triple stub server started
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="11">
&lt;li>打开新的终端,启动客户端&lt;/li>
&lt;/ol>
&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>$ mvn org.codehaus.mojo:exec-maven-plugin:3.0.0:java -Dexec.mainClass=&amp;#34;org.apache.dubbo.MyDubboClient&amp;#34;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Received reply:message: &amp;#34;Hello,Demo!&amp;#34;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item></channel></rss>