SpringCloud笔记——2.创建微服务项目和服务注册、发现、编写微服务api
通过进行学习,记录笔记。
通过尚硅谷2025最新SpringCloud教程视频进行学习,记录笔记
步骤一 ——对应视频第四集(创建微服务项目)
-
首先,创建Spring Boot项目,Type选择maven,jdk选择java17

-
再根据视频步骤做,最后得到项目结构为

配置文件参考:
pom.xml(cloud-demo):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<packaging>pom</packaging>
<modules>
<module>services</module>
</modules>
<groupId>com.cg</groupId>
<artifactId>cloud-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>study-cloud</name>
<description>study-cloud</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-cloud.version>2023.0.3</spring-cloud.version>
<spring-cloud-alibaba.version>2023.0.3.2</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
pom.xml(services):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.cg</groupId>
<artifactId>cloud-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<packaging>pom</packaging>
<modules>
<module>service-product</module>
<module>service-order</module>
</modules>
<artifactId>services</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- 服务发现/注册中心-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 远程调用-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
</project>
步骤二——安装启动nacos
打开nacos文件夹,在bin文件夹里cmd打开命令提示符,输入startup.cmd -m standalone单机模式启动nacos,在浏览器网址栏输入localhost:8848/nacos打开nacos管理器
步骤三——nacos-注册中心-服务注册-对应第六集
- 在service-order模块中配置pom,用dependencies标签编辑启动器加入Spring Web

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
由于在services模块里引入了服务发现依赖(alibaba-nacos-discovery),所以order模块配置文件不需要再导入
-
在order里java文件夹里编写一个主程序(OrdeMainApplication)来启动微服务,创建java类(com.cg.order.OrdeMainApplication).

-
创建完后写上@SpringBootApplication注解代表这是个Spring Boot 应用
-
使用SpringApplication.run(OrdeMainApplication.class, args); run让应用跑起来,传入主程序和args参数。
-
在resources文件夹创建配置文件application.properties,写上spring应用名字(项目名)、应用启动占用的端口号和nacos服务器地址(用来把项目注册到注册中心)
Spring.application.name=service-order
server.port=8000
spring.cloud.nacos.server-addr=127.0.0.1:8848
-
运行主程序。在nacos服务管理-服务列表中发现service-order即为成功
-
service-product 重复该操作即可

-
在IDEA服务中可以复制配置,复制一个微服务出来(不知道为啥我的ProductMainApplicaton没显示出来,但是后面重新运行下就有了)

-
在编辑配置中修改选项选择Program arguments(程序实参),写上==–server.port=8001==修改微服务的端口(因为不能重复)。

-
修改完后应用,运行后到nacos查询即可

搞定!
步骤四——服务发现-对应第七集

- 商品服务为例,在主程序中加入注解@EnableDiscoveryClient(开启服务发现功能)
- 再到test-java新建一个测试类com.cg.product.DiscoveryTest
- 在pom里用dependency添加测试依赖spring-boot-starter-test且让他只在测试范围生效
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<!-- 生效范围-->
- 在DiscoveryTest加入注解@SpringBootTest
- 因为DiscoveryClient提供了服务发现的api,那我们把他自动注入即可
package com.cg.product;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import java.util.List;
@SpringBootTest
public class DiscoveryTest {
//@Autowired 注解是Spring框架的一部分,用于自动装配(自动注入)Spring Bean到其他Bean中。它的主要作用是帮助我们消除手动配置Bean依赖关系的繁琐工作,使代码更加简洁和可维护
@Autowired
DiscoveryClient discoveryClient;
@Test
void discoveryClientTest() {
for (String service : discoveryClient.getServices()) {
//获取微服务的名字
System.out.println("service = "+service);
//获取ip+port getInstances获取实例
List<ServiceInstance> instances = discoveryClient.getInstances(service);
for (ServiceInstance instance : instances) {
System.out.println("ip = "+instance.getHost()+" port = "+instance.getPort());
}
}
}
}
-
运行后获取微服务名称以及ip和端口号

-
用过DiscoveryClient,我们接着引入NacosServiceDiscovery,他们两个的区别是DiscoveryClient是Spring家的标准规范,无论用哪个注册中心都能调用这个api。NacosServiceDiscovery是只有引入Nacos时才能用的api,这两个测试代码基本一样,输出结果也一样
package com.cg.product;
import com.alibaba.cloud.nacos.discovery.NacosServiceDiscovery;
import com.alibaba.nacos.api.exception.NacosException;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import java.util.List;
@SpringBootTest
public class DiscoveryTest {
@Autowired
DiscoveryClient discoveryClient;
@Autowired
NacosServiceDiscovery nacosServiceDiscovery;
@Test
void discoveryClientTest() {
for (String service : discoveryClient.getServices()) {
//获取微服务的名字
System.out.println("service = "+service);
//获取ip+port getInstances获取实例
List<ServiceInstance> instances = discoveryClient.getInstances(service);
for (ServiceInstance instance : instances) {
System.out.println("ip = "+instance.getHost()+" port = "+instance.getPort());
}
}
}
//NacosServiceDiscovery部分
@Test
void nacosServiceDiscoveryTest() throws NacosException {
for (String service : nacosServiceDiscovery.getServices()) {
System.out.println("service = "+service);
List<ServiceInstance> instances = nacosServiceDiscovery.getInstances(service);
for (ServiceInstance instance : instances) {
System.out.println("ip = "+instance.getHost()+" port = "+instance.getPort());
}
}
}
}
[!NOTE] @Autowired
@Autowired 注解是Spring框架的一部分,用于自动装配(自动注入)Spring Bean到其他Bean中。它的主要作用是帮助我们消除手动配置Bean依赖关系的繁琐工作,使代码更加简洁和可维护。通过使用@Autowired注解,我们可以轻松地将一个Bean注入到另一个Bean中,而无需手动创建实例或者进行繁琐的配置。
@Autowired 注解为项目提供了以下优势:
- 减少了手动配置Bean之间的依赖关系的工作,提高了开发效率。
- 降低了代码的耦合度,使得代码更容易测试和维护。
- 提供了一种声明式的方式来定义Bean之间的依赖关系,增强了代码的可读性。
步骤五——编写微服务-第八集
-
远程调用基本流程

