This is an automated email from the ASF dual-hosted git repository.
albumenj pushed a commit to branch refactor/next-2
in repository https://gitbox.apache.org/repos/asf/dubbo-website.git
The following commit(s) were added to refs/heads/refactor/next-2 by this push:
new 063aa1fd19 Update java quickstart (#2176)
063aa1fd19 is described below
commit 063aa1fd19a43722db66f95f256ca81388c7aee3
Author: Albumen Kevin <[email protected]>
AuthorDate: Fri Feb 10 09:51:26 2023 +0800
Update java quickstart (#2176)
---
content/zh-cn/overview/quickstart/_index.md | 5 +
content/zh-cn/overview/quickstart/java/_index.md | 333 +-----------
content/zh-cn/overview/quickstart/java/api.md | 277 ++++++++++
.../quickstart/java/{_index.md => brief.md} | 44 +-
.../zh-cn/overview/quickstart/java/spring-boot.md | 556 +++++++++++++++++++++
.../zh-cn/overview/quickstart/java/spring-xml.md | 393 +++++++++++++++
data/i18n/{zh => zh-cn}/zh.toml | 0
i18n/{zh.toml => zh-cn.toml} | 0
8 files changed, 1263 insertions(+), 345 deletions(-)
diff --git a/content/zh-cn/overview/quickstart/_index.md
b/content/zh-cn/overview/quickstart/_index.md
index 0bebea8a3e..17f2ca5ba5 100755
--- a/content/zh-cn/overview/quickstart/_index.md
+++ b/content/zh-cn/overview/quickstart/_index.md
@@ -16,6 +16,11 @@ no_list: true
<h4 class="card-title">
<a href='{{< relref "./java/" >}}'>Java 微服务开发入门</a>
</h4>
+ <p> </p>
+ <p><a href='{{< relref "./java/brief" >}}'>1 - 快速部署</a></p>
+ <p><a href='{{< relref "./java/api" >}}'>2 - 基于 Dubbo API
开发</a></p>
+ <p><a href='{{< relref "./java/spring-boot" >}}'>3 - 基于
Dubbo x Spring Boot 开发</a></p>
+ <p><a href='{{< relref "./java/spring-xml" >}}'>4 - 基于
Dubbo x Spring XML 开发</a></p>
<p></p>
</div>
</div>
diff --git a/content/zh-cn/overview/quickstart/java/_index.md
b/content/zh-cn/overview/quickstart/java/_index.md
index e30ffdc937..8623084875 100755
--- a/content/zh-cn/overview/quickstart/java/_index.md
+++ b/content/zh-cn/overview/quickstart/java/_index.md
@@ -3,312 +3,9 @@ type: docs
title: "Java 微服务开发入门"
linkTitle: "Java"
weight: 10
+no_list: true
---
-## 背景
-
-
-
-Dubbo 作为一款微服务框架,最重要的是向用户提供跨进程的 RPC 远程调用能力。如上图所示,Dubbo
的服务消费者(Consumer)通过一系列的工作将请求发送给服务提供者(Provider)。
-
-为了实现这样一个目标,Dubbo
引入了注册中心(Registry)组件,通过注册中心,服务消费者可以感知到服务提供者的连接方式,从而将请求发送给正确的服务提供者。
-
-## 目标
-
-了解微服务调用的方式以及 Dubbo 的能力
-
-## 难度
-
-低
-
-## 环境要求
-
-- 系统:Windows、Linux、MacOS
-
-- JDK 8 及以上(推荐使用 JDK17)
-
-- Git
-
-- Docker (可选)
-
-## 动手实践
-
-本章将通过几个简单的命令,一步一步教你如何部署并运行一个最简单的 Dubbo 用例。
-
-### 1. 获取测试工程
-
-在开始整个教程之前,我们需要先获取测试工程的代码。Dubbo 的所有测试用例代码都存储在
[apache/dubbo-samples](https://github.com/apache/dubbo-samples)
这个仓库中,以下这个命令可以帮你获取 Samples 仓库的所有代码。
-
-```bash
-git clone --depth=1 --branch master [email protected]:apache/dubbo-samples.git
-```
-
-### 2. 认识 Dubbo Samples 项目结构
-
-在将 [apache/dubbo-samples](https://github.com/apache/dubbo-samples) 这个仓库 clone
到本地以后,本小节将就仓库的具体组织方式做说明。
-
-```
-.
-├── codestyle // 开发使用的 style 配置文件
-
-├── 1-basic // 基础的入门用例
-├── 2-advanced // 高级用法
-├── 3-extensions // 扩展使用示例
-├── 4-governance // 服务治理用例
-├── 10-task // Dubbo 学习系列示例
-
-├── 99-integration // 集成测试使用
-├── test // 集成测试使用
-└── tools // 三方组件快速启动工具
-```
-
-如上表所示,[apache/dubbo-samples](https://github.com/apache/dubbo-samples)
主要由三个部分组成:代码风格文件、测试代码、集成测试。
-
-1. 代码风格文件是开发 Dubbo 代码的时候可以使用,其中包括了 IntelliJ IDEA 的配置文件。
-
-2. 测试代码即本教材所需要的核心内容。目前包括了 5 个部分的内容:面向初学者的 basic 入门用例、面向开发人员的 advanced
高级用法、面向中间件维护者的 extensions Dubbo 周边扩展使用示例、面向生产的 governance 服务治理用例以及 Dubbo
学习系列。本文将基于 basic 入门用例中最简单的 Dubbo API 使用方式进行讲解。
-
-3. 集成测试是 Dubbo 的质量保证体系中重要的一环,Dubbo 的每个版本都会对所有的 samples 进行回归验证,保证 Dubbo
的所有变更都不会影响 samples 的使用。
-
-### 3. 启动一个简易的注册中心
-
-从这一小节开始,将正式通过三个命令部署一个微服务应用。
-
-从 [背景](#背景) 一节中可知,运行起 Dubbo 应用的一个大前提是部署一个注册中心,为了让本教程更易于上手,我们提供了一个基于 Apache
Zookeeper 注册中心的简易启动器,如果您需要在生产环境部署注册中心,请参考[生产环境初始化]()一文部署高可用的注册中心。
-
-```bash
-Windows:
-./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper
-
-Linux / MacOS:
-./mvnw clean compile exec:java -pl tools/embedded-zookeeper
-
-注:需要开一个独立的 terminal 运行,命令将会保持一直执行的状态。
-
-Docker:
-docker run --name some-zookeeper --restart always -d zookeeper
-```
-
-在执行完上述命令以后,等待一会出现如下图所示的日志即代表注册中心启动完毕,可以继续执行后续任务。
-
-
-
-### 4. 启动服务提供者
-
-在启动了注册中心之后,下一步是启动一个对外提供服务的服务提供者。在 dubbo-samples 中也提供了对应的示例,可以通过以下命令快速拉起。
-
-```bash
-Windows:
-./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-api
-Dexec.mainClass="org.apache.dubbo.samples.provider.Application"
-
-Linux / MacOS:
-./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-api
-Dexec.mainClass="org.apache.dubbo.samples.provider.Application"
-
-注:需要开一个独立的 terminal 运行,命令将会保持一直执行的状态。
-```
-
-在执行完上述命令以后,等待一会出现如下图所示的日志(`DubboBootstrap
awaiting`)即代表服务提供者启动完毕,标志着该服务提供者可以对外提供服务了。
-
-
-
-```log
-[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
-```
-
-### 5. 启动服务消费者
-
-最后一步是启动一个服务消费者来调用服务提供者,也即是 RPC 调用的核心,为服务消费者提供调用服务提供者的桥梁。
-
-```bash
-Windows:
-./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-api
-Dexec.mainClass="org.apache.dubbo.samples.client.Application"
-
-Linux / MacOS:
-./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-api
-Dexec.mainClass="org.apache.dubbo.samples.client.Application"
-```
-
-在执行完上述命令以后,等待一会出现如下图所示的日志(`hi, dubbo`),打印出的数据就是服务提供者处理之后返回的,标志着一次服务调用的成功。
-
-
-
-```log
-Receive result ======> hi, dubbo
-```
-
-## 延伸阅读
-
-### 1. 消费端是怎么找到服务端的?
-
-在本用例中的步骤 3 启动了一个 Zookeeper 的注册中心,服务提供者会向注册中心中写入自己的地址,供服务消费者获取。
-
-Dubbo 会在 Zookeeper 的 `/dubbo/interfaceName` 和 `/services/appName`
下写入服务提供者的连接信息。
-
-如下所示是 Zookeeper 上的数据示例:
-
-```
-[zk: localhost:2181(CONNECTED) 5] ls
/dubbo/org.apache.dubbo.samples.api.GreetingsService/providers
-[dubbo%3A%2F%2F30.221.146.35%3A20880%2Forg.apache.dubbo.samples.api.GreetingsService%3Fanyhost%3Dtrue%26application%3Dfirst-dubbo-provider%26background%3Dfalse%26deprecated%3Dfalse%26dubbo%3D2.0.2%26dynamic%3Dtrue%26environment%3Dproduct%26generic%3Dfalse%26interface%3Dorg.apache.dubbo.samples.api.GreetingsService%26ipv6%3Dfd00%3A1%3A5%3A5200%3A3218%3A774a%3A4f67%3A2341%26methods%3DsayHi%26pid%3D85639%26release%3D3.1.4%26service-name-mapping%3Dtrue%26side%3Dprovider%26timestamp%3D1674960780647]
-
-[zk: localhost:2181(CONNECTED) 2] ls /services/first-dubbo-provider
-[30.221.146.35:20880]
-[zk: localhost:2181(CONNECTED) 3] get
/services/first-dubbo-provider/30.221.146.35:20880
-{"name":"first-dubbo-provider","id":"30.221.146.35:20880","address":"30.221.146.35","port":20880,"sslPort":null,"payload":{"@class":"org.apache.dubbo.registry.zookeeper.ZookeeperInstance","id":"30.221.146.35:20880","name":"first-dubbo-provider","metadata":{"dubbo.endpoints":"[{\"port\":20880,\"protocol\":\"dubbo\"}]","dubbo.metadata-service.url-params":"{\"connections\":\"1\",\"version\":\"1.0.0\",\"dubbo\":\"2.0.2\",\"release\":\"3.1.4\",\"side\":\"provider\",\"ipv6\":\"fd00:1:5:5200:32
[...]
-```
-
-更多关于 Dubbo
服务发现模型的细节,可以参考[服务发现](/zh/docs3-v2/java-sdk/concepts-and-architecture/service-discovery/)一文。
-
-### 2. 消费端是如何发起请求的?
-
-在 Dubbo 的调用模型中,起到连接服务消费者和服务提供者的桥梁是接口。
-
-服务提供者通过对指定接口进行实现,服务消费者通过 Dubbo 去订阅这个接口。服务消费者调用接口的过程中 Dubbo
会将请求封装成网络请求,然后发送到服务提供者进行实际的调用。
-
-在本用例中,定义了一个 `GreetingsService` 的接口,这个接口有一个名为 `sayHi` 的方法。
-
-```java
-//
1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/api/GreetingsService.java
-
-package org.apache.dubbo.samples.api;
-
-public interface GreetingsService {
-
- String sayHi(String name);
-
-}
-```
-
-服务消费者通过 Dubbo 的 API 可以获取这个 `GreetingsService` 接口的代理,然后就可以按照普通的接口调用方式进行调用。**得益于
Dubbo 的动态代理机制,这一切都像本地调用一样。**
-
-```java
-//
1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/client/Application.java
-
-// 获取订阅到的 Stub
-GreetingsService service = reference.get();
-// 像普通的 java 接口一样调用
-String message = service.sayHi("dubbo");
-```
-
-### 3. 服务端可以部署多个吗?
-
-可以,本小节将演示如何启动一个服务端**集群**。
-
-1)启动一个注册中心,可以参考动手实践中第 3 小节的[教程](#3-启动一个简易的注册中心)
-
-2)修改服务提供者返回的数据,让第一个启动的服务提供者返回 `hi, dubbo. I am provider 1.`
-
-修改
`1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java`
文件的第 25 行如下所示。
-
-```java
-//
1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java
-
-package org.apache.dubbo.samples.provider;
-
-import org.apache.dubbo.samples.api.GreetingsService;
-
-public class GreetingsServiceImpl implements GreetingsService {
- @Override
- public String sayHi(String name) {
- return "hi, " + name + ". I am provider 1.";
- }
-}
-```
-
-3)启动第一个服务提供者,可以参考动手实践中第 4 小节的[教程](#4-启动服务提供者)
-
-4)修改服务提供者返回的数据,让第二个启动的服务提供者返回 `hi, dubbo. I am provider 2.`
-
-修改
`1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java`
文件的第 25 行如下所示。
-
-```java
-//
1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java
-
-package org.apache.dubbo.samples.provider;
-
-import org.apache.dubbo.samples.api.GreetingsService;
-
-public class GreetingsServiceImpl implements GreetingsService {
- @Override
- public String sayHi(String name) {
- return "hi, " + name + ". I am provider 2.";
- }
-}
-```
-
-4)启动第二个服务提供者,可以参考动手实践中第 4 小节的[教程](#4-启动服务提供者)
-
-5)启动服务消费者,可以参考动手实践中第 5 小节的[教程](#5-启动服务消费者)。多次启动消费者可以看到返回的结果是不一样的。
-
-在 dubbo-samples
中也提供了一个会定时发起调用的消费端应用`org.apache.dubbo.samples.client.AlwaysApplication`,可以通过以下命令启动。
-
-```bash
-Windows:
-./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-api
-Dexec.mainClass="org.apache.dubbo.samples.client.AlwaysApplication"
-
-Linux / MacOS:
-./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-api
-Dexec.mainClass="org.apache.dubbo.samples.client.AlwaysApplication"
-```
-
-启动后可以看到类似以下的日志,消费端会随机调用到不同的服务提供者,返回的结果也是远端的服务提供者觉得其结果。
-
-```
-Sun Jan 29 11:23:37 CST 2023 Receive result ======> hi, dubbo. I am provider 1.
-Sun Jan 29 11:23:38 CST 2023 Receive result ======> hi, dubbo. I am provider 2.
-Sun Jan 29 11:23:39 CST 2023 Receive result ======> hi, dubbo. I am provider 2.
-Sun Jan 29 11:23:40 CST 2023 Receive result ======> hi, dubbo. I am provider 1.
-Sun Jan 29 11:23:41 CST 2023 Receive result ======> hi, dubbo. I am provider 1.
-```
-
-### 4. 这个用例复杂吗?
-
-不,Dubbo 只需要简单的配置就可以实现稳定、高效的远程调用。
-
-以下是一个服务提供者的简单示例,通过定义若干个配置就可以启动。
-
-```java
-//
1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/Application.java
-
-// 定义所有的服务
-ServiceConfig<GreetingsService> service = new ServiceConfig<>();
-service.setInterface(GreetingsService.class);
-service.setRef(new GreetingsServiceImpl());
-
-// 启动 Dubbo
-DubboBootstrap.getInstance()
- .application("first-dubbo-provider")
- .registry(new RegistryConfig(ZOOKEEPER_ADDRESS))
- .protocol(new ProtocolConfig("dubbo", -1))
- .service(service)
- .start();
-```
-
-以下是一个服务消费者的简单示例,通过定义若干个配置启动后就可以获取到对应的代理对象,之后用户完全不需要感知这个对象背后的复杂实现,**一切只需要和本地调用一样就行了**。
-
-```java
-//
1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/client/Application.java
-
-// 定义所有的订阅
-ReferenceConfig<GreetingsService> reference = new ReferenceConfig<>();
-reference.setInterface(GreetingsService.class);
-
-// 启动 Dubbo
-DubboBootstrap.getInstance()
- .application("first-dubbo-consumer")
- .registry(new RegistryConfig(ZOOKEEPER_ADDRESS))
- .reference(reference)
- .start();
-
-// 获取订阅到的 Stub
-GreetingsService service = reference.get();
-// 像普通的 java 接口一样调用
-String message = service.sayHi("dubbo");
-```
-
-## 更多
-
-本用例介绍了一个 RPC 远程调用的基础流程,通过启动注册中心、服务提供者、服务消费者三个节点来模拟一个微服务的部署架构。
-
-下一个教程中,将就服务提供者和服务消费者分别都做了什么配置进行讲解,从零告诉你如何搭建一个微服务应用。
-
{{< blocks/section color="white" height="auto">}}
<div class="td-content list-page">
<div class="lead"></div><header class="article-meta">
@@ -317,9 +14,29 @@ String message = service.sayHi("dubbo");
<div class="h-100 card shadow" href="#">
<div class="card-body">
<h4 class="card-title">
- <a href='{{< relref
"../../../docs3-v2/rust-sdk/streaming/" >}}'>Streaming 通信模式</a>
+ <a href='{{< relref "./brief" >}}'>快速部署</a>
+ </h4>
+ <p>零基础快速部署一个微服务应用</p>
+ </div>
+ </div>
+ </div>
+ <div class="col-sm col-md-6 mb-4">
+ <div class="h-100 card shadow" href="#">
+ <div class="card-body">
+ <h4 class="card-title">
+ <a href='{{< relref "./api" >}}'>Dubbo API 开发</a>
+ </h4>
+ <p>基于 Dubbo API 开发微服务应用</p>
+ </div>
+ </div>
+ </div>
+ <div class="col-sm col-md-6 mb-4">
+ <div class="h-100 card shadow" href="#">
+ <div class="card-body">
+ <h4 class="card-title">
+ <a href='{{< relref "./spring-boot" >}}'>Dubbo x Spring
Boot 开发</a>
</h4>
- <p>使用 Dubbo Rust 实现 Streaming 通信模型。</p>
+ <p>Dubbo x Spring Boot 开发微服务应用</p>
</div>
</div>
</div>
@@ -327,9 +44,9 @@ String message = service.sayHi("dubbo");
<div class="h-100 card shadow" href="#">
<div class="card-body">
<h4 class="card-title">
- <a href='{{< relref
"../../../docs3-v2/rust-sdk/java-interoperability/" >}}'>与 Dubbo Java 互通</a>
+ <a href='{{< relref "./spring-xml" >}}'>Dubbo x Spring
XML 开发</a>
</h4>
- <p>实现与其他 Dubbo 多语言服务的互通</p>
+ <p>Dubbo x Spring XML 开发微服务应用</p>
</div>
</div>
</div>
diff --git a/content/zh-cn/overview/quickstart/java/api.md
b/content/zh-cn/overview/quickstart/java/api.md
new file mode 100644
index 0000000000..838d4ea9eb
--- /dev/null
+++ b/content/zh-cn/overview/quickstart/java/api.md
@@ -0,0 +1,277 @@
+---
+type: docs
+title: "2 - 基于 Dubbo API 开发微服务应用"
+linkTitle: "基于 Dubbo API 开发微服务应用"
+weight: 2
+description: "本文将基于 Dubbo Samples 示例演示如何通过 Dubbo API 快速开发微服务应用。"
+---
+
+## 目标
+
+从零上手开发基于 Dubbo 的微服务
+
+## 难度
+
+低
+
+## 环境要求
+
+- 系统:Windows、Linux、MacOS
+
+- JDK 8 及以上(推荐使用 JDK17)
+
+- Git
+
+- IntelliJ IDEA(可选)
+
+- Docker (可选)
+
+## 动手实践
+
+本章将通过手把手的教程一步一步教你如何从零开发一个微服务应用。
+
+### 1. 启动注册中心
+
+对于一个微服务化的应用来说,注册中心是不可或缺的一个组件。只有通过注册中心,消费端才可以成功发现服务端的地址信息,进而进行调用。
+
+为了让本教程更易于上手,我们提供了一个基于 Apache Zookeeper
注册中心的简易启动器,如果您需要在生产环境部署注册中心,请参考[生产环境初始化](/)一文部署高可用的注册中心。
+
+```bash
+Windows:
+git clone --depth=1 --branch master [email protected]:apache/dubbo-samples.git
+cd dubbo-samples
+./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper
+
+Linux / MacOS:
+git clone --depth=1 --branch master [email protected]:apache/dubbo-samples.git
+cd dubbo-samples
+./mvnw clean compile exec:java -pl tools/embedded-zookeeper
+
+Docker:
+docker run --name some-zookeeper --restart always -d zookeeper
+```
+
+### 2. 初始化项目
+
+从本小节开始,将基于 IntelliJ IDEA 进行工程的搭建以及测试。
+
+
+
+如上图所示,可以建立一个基础的项目。
+
+
+
+在初始化完项目之后,需要在 `src/main/java` 目录下创建 `org.apache.dubbo.samples.api`
、`org.apache.dubbo.samples.client` 和 `org.apache.dubbo.samples.provider` 三个
package。
+
+后续我们将在 `api` 下创建对应的接口,在 `client` 下创建对应客户端订阅服务的功能,在 `provider`
下创建对应服务端的实现以及发布服务的功能。
+
+上述三个 package 分别对应了应用共同依赖的 api、消费端应用的模块、服务端应用的模块。在实际部署中需要拆成三个工程,消费端和服务的共同依赖 api
模块。从简单出发,本教程将在同一个工程中进行开发,区分多个启动类。
+
+### 3. 添加 Maven 依赖
+
+在初始化完项目以后,我们需要先添加 Dubbo 相关的 maven 依赖。
+
+
+
+编辑 `pom.xml` 这个文件,添加下列配置。
+
+```xml
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo</artifactId>
+ <version>3.2.0-beta.4</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.curator</groupId>
+ <artifactId>curator-x-discovery</artifactId>
+ <version>4.3.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.zookeeper</groupId>
+ <artifactId>zookeeper</artifactId>
+ <version>3.8.0</version>
+ <exclusions>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-handler</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-transport-native-epoll</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+```
+
+在这份配置中,定义了 dubbo 和 zookeeper(以及对应的连接器 curator)的依赖。
+
+
+
+添加了上述的配置以后,可以通过 IDEA 的 `Maven - Reload All Maven Projects` 刷新依赖。
+
+### 4. 定义服务接口
+
+服务接口 Dubbo 中沟通消费端和服务端的桥梁。
+
+
+
+在 `org.apache.dubbo.samples.api` 下建立 `GreetingsService` 接口,定义如下:
+
+```java
+package org.apache.dubbo.samples.api;
+
+public interface GreetingsService {
+
+ String sayHi(String name);
+}
+```
+
+在 `GreetingsService` 中,定义了 `sayHi` 这个方法。后续服务端发布的服务,消费端订阅的服务都是围绕着
`GreetingsService` 接口展开的。
+
+### 5. 定义服务端的实现
+
+定义了服务接口之后,可以在服务端这一侧定义对应的实现,这部分的实现相对于消费端来说是远端的实现,本地没有相关的信息。
+
+
+
+在 `org.apache.dubbo.samples.provider` 下建立 `GreetingsServiceImpl` 类,定义如下:
+
+```java
+package org.apache.dubbo.samples.provider;
+
+import org.apache.dubbo.samples.api.GreetingsService;
+
+public class GreetingsServiceImpl implements GreetingsService {
+ @Override
+ public String sayHi(String name) {
+ return "hi, " + name;
+ }
+}
+```
+
+在 `GreetingsServiceImpl` 中,实现了 `GreetingsService` 接口,对于 `sayHi` 方法返回 `hi,
name`。
+
+### 6. 服务端发布服务
+
+在实现了服务之后,本小节将通过 Dubbo 的 API 在网络上发布这个服务。
+
+
+
+在 `org.apache.dubbo.samples.provider` 下建立 `Application` 类,定义如下:
+
+```java
+package org.apache.dubbo.samples.provider;
+
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.ServiceConfig;
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
+import org.apache.dubbo.samples.api.GreetingsService;
+
+public class Application {
+ public static void main(String[] args) {
+ // 定义具体的服务
+ ServiceConfig<GreetingsService> service = new ServiceConfig<>();
+ service.setInterface(GreetingsService.class);
+ service.setRef(new GreetingsServiceImpl());
+
+ // 启动 Dubbo
+ DubboBootstrap.getInstance()
+ .application("first-dubbo-provider")
+ .registry(new RegistryConfig("zookeeper://127.0.0.1:2181"))
+ .protocol(new ProtocolConfig("dubbo", -1))
+ .service(service)
+ .start()
+ .await();
+ }
+}
+```
+
+在 `org.apache.dubbo.samples.provider.Application` 中做了两部分的功能:首先是基于
`ServiceConfig` 定义了发布的服务信息,包括接口的信息以及对应的实现类对象;然后是配置 Dubbo
启动器,传入了应用名,注册中心地址,协议的信息以及服务的信息等。
+
+注:DubboBootstrap 中的`registry` 、`protocol` 和 `service` 可以多次传入。
+
+### 7. 消费端订阅并调用
+
+对于消费端,可以通过 Dubbo 的 API 可以进行消费端订阅。
+
+
+
+在 `org.apache.dubbo.samples.client` 下建立 `Application` 类,定义如下:
+
+```java
+package org.apache.dubbo.samples.client;
+
+import java.io.IOException;
+
+import org.apache.dubbo.config.ReferenceConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
+import org.apache.dubbo.samples.api.GreetingsService;
+
+public class Application {
+ public static void main(String[] args) throws IOException {
+ ReferenceConfig<GreetingsService> reference = new ReferenceConfig<>();
+ reference.setInterface(GreetingsService.class);
+
+ DubboBootstrap.getInstance()
+ .application("first-dubbo-consumer")
+ .registry(new RegistryConfig("zookeeper://127.0.0.1:2181"))
+ .reference(reference);
+
+ GreetingsService service = reference.get();
+ String message = service.sayHi("dubbo");
+ System.out.println("Receive result ======> " + message);
+ System.in.read();
+ }
+}
+```
+
+在 `org.apache.dubbo.samples.client.Application` 中做了三部分的功能:
+
+首先是基于 `ReferenceConfig` 定义了订阅的服务信息,包括接口的信息。
+
+其次是配置 Dubbo 启动器,传入了应用名,注册中心地址,协议的信息以及服务的信息等。
+
+最后是获取到动态代理的对象并进行调用。
+
+注:DubboBootstrap 中支持 `service` 和 `reference` 可以同时传入,意味着一个应用可以同时即是消费端、也是服务端。
+
+### 8. 启动应用
+
+截止第 7 步,代码就已经开发完成了,本小节将启动整个项目并进行验证。
+
+
+
+首先是启动 `org.apache.dubbo.samples.provider.Application`
,等待一会出现如下图所示的日志(`DubboBootstrap awaiting`)即代表服务提供者启动完毕,标志着该服务提供者可以对外提供服务了。
+
+```log
+[DUBBO] DubboBootstrap awaiting ..., dubbo version: 3.2.0-beta.4, current
host: 169.254.44.42
+```
+
+然后是启动`org.apache.dubbo.samples.client.Application` ,等待一会出现如下图所示的日志(`hi, dubbo`
)即代表服务消费端启动完毕并调用到服务端成功获取结果。
+
+
+
+```log
+Receive result ======> hi, dubbo
+```
+
+## 延伸阅读
+
+### 1. Dubbo 的配置介绍
+
+Dubbo 的主要配置入口有`ReferenceConfig` 、`ServiceConfig` 和 `DubboBootstrap` ,更多的细节可以参考
[API 配置 | Apache Dubbo](/zh-cn/docs3-v2/java-sdk/reference-manual/config/api/)
一文。
+
+### 2. 除了 API 方式其他的使用方式
+
+Dubbo 除了 API 方式还支持 Spring XML、Annotation、Spring Boot 等配置方式,在下一个教程中将就 Spring
Boot 配置方式讲解如何进行快速开发。
+
+关于 XML 和 Annotation 的细节可以参考 [XML 配置 | Apache
Dubbo](/zh-cn/docs3-v2/java-sdk/reference-manual/config/xml/)、[Annotation 配置 |
Apache Dubbo](/zh-cn/docs3-v2/java-sdk/reference-manual/config/annotation/) 疑问。
+
+## 更多
+
+本教程介绍了如何基于 Dubbo 的纯 API 开发一个微服务应用。下一个教程中,将介绍[如何基于 Spring Boot
开发微服务项目](../spring-boot/)。
diff --git a/content/zh-cn/overview/quickstart/java/_index.md
b/content/zh-cn/overview/quickstart/java/brief.md
old mode 100755
new mode 100644
similarity index 90%
copy from content/zh-cn/overview/quickstart/java/_index.md
copy to content/zh-cn/overview/quickstart/java/brief.md
index e30ffdc937..b57bb8360f
--- a/content/zh-cn/overview/quickstart/java/_index.md
+++ b/content/zh-cn/overview/quickstart/java/brief.md
@@ -1,8 +1,9 @@
---
type: docs
-title: "Java 微服务开发入门"
-linkTitle: "Java"
-weight: 10
+title: "1 - 零基础快速部署一个微服务应用"
+linkTitle: "快速部署一个微服务应用"
+weight: 1
+description: "本文将基于 Dubbo Samples 示例演示如何快速搭建并部署一个微服务应用。"
---
## 背景
@@ -74,7 +75,7 @@ git clone --depth=1 --branch master
[email protected]:apache/dubbo-samples.git
从这一小节开始,将正式通过三个命令部署一个微服务应用。
-从 [背景](#背景) 一节中可知,运行起 Dubbo 应用的一个大前提是部署一个注册中心,为了让本教程更易于上手,我们提供了一个基于 Apache
Zookeeper 注册中心的简易启动器,如果您需要在生产环境部署注册中心,请参考[生产环境初始化]()一文部署高可用的注册中心。
+从 [背景](#背景) 一节中可知,运行起 Dubbo 应用的一个大前提是部署一个注册中心,为了让本教程更易于上手,我们提供了一个基于 Apache
Zookeeper 注册中心的简易启动器,如果您需要在生产环境部署注册中心,请参考[生产环境初始化](/)一文部署高可用的注册中心。
```bash
Windows:
@@ -155,7 +156,7 @@ Dubbo 会在 Zookeeper 的 `/dubbo/interfaceName` 和
`/services/appName` 下
{"name":"first-dubbo-provider","id":"30.221.146.35:20880","address":"30.221.146.35","port":20880,"sslPort":null,"payload":{"@class":"org.apache.dubbo.registry.zookeeper.ZookeeperInstance","id":"30.221.146.35:20880","name":"first-dubbo-provider","metadata":{"dubbo.endpoints":"[{\"port\":20880,\"protocol\":\"dubbo\"}]","dubbo.metadata-service.url-params":"{\"connections\":\"1\",\"version\":\"1.0.0\",\"dubbo\":\"2.0.2\",\"release\":\"3.1.4\",\"side\":\"provider\",\"ipv6\":\"fd00:1:5:5200:32
[...]
```
-更多关于 Dubbo
服务发现模型的细节,可以参考[服务发现](/zh/docs3-v2/java-sdk/concepts-and-architecture/service-discovery/)一文。
+更多关于 Dubbo
服务发现模型的细节,可以参考[服务发现](/zh-cn/docs3-v2/java-sdk/concepts-and-architecture/service-discovery/)一文。
### 2. 消费端是如何发起请求的?
@@ -307,35 +308,4 @@ String message = service.sayHi("dubbo");
本用例介绍了一个 RPC 远程调用的基础流程,通过启动注册中心、服务提供者、服务消费者三个节点来模拟一个微服务的部署架构。
-下一个教程中,将就服务提供者和服务消费者分别都做了什么配置进行讲解,从零告诉你如何搭建一个微服务应用。
-
-{{< blocks/section color="white" height="auto">}}
-<div class="td-content list-page">
- <div class="lead"></div><header class="article-meta">
- </header><div class="row">
- <div class="col-sm col-md-6 mb-4">
- <div class="h-100 card shadow" href="#">
- <div class="card-body">
- <h4 class="card-title">
- <a href='{{< relref
"../../../docs3-v2/rust-sdk/streaming/" >}}'>Streaming 通信模式</a>
- </h4>
- <p>使用 Dubbo Rust 实现 Streaming 通信模型。</p>
- </div>
- </div>
- </div>
- <div class="col-sm col-md-6 mb-4">
- <div class="h-100 card shadow" href="#">
- <div class="card-body">
- <h4 class="card-title">
- <a href='{{< relref
"../../../docs3-v2/rust-sdk/java-interoperability/" >}}'>与 Dubbo Java 互通</a>
- </h4>
- <p>实现与其他 Dubbo 多语言服务的互通</p>
- </div>
- </div>
- </div>
-</div>
-<hr>
-</div>
-
-{{< /blocks/section >}}
-
+下一个教程中,将就服务提供者和服务消费者分别都做了什么配置进行讲解,[从零告诉你如何搭建一个微服务应用](../api/)。
diff --git a/content/zh-cn/overview/quickstart/java/spring-boot.md
b/content/zh-cn/overview/quickstart/java/spring-boot.md
new file mode 100644
index 0000000000..1965ea52fc
--- /dev/null
+++ b/content/zh-cn/overview/quickstart/java/spring-boot.md
@@ -0,0 +1,556 @@
+---
+type: docs
+title: "3 - Dubbo x Spring Boot 开发微服务应用"
+linkTitle: "Dubbo x Spring Boot 开发微服务应用"
+weight: 3
+description: "本文将基于 Dubbo Samples 示例演示如何通过 Dubbo x Spring Boot 快速开发微服务应用。"
+---
+
+## 目标
+
+从零上手开发基于 Dubbo x Spring Boot 的微服务开发,了解 Dubbo x Spring Boot 配置方式。
+
+## 难度
+
+低
+
+## 环境要求
+
+- 系统:Windows、Linux、MacOS
+
+- JDK 8 及以上(推荐使用 JDK17)
+
+- Git
+
+- IntelliJ IDEA(可选)
+
+- Docker (可选)
+
+## 项目介绍
+
+在本任务中,将分为 3 个子模块进行独立开发,模拟生产环境下的部署架构。
+
+```
+. // apache/dubbo-samples/1-basic/dubbo-samples-spring-boot
+├── dubbo-samples-spring-boot-interface // 共享 API 模块
+├── dubbo-samples-spring-boot-consumer // 消费端模块
+└── dubbo-samples-spring-boot-provider // 服务端模块
+```
+
+如上所示,共有 3 个模块,其中 `interface` 模块被 `consumer` 和 `provider` 两个模块共同依赖,存储 RPC 通信使用的
API 接口。
+
+```
+. // apache/dubbo-samples/1-basic/dubbo-samples-spring-boot
+├── dubbo-samples-spring-boot-interface // 共享 API 模块
+│ ├── pom.xml
+│ └── src
+│ └── main
+│ └── java
+│ └── org
+│ └── apache
+│ └── dubbo
+│ └── springboot
+│ └── demo
+│ └── DemoService.java // API 接口
+├── dubbo-samples-spring-boot-consumer // 消费端模块
+│ ├── pom.xml
+│ └── src
+│ ├── main
+│ │ ├── java
+│ │ │ └── org
+│ │ │ └── apache
+│ │ │ └── dubbo
+│ │ │ └── springboot
+│ │ │ └── demo
+│ │ │ └── consumer
+│ │ │ ├── ConsumerApplication.java // 消费端启动类
+│ │ │ └── Task.java //
消费端模拟调用任务
+│ │ └── resources
+│ │ └── application.yml // Spring Boot 配置文件
+├── dubbo-samples-spring-boot-provider // 服务端模块
+│ ├── pom.xml
+│ └── src
+│ └── main
+│ ├── java
+│ │ └── org
+│ │ └── apache
+│ │ └── dubbo
+│ │ └── springboot
+│ │ └── demo
+│ │ └── provider
+│ │ ├── DemoServiceImpl.java //
服务端实现类
+│ │ └── ProviderApplication.java //
服务端启动类
+│ └── resources
+│ └── application.yml // Spring Boot 配置文件
+└── pom.xml
+```
+
+如上为本教程接下来会使用到的项目的文件结构。
+
+## 快速部署(基于 Samples 直接启动)
+
+本章将通过几个简单的命令,一步一步教你如何部署并运行一个基于 Dubbo x Spring Boot 的用例。
+
+注:本章部署的代码细节可以在 [apache/dubbo-samples](https://github.com/apache/dubbo-samples)
这个仓库中 `1-basic/dubbo-samples-spring-boot` 中找到,在下一章中也将展开进行讲解。
+
+### 1. 获取测试工程
+
+在开始整个教程之前,我们需要先获取测试工程的代码。Dubbo 的所有测试用例代码都存储在
[apache/dubbo-samples](https://github.com/apache/dubbo-samples)
这个仓库中,以下这个命令可以帮你获取 Samples 仓库的所有代码。
+
+```bash
+git clone --depth=1 --branch master [email protected]:apache/dubbo-samples.git
+```
+
+### 2. 启动一个简易的注册中心
+
+对于一个微服务化的应用来说,注册中心是不可或缺的一个组件。只有通过注册中心,消费端才可以成功发现服务端的地址信息,进而进行调用。
+
+为了让本教程更易于上手,我们提供了一个基于 Apache Zookeeper
注册中心的简易启动器,如果您需要在生产环境部署注册中心,请参考[生产环境初始化](/)一文部署高可用的注册中心。
+
+```bash
+Windows:
+./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper
+
+Linux / MacOS:
+./mvnw clean compile exec:java -pl tools/embedded-zookeeper
+
+Docker:
+docker run --name some-zookeeper -p 2181:2181 --restart always -d zookeeper
+```
+
+### 3. 本地打包 API 模块
+
+为了成功编译服务端、消费端模块,需要先在本地打包安装 `dubbo-samples-spring-boot-interface` 模块。
+
+```bash
+./mvnw clean install -pl 1-basic/dubbo-samples-spring-boot
+./mvnw clean install -pl
1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-interface
+```
+
+### 4. 启动服务提供者
+
+在启动了注册中心之后,下一步是启动一个对外提供服务的服务提供者。在 dubbo-samples 中也提供了对应的示例,可以通过以下命令快速拉起。
+
+```bash
+Windows:
+./mvnw.cmd clean compile exec:java -pl
1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-provider
-Dexec.mainClass="org.apache.dubbo.springboot.demo.provider.ProviderApplication"
+
+Linux / MacOS:
+./mvnw clean compile exec:java -pl
1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-provider
-Dexec.mainClass="org.apache.dubbo.springboot.demo.provider.ProviderApplication"
+
+注:需要开一个独立的 terminal 运行,命令将会保持一直执行的状态。
+```
+
+在执行完上述命令以后,等待一会出现如下所示的日志(`Current Spring Boot Application is
await`)即代表服务提供者启动完毕,标志着该服务提供者可以对外提供服务了。
+
+```log
+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
+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)
+2023-02-08 17:13:00.387 INFO 80600 --- [pool-1-thread-1]
.b.c.e.AwaitingNonWebApplicationListener : [Dubbo] Current Spring Boot
Application is await...
+```
+
+### 5. 启动服务消费者
+
+最后一步是启动一个服务消费者来调用服务提供者,也即是 RPC 调用的核心,为服务消费者提供调用服务提供者的桥梁。
+
+```bash
+Windows:
+./mvnw.cmd clean compile exec:java -pl
1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-consumer
-Dexec.mainClass="org.apache.dubbo.springboot.demo.consumer.ConsumerApplication"
+
+Linux / MacOS:
+./mvnw clean compile exec:java -pl
1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-consumer
-Dexec.mainClass="org.apache.dubbo.springboot.demo.consumer.ConsumerApplication"
+```
+
+在执行完上述命令以后,等待一会出现如下所示的日志(`Hello world`),打印出的数据就是服务提供者处理之后返回的,标志着一次服务调用的成功。
+
+```log
+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)
+Receive result ======> Hello world
+2023-02-08 17:14:33.146 INFO 80740 --- [pool-1-thread-1]
.b.c.e.AwaitingNonWebApplicationListener : [Dubbo] Current Spring Boot
Application is await...
+Wed Feb 08 17:14:34 CST 2023 Receive result ======> Hello world
+Wed Feb 08 17:14:35 CST 2023 Receive result ======> Hello world
+Wed Feb 08 17:14:36 CST 2023 Receive result ======> Hello world
+Wed Feb 08 17:14:37 CST 2023 Receive result ======> Hello world
+```
+
+## 动手实践(从零代码开发版)
+
+本章将通过手把手的教程一步一步教你如何从零开发一个微服务应用。
+
+### 1. 启动注册中心
+
+对于一个微服务化的应用来说,注册中心是不可或缺的一个组件。只有通过注册中心,消费端才可以成功发现服务端的地址信息,进而进行调用。
+
+为了让本教程更易于上手,我们提供了一个基于 Apache Zookeeper
注册中心的简易启动器,如果您需要在生产环境部署注册中心,请参考[生产环境初始化](/)一文部署高可用的注册中心。
+
+```bash
+Windows:
+git clone --depth=1 --branch master [email protected]:apache/dubbo-samples.git
+cd dubbo-samples
+./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper
+
+Linux / MacOS:
+git clone --depth=1 --branch master [email protected]:apache/dubbo-samples.git
+cd dubbo-samples
+./mvnw clean compile exec:java -pl tools/embedded-zookeeper
+
+Docker:
+docker run --name some-zookeeper -p 2181:2181 --restart always -d zookeeper
+```
+
+### 2. 初始化项目
+
+从本小节开始,将基于 IntelliJ IDEA 进行工程的搭建以及测试。
+
+
+
+如上图所示,可以建立一个基础的项目。
+
+搭建了基础项目之后,我们还需要创建 `dubbo-spring-boot-demo-interface`
、`dubbo-spring-boot-demo-provider` 和 `dubbo-spring-boot-demo-consumer` 三个子模块。
+
+
+
+
+
+
+
+
+
+创建了三个子模块之后,需要创建一下几个文件夹:
+
+1. 在 `dubbo-spring-boot-demo-consumer/src/main/java` 下创建
`org.apache.dubbo.springboot.demo.consumer` package
+
+2. 在 `dubbo-spring-boot-demo-interface/src/main/java` 下创建
`org.apache.dubbo.springboot.demo` package
+
+3. 在 `dubbo-spring-boot-demo-provider/src/main/java` 下创建
`org.apache.dubbo.springboot.demo.provider` package
+
+
+
+最终的文件夹参考如上图所示。
+
+### 3. 添加 Maven 依赖
+
+在初始化完项目以后,我们需要先添加 Dubbo 相关的 maven 依赖。
+
+对于多模块项目,首先需要在父项目的 `pom.xml` 里面配置依赖信息。
+
+
+
+编辑 `./pom.xml` 这个文件,添加下列配置。
+
+```xml
+ <properties>
+ <dubbo.version>3.2.0-beta.4</dubbo.version>
+ <spring-boot.version>2.7.8</spring-boot.version>
+ <maven.compiler.source>17</maven.compiler.source>
+ <maven.compiler.target>17</maven.compiler.target>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <!-- Spring Boot -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-dependencies</artifactId>
+ <version>${spring-boot.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+
+ <!-- Dubbo -->
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-bom</artifactId>
+ <version>${dubbo.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
+ <version>${dubbo.version}</version>
+ <type>pom</type>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>${spring-boot.version}</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+```
+
+然后在 `dubbo-spring-boot-consumer` 和 `dubbo-spring-boot-provider` 两个模块 `pom.xml`
中进行具体依赖的配置。
+
+
+
+编辑 `./dubbo-spring-boot-consumer/pom.xml` 和
`./dubbo-spring-boot-provider/pom.xml` 这两文件,都添加下列配置。
+
+```xml
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-samples-spring-boot-interface</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+
+ <!-- dubbo -->
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-spring-boot-starter</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
+ <type>pom</type>
+ <exclusions>
+ <exclusion>
+ <artifactId>slf4j-reload4j</artifactId>
+ <groupId>org.slf4j</groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <!-- spring boot starter -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter</artifactId>
+ </dependency>
+
+ </dependencies>
+```
+
+在这份配置中,定义了 dubbo 和 zookeeper(以及对应的连接器 curator)的依赖。
+
+添加了上述的配置以后,可以通过 IDEA 的 `Maven - Reload All Maven Projects` 刷新依赖。
+
+### 4. 定义服务接口
+
+服务接口 Dubbo 中沟通消费端和服务端的桥梁。
+
+
+
+在 `dubbo-spring-boot-demo-interface` 模块的 `org.apache.dubbo.samples.api` 下建立
`DemoService` 接口,定义如下:
+
+```java
+package org.apache.dubbo.springboot.demo;
+
+public interface DemoService {
+
+ String sayHello(String name);
+}
+```
+
+在 `GreetingsService` 中,定义了 `sayHi` 这个方法。后续服务端发布的服务,消费端订阅的服务都是围绕着
`GreetingsService` 接口展开的。
+
+### 5. 定义服务端的实现
+
+定义了服务接口之后,可以在服务端这一侧定义对应的实现,这部分的实现相对于消费端来说是远端的实现,本地没有相关的信息。
+
+
+
+在`dubbo-spring-boot-demo-provider` 模块的 `org.apache.dubbo.samples.provider` 下建立
`DemoServiceImpl` 类,定义如下:
+
+```java
+package org.apache.dubbo.springboot.demo.provider;
+
+import org.apache.dubbo.config.annotation.DubboService;
+import org.apache.dubbo.springboot.demo.DemoService;
+
+@DubboService
+public class DemoServiceImpl implements DemoService {
+
+ @Override
+ public String sayHello(String name) {
+ return "Hello " + name;
+ }
+}
+```
+
+在 `DemoServiceImpl` 中,实现了 `DemoService` 接口,对于 `sayHello` 方法返回 `Hello name`。
+
+注:在`DemoServiceImpl` 类中添加了 `@DubboService` 注解,通过这个配置可以基于 Spring Boot 去发布 Dubbo
服务。
+
+### 6. 配置服务端 Yaml 配置文件
+
+从本步骤开始至第 7 步,将会通过 Spring Boot 的方式配置 Dubbo 的一些基础信息。
+
+首先,我们先创建服务端的配置文件。
+
+
+
+在 `dubbo-spring-boot-demo-provider` 模块的 `resources` 资源文件夹下建立 `application.yml`
文件,定义如下:
+
+```yaml
+dubbo:
+ application:
+ name: dubbo-springboot-demo-provider
+ protocol:
+ name: dubbo
+ port: -1
+ registry:
+ address: zookeeper://${zookeeper.address:127.0.0.1}:2181
+```
+
+在这个配置文件中,定义了 Dubbo 的应用名、Dubbo 协议信息、Dubbo 使用的注册中心地址。
+
+### 7. 配置消费端 XML 配置文件
+
+同样的,我们需要创建消费端的配置文件。
+
+
+
+在 `dubbo-spring-boot-demo-consumer` 模块的 `resources` 资源文件夹下建立 `application.yml`
文件,定义如下:
+
+```yaml
+dubbo:
+ application:
+ name: dubbo-springboot-demo-consumer
+ protocol:
+ name: dubbo
+ port: -1
+ registry:
+ address: zookeeper://${zookeeper.address:127.0.0.1}:2181
+```
+
+在这个配置文件中,定义了 Dubbo 的应用名、Dubbo 协议信息、Dubbo 使用的注册中心地址。
+
+### 8. 基于 Spring 配置服务端启动类
+
+除了配置 Yaml 配置文件之外,我们还需要创建基于 Spring Boot 的启动类。
+
+首先,我们先创建服务端的启动类。
+
+
+
+在 `dubbo-spring-boot-demo-provider` 模块的
`org.apache.dubbo.springboot.demo.provider` 下建立 `Application` 类,定义如下:
+
+```java
+package org.apache.dubbo.springboot.demo.provider;
+
+import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+@EnableDubbo
+public class ProviderApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(ProviderApplication.class, args);
+ }
+}
+```
+
+在这个启动类中,配置了一个 `ProviderApplication` 去读取我们前面第 6 步中定义的 `application.yml`
配置文件并启动应用。
+
+### 9. 基于 Spring 配置消费端启动类
+
+同样的,我们需要创建消费端的启动类。
+
+
+
+在 `dubbo-spring-boot-demo-consumer` 模块的
`org.apache.dubbo.springboot.demo.consumer` 下建立 `Application` 类,定义如下:
+
+```java
+package org.apache.dubbo.springboot.demo.consumer;
+
+import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+@EnableDubbo
+public class ConsumerApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ConsumerApplication.class, args);
+ }
+}
+```
+
+在这个启动类中,配置了一个 `ConsumerApplication` 去读取我们前面第 7 步中定义的 `application.yml`
配置文件并启动应用。
+
+### 10. 配置消费端请求任务
+
+除了配置消费端的启动类,我们在 Spring Boot 模式下还可以基于 `CommandLineRunner`去创建
+
+
+
+在 `dubbo-spring-boot-demo-consumer` 模块的
`org.apache.dubbo.springboot.demo.consumer` 下建立 `Task` 类,定义如下:
+
+```java
+package org.apache.dubbo.springboot.demo.consumer;
+
+import java.util.Date;
+
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.apache.dubbo.springboot.demo.DemoService;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.stereotype.Component;
+
+@Component
+public class Task implements CommandLineRunner {
+ @DubboReference
+ private DemoService demoService;
+
+ @Override
+ public void run(String... args) throws Exception {
+ String result = demoService.sayHello("world");
+ System.out.println("Receive result ======> " + result);
+
+ new Thread(()-> {
+ while (true) {
+ try {
+ Thread.sleep(1000);
+ System.out.println(new Date() + " Receive result ======> "
+ demoService.sayHello("world"));
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ Thread.currentThread().interrupt();
+ }
+ }
+ }).start();
+ }
+}
+```
+
+在 `Task` 类中,通过`@DubboReference` 从 Dubbo 获取了一个 RPC 订阅,这个 `demoService`
可以像本地调用一样直接调用。在 `run`方法中创建了一个线程进行调用。
+
+### 11. 启动应用
+
+截止第 10 步,代码就已经开发完成了,本小节将启动整个项目并进行验证。
+
+
+
+首先是启动 `org.apache.dubbo.samples.provider.Application` ,等待一会出现如下图所示的日志(`Current
Spring Boot Application is await`)即代表服务提供者启动完毕,标志着该服务提供者可以对外提供服务了。
+
+```log
+[Dubbo] Current Spring Boot Application is await...
+```
+
+然后是启动`org.apache.dubbo.samples.client.Application` ,等待一会出现如下图所示的日志(`Hello
world` )即代表服务消费端启动完毕并调用到服务端成功获取结果。
+
+
+
+```log
+Receive result ======> Hello world
+```
+
+## 延伸阅读
+
+### 1. Dubbo 的 Spring 配置介绍
+
+Dubbo 的主要配置入口有 yaml 的配置内容、`@DubboReference` 和`@DubboService` 等,更多的细节可以参考
[Annotation 配置 | Apache
Dubbo](/zh-cn/docs3-v2/java-sdk/reference-manual/config/annotation/) 一文。
+
+## 更多
+
+本教程介绍了如何基于 Dubbo x Spring Boot 开发一个微服务应用。在下一节中,将介绍[另外一种 Dubbo 的配置方式 —— Dubbo x
Spring XML](../spring-xml/)。
diff --git a/content/zh-cn/overview/quickstart/java/spring-xml.md
b/content/zh-cn/overview/quickstart/java/spring-xml.md
new file mode 100644
index 0000000000..faef8bf039
--- /dev/null
+++ b/content/zh-cn/overview/quickstart/java/spring-xml.md
@@ -0,0 +1,393 @@
+---
+type: docs
+title: "4 - Dubbo x Spring XML 开发微服务应用"
+linkTitle: "Dubbo x Spring XML 开发微服务应用"
+weight: 4
+description: "本文将基于 Dubbo Samples 示例演示如何通过 Dubbo x Spring XML 快速开发微服务应用。"
+---
+
+## 目标
+
+从零上手开发基于 Dubbo x Spring XML 的微服务开发,了解 Dubbo x Spring XML 配置方式。
+
+## 难度
+
+低
+
+## 环境要求
+
+- 系统:Windows、Linux、MacOS
+
+- JDK 8 及以上(推荐使用 JDK17)
+
+- Git
+
+- IntelliJ IDEA(可选)
+
+- Docker (可选)
+
+## 快速部署(基于 Samples 直接启动)
+
+本章将通过几个简单的命令,一步一步教你如何部署并运行一个基于 Dubbo x Spring XML 的用例。
+
+注:本章部署的代码细节可以在 [apache/dubbo-samples](https://github.com/apache/dubbo-samples)
这个仓库中 `1-basic/dubbo-samples-spring-xml` 中找到,在下一章中也将展开进行讲解。
+
+### 1. 获取测试工程
+
+在开始整个教程之前,我们需要先获取测试工程的代码。Dubbo 的所有测试用例代码都存储在
[apache/dubbo-samples](https://github.com/apache/dubbo-samples)
这个仓库中,以下这个命令可以帮你获取 Samples 仓库的所有代码。
+
+```bash
+git clone --depth=1 --branch master [email protected]:apache/dubbo-samples.git
+```
+
+### 2. 启动一个简易的注册中心
+
+对于一个微服务化的应用来说,注册中心是不可或缺的一个组件。只有通过注册中心,消费端才可以成功发现服务端的地址信息,进而进行调用。
+
+为了让本教程更易于上手,我们提供了一个基于 Apache Zookeeper
注册中心的简易启动器,如果您需要在生产环境部署注册中心,请参考[生产环境初始化](/)一文部署高可用的注册中心。
+
+```bash
+Windows:
+./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper
+
+Linux / MacOS:
+./mvnw clean compile exec:java -pl tools/embedded-zookeeper
+
+Docker:
+docker run --name some-zookeeper -p 2181:2181 --restart always -d zookeeper
+```
+
+### 3. 启动服务提供者
+
+在启动了注册中心之后,下一步是启动一个对外提供服务的服务提供者。在 dubbo-samples 中也提供了对应的示例,可以通过以下命令快速拉起。
+
+```bash
+Windows:
+./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-spring-xml
-Dexec.mainClass="org.apache.dubbo.samples.provider.Application"
+
+Linux / MacOS:
+./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-spring-xml
-Dexec.mainClass="org.apache.dubbo.samples.provider.Application"
+
+注:需要开一个独立的 terminal 运行,命令将会保持一直执行的状态。
+```
+
+在执行完上述命令以后,等待一会出现如下所示的日志(`Dubbo Application[1.1](demo-provider) is
ready.`)即代表服务提供者启动完毕,标志着该服务提供者可以对外提供服务了。
+
+```log
+[08/02/23 03:26:52:052 CST]
org.apache.dubbo.samples.provider.Application.main() INFO
metadata.ConfigurableMetadataServiceExporter: [DUBBO] The MetadataService
exports urls :
[dubbo://30.221.128.96:20880/org.apache.dubbo.metadata.MetadataService?anyhost=true&application=demo-provider&background=false&bind.ip=30.221.128.96&bind.port=20880&connections=1&corethreads=2&delay=0&deprecated=false&dubbo=2.0.2&dynamic=true&executes=100&generic=false&getAndListenInstanceMetadata.1.callback=true&
[...]
+[08/02/23 03:26:52:052 CST]
org.apache.dubbo.samples.provider.Application.main() INFO
metadata.ServiceInstanceMetadataUtils: [DUBBO] Start registering instance
address to registry., dubbo version: 3.1.6, current host: 30.221.128.96
+[08/02/23 03:26:52:052 CST]
org.apache.dubbo.samples.provider.Application.main() INFO
metadata.MetadataInfo: [DUBBO] metadata revision changed: null ->
602d44cc6d653b9cd42ab23c3948b5ab, app: demo-provider, services: 1, dubbo
version: 3.1.6, current host: 30.221.128.96
+[08/02/23 03:26:52:052 CST]
org.apache.dubbo.samples.provider.Application.main() INFO
deploy.DefaultApplicationDeployer: [DUBBO] Dubbo
Application[1.1](demo-provider) is ready., dubbo version: 3.1.6, current host:
30.221.128.96
+```
+
+### 4. 启动服务消费者
+
+最后一步是启动一个服务消费者来调用服务提供者,也即是 RPC 调用的核心,为服务消费者提供调用服务提供者的桥梁。
+
+```bash
+Windows:
+./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-spring-xml
-Dexec.mainClass="org.apache.dubbo.samples.client.Application"
+
+Linux / MacOS:
+./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-spring-xml
-Dexec.mainClass="org.apache.dubbo.samples.client.Application"
+```
+
+在执行完上述命令以后,等待一会出现如下所示的日志(`hi, dubbo`),打印出的数据就是服务提供者处理之后返回的,标志着一次服务调用的成功。
+
+```log
+[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
+Receive result ======> hi, dubbo
+```
+
+## 动手实践(从零代码开发版)
+
+本章将通过手把手的教程一步一步教你如何从零开发一个微服务应用。
+
+### 1. 启动注册中心
+
+对于一个微服务化的应用来说,注册中心是不可或缺的一个组件。只有通过注册中心,消费端才可以成功发现服务端的地址信息,进而进行调用。
+
+为了让本教程更易于上手,我们提供了一个基于 Apache Zookeeper
注册中心的简易启动器,如果您需要在生产环境部署注册中心,请参考[生产环境初始化](/)一文部署高可用的注册中心。
+
+```bash
+Windows:
+git clone --depth=1 --branch master [email protected]:apache/dubbo-samples.git
+cd dubbo-samples
+./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper
+
+Linux / MacOS:
+git clone --depth=1 --branch master [email protected]:apache/dubbo-samples.git
+cd dubbo-samples
+./mvnw clean compile exec:java -pl tools/embedded-zookeeper
+
+Docker:
+docker run --name some-zookeeper -p 2181:2181 --restart always -d zookeeper
+```
+
+### 2. 初始化项目
+
+从本小节开始,将基于 IntelliJ IDEA 进行工程的搭建以及测试。
+
+
+
+如上图所示,可以建立一个基础的项目。
+
+
+
+在初始化完项目之后,需要在 `src/main/java` 目录下创建 `org.apache.dubbo.samples.api`
、`org.apache.dubbo.samples.client` 和 `org.apache.dubbo.samples.provider` 三个
package。
+
+后续我们将在 `api` 下创建对应的接口,在 `client` 下创建对应客户端订阅服务的功能,在 `provider`
下创建对应服务端的实现以及发布服务的功能。
+
+上述三个 package 分别对应了应用共同依赖的 api、消费端应用的模块、服务端应用的模块。在实际部署中需要拆成三个工程,消费端和服务的共同依赖 api
模块。从简单出发,本教程将在同一个工程中进行开发,区分多个启动类。
+
+### 3. 添加 Maven 依赖
+
+在初始化完项目以后,我们需要先添加 Dubbo 相关的 maven 依赖。
+
+
+
+编辑 `pom.xml` 这个文件,添加下列配置。
+
+```xml
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo</artifactId>
+ <version>3.1.6</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ <version>5.3.25</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.curator</groupId>
+ <artifactId>curator-x-discovery</artifactId>
+ <version>5.2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.zookeeper</groupId>
+ <artifactId>zookeeper</artifactId>
+ <version>3.8.0</version>
+ </dependency>
+ </dependencies>
+```
+
+在这份配置中,定义了 dubbo 和 zookeeper(以及对应的连接器 curator)的依赖。
+
+
+
+添加了上述的配置以后,可以通过 IDEA 的 `Maven - Reload All Maven Projects` 刷新依赖。
+
+### 4. 定义服务接口
+
+服务接口 Dubbo 中沟通消费端和服务端的桥梁。
+
+
+
+在 `org.apache.dubbo.samples.api` 下建立 `GreetingsService` 接口,定义如下:
+
+```java
+package org.apache.dubbo.samples.api;
+
+public interface GreetingsService {
+
+ String sayHi(String name);
+}
+```
+
+在 `GreetingsService` 中,定义了 `sayHi` 这个方法。后续服务端发布的服务,消费端订阅的服务都是围绕着
`GreetingsService` 接口展开的。
+
+### 5. 定义服务端的实现
+
+定义了服务接口之后,可以在服务端这一侧定义对应的实现,这部分的实现相对于消费端来说是远端的实现,本地没有相关的信息。
+
+
+
+在 `org.apache.dubbo.samples.provider` 下建立 `GreetingsServiceImpl` 类,定义如下:
+
+```java
+package org.apache.dubbo.samples.provider;
+
+import org.apache.dubbo.samples.api.GreetingsService;
+
+public class GreetingsServiceImpl implements GreetingsService {
+ @Override
+ public String sayHi(String name) {
+ return "hi, " + name;
+ }
+}
+```
+
+在 `GreetingsServiceImpl` 中,实现了 `GreetingsService` 接口,对于 `sayHi` 方法返回 `hi,
name`。
+
+### 6. 配置服务端 XML 配置文件
+
+从本步骤开始至第 7 步,将会通过 Spring XML 的方式配置 Dubbo 服务的信息。
+
+首先,我们先创建服务端的配置文件。
+
+
+
+在 `resources` 资源文件夹下建立 `dubbo-demo-provider.xml` 文件,定义如下:
+
+```xml
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
+ xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
+ 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">
+ <context:property-placeholder/>
+
+ <!-- 定义应用名 -->
+ <dubbo:application name="demo-provider"/>
+
+ <!-- 定义注册中心地址 -->
+ <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
+
+ <!-- 定义实现类对应的 bean -->
+ <bean id="greetingsService"
class="org.apache.dubbo.samples.provider.GreetingsServiceImpl"/>
+ <!-- 定义服务信息,引用上面的 bean -->
+ <dubbo:service interface="org.apache.dubbo.samples.api.GreetingsService"
ref="greetingsService"/>
+
+</beans>
+```
+
+在这个配置文件中,定义了 Dubbo 的应用名、Dubbo 使用的注册中心地址、发布服务的 spring bean 以及通过 Dubbo 去发布这个
bean。
+
+### 7. 配置消费端 XML 配置文件
+
+同样的,我们需要创建消费端的配置文件。
+
+
+
+在 `resources` 资源文件夹下建立 `dubbo-demo-consumer.xml` 文件,定义如下:
+
+```xml
+<?xml version="1.0" encoding="UTF-8"?>
+
+<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
+ xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
+ 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">
+ <context:property-placeholder/>
+
+ <!-- 定义应用名 -->
+ <dubbo:application name="demo-provider"/>
+
+ <!-- 定义注册中心地址 -->
+ <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
+
+ <!-- 定义订阅信息,Dubbo 会在 Spring Context 中创建对应的 bean -->
+ <dubbo:reference id="greetingsService"
interface="org.apache.dubbo.samples.api.GreetingsService"/>
+
+</beans>
+```
+
+在这个配置文件中,定义了 Dubbo 的应用名、Dubbo 使用的注册中心地址、订阅的服务信息。
+
+### 8. 基于 Spring 配置服务端启动类
+
+除了配置 XML 配置文件之外,我们还需要创建基于 Spring Context 的启动类。
+
+首先,我们先创建服务端的启动类。
+
+
+
+在 `org.apache.dubbo.samples.provider` 下建立 `Application` 类,定义如下:
+
+```java
+package org.apache.dubbo.samples.provider;
+
+import java.util.concurrent.CountDownLatch;
+
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+public class Application {
+
+ public static void main(String[] args) throws InterruptedException {
+ ClassPathXmlApplicationContext context = new
ClassPathXmlApplicationContext("dubbo-demo-provider.xml");
+ context.start();
+
+ // 挂起主线程,防止退出
+ new CountDownLatch(1).await();
+ }
+}
+```
+
+在这个启动类中,配置了一个 `ClassPathXmlApplicationContext` 去读取我们前面第 6 步中定义的
`dubbo-demo-provider.xml` 配置文件。
+
+### 9. 基于 Spring 配置消费端启动类
+
+同样的,我们需要创建消费端的启动类。
+
+
+
+在 `org.apache.dubbo.samples.client` 下建立 `Application` 类,定义如下:
+
+```java
+package org.apache.dubbo.samples.client;
+
+import java.io.IOException;
+
+import org.apache.dubbo.samples.api.GreetingsService;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+public class Application {
+ public static void main(String[] args) throws IOException {
+ ClassPathXmlApplicationContext context = new
ClassPathXmlApplicationContext("dubbo-demo-consumer.xml");
+ context.start();
+ GreetingsService greetingsService = (GreetingsService)
context.getBean("greetingsService");
+
+ String message = greetingsService.sayHi("dubbo");
+ System.out.println("Receive result ======> " + message);
+ System.in.read();
+ System.exit(0);
+ }
+
+}
+```
+
+在这个启动类中,主要执行了三个功能:
+
+1. 配置了一个 `ClassPathXmlApplicationContext` 去读取我们前面第 7 步中定义的
`dubbo-demo-consumer.xml` 配置文件
+
+2. 从 Spring Context 中获取名字为 `greetingsService` 的由 Dubbo 创建的 bean
+
+3. 通过这个 bean 对远端发起调用
+
+### 10. 启动应用
+
+截止第 9 步,代码就已经开发完成了,本小节将启动整个项目并进行验证。
+
+
+
+首先是启动 `org.apache.dubbo.samples.provider.Application` ,等待一会出现如下图所示的日志(`Dubbo
Application[1.1](demo-provider) is ready`)即代表服务提供者启动完毕,标志着该服务提供者可以对外提供服务了。
+
+```log
+[DUBBO] Dubbo Application[1.1](demo-provider) is ready., dubbo version: 3.1.6,
current host: 30.221.128.96
+```
+
+然后是启动`org.apache.dubbo.samples.client.Application` ,等待一会出现如下图所示的日志(`hi, dubbo`
)即代表服务消费端启动完毕并调用到服务端成功获取结果。
+
+
+
+```log
+Receive result ======> hi, dubbo
+```
+
+## 延伸阅读
+
+### 1. Dubbo 的 XML 配置介绍
+
+Dubbo 的主要配置入口有`dubbo:application` 、`dubbo:registry` 、 `dubbo:reference` 和
`dubbo:service` 等,更多的细节可以参考 [XML 配置 | Apache
Dubbo](/zh-cn/docs3-v2/java-sdk/reference-manual/config/xml/) 一文。
+
+## 更多
+
+本教程介绍了如何基于 Dubbo x Spring XML 开发一个微服务应用。至此,Dubbo 基于 API、Spring Boot、Spring XML
三种主要的启动方式都已经介绍完毕。
+
+在下一节中,将介绍[基于 Protobuf IDL 配置的微服务开发方式](../idl/)。
diff --git a/data/i18n/zh/zh.toml b/data/i18n/zh-cn/zh.toml
similarity index 100%
rename from data/i18n/zh/zh.toml
rename to data/i18n/zh-cn/zh.toml
diff --git a/i18n/zh.toml b/i18n/zh-cn.toml
similarity index 100%
rename from i18n/zh.toml
rename to i18n/zh-cn.toml