-
仿照远程调用-下单场景编写微服务
-
在商品模块com.cg.product包中创建java类controller.ProductController用来查询商品,标注SpringMVC 的@RestController注解让他能接受请求
package com.cg.product.controller;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ProductController {
//查询商品
public void getProduct(Long productId) {
}
}
- 在com.cg.product包中创建javabean来封装数据,新建java类bean.Product,并且在services模块的pom中导入lombok简化java bean开发(可以在编辑启动器中直接选择)。
[!NOTE] Lombok
Lombok的核心作用是通过注解自动生成常见的Java类功能,简化开发流程,使得代码更加简洁且易于维护。
package com.cg.product.bean;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class Product {
private Long id;
private BigDecimal price;
private String ProductName;
private int num;
}
- 再回去修改ProductController
package com.cg.product.controller;
import com.cg.product.bean.Product;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ProductController {
//查询商品
public Product getProduct(Long productId) {
return null;
}
}
- 商品的Controller调用商品的service,根据id获取到商品数据,所以这时候我们编写商品的service。先在com.cg.product包下创建service接口service.ProductService,再在service包下编写实现类impl.ProductServiceImpl,并把该实现类放入容器中(@Service)
package com.cg.product.service.impl;
import com.cg.product.service.ProductService;
import org.springframework.stereotype.Service;
@Service
public class ProductServiceImpl implements ProductService {
}
- Controller查询商品需要调用商品的service,所以接下来修改ProductController
package com.cg.product.controller;
import com.cg.product.bean.Product;
import com.cg.product.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ProductController {
@Autowired
ProductService productService;
//查询商品
@GetMapping("/product/{id}")
public Product getProduct(@PathVariable("id") Long productId) {
//productId是路径变量,注解@PathVariable
Product product = productService.getProductById(productId);
return product;
}
}
[!NOTE] @RestController
@RestController表示该类是一个控制器,并且返回的结果会直接以 JSON 等形式返回给客户端,而不是解析为视图。
[!NOTE] @RequestMapping(“/user/{id}”)
@RequestMapping("/user/{id}")映射 URL 路径,当客户端发起形如http://localhost:8080/user/123的请求时,会匹配到这个方法。
[!NOTE] @PathVariable
@PathVariable Long id注解将 URL 中{id}占位符的值提取出来,并将其转换为Long类型,赋值给方法参数id,后续就可以根据这个参数值进行业务处理,比如查询数据库获取对应的用户信息。
- 由于getProductById是还未创建的方法,alt enter在ProductService里创建该方法,再到实现类ProductService里alt enter添加实现,new一个product对象,用GenerateAllSetter插件快速生成set方法并修改细节。
package com.cg.product.service.impl;
import java.math.BigDecimal;
import com.cg.product.bean.Product;
import com.cg.product.service.ProductService;
import org.springframework.stereotype.Service;
@Service
public class ProductServiceImpl implements ProductService {
@Override
public Product getProductById(Long productId) {
Product product = new Product();
product.setId(productId);
product.setPrice(new BigDecimal("199"));
product.setProductName("威士忌-"+productId);
product.setNum(2);
return product;
}
}
- 完成后运行ProductMainApplication,打开任一端口,在后面加上product/任意数字,比如localhost:9000/product/3,得到

成功!
- 接下来,用户想要给订单功能发送请求,做法跟刚刚一样。照视频做即可。代码参考:
controller-OrderController:
package com.cg.order.controller;
import com.cg.order.bean.Order;
import com.cg.order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class OrderController {
@Autowired
OrderService orderService;
//创建订单
//请求映射的路径
@GetMapping("/create")
public Order createOrder(@RequestParam("userId") Long userId,
@RequestParam("productId") Long productId){
Order order = orderService.createOrder(productId, userId);
return order;
}
}
bean-Order:
package com.cg.order.bean;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
@Data
public class Order {
private Long id;
private BigDecimal totalAmount;
private Long userId;
private String nickName;
private String address;
private List<Objects> productList;
}
service-OrderService接口:
package com.cg.order.service;
import com.cg.order.bean.Order;
public interface OrderService {
Order createOrder(Long productId, Long userId);
}
service-impl-OrderServiceImpl:
package com.cg.order.service.impl;
import java.math.BigDecimal;
import com.cg.order.bean.Order;
import com.cg.order.service.OrderService;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RestController;
@Service
public class OrderServiceImpl implements OrderService {
@Override
public Order createOrder(Long productId, Long userId) {
Order order = new Order();
order.setId(1L);
//TODO 总金额
order.setTotalAmount(new BigDecimal("0"));
order.setUserId(userId);
order.setNickName("chenguo");
order.setAddress("泉州");
//TODO 远程查询商品列表
order.setProductList(null);
return order;
}
}
- 别忘了在OrderApplication主程序里加上注释@EnableDiscoveryClient
- 这里的OrderController不同,访问的url要加入userId和productId,如http://localhost:8000/create?userId=2&productId=100
- 最后运行,因为这里暂不涉及远程调用,所以用返回null代替

成功!
更多推荐



所有评论(0)