项目源码:https://gitee.com/zhangchouchou/spring-cloud-demo
后文链接:https://blog.csdn.net/weixin_42547014/article/details/120334570
一、前言
1. 基本认识
- 掌握 spring cloud 的前提是掌握好 spring boot。
- spring cloud 中的子模块一般使用 spring boot 实现
- spring cloud 的版本和 spring boot 有对应关系,可以在 spring 官网查看对应关系。
- spring cloud 项目中分为父工程和子模块,父工程主要做 jar 包的版本控制,子模块 jar 包的引用通过父模块来控制,并通过模块之间互相调用实现业务功能。
2. spring cloud 项目创建流程
-
创建父工程
建议采用 maven 方式创建,这样可以控制 spring boot 的版本。比如应该使用的 spring boot 的版本是 2.3,而自动创建的时候最低版本只能选择到 2.4。 -
创建子模块
根据业务需求,创建子模块。项目构建的过程中一定会经历工程重构的过程。创建项目的流程就是先实现功能,再进行工程优化和重构。
以下为创建 spring cloud 项目的一个简单例子
二、创建父工程
1.创建项目
2.调整配置
创建完成后需要对IDEA进行一些设置
激活注解
过滤无用文件
添加 *idea
和 *iml
字符编码
字符编码都调整为 UTF-8
调整JDK
我用的是 JDK11
3. 修改pom文件,定义为父工程
添加 <packaging>pom</packaging>
4. 删除src文件夹
5. 简单配置pom文件
<?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>
<groupId>org.zjh.springclouddemo</groupId>
<artifactId>SpringCloudDemo</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>cloud-provider-payment8001</module>
</modules>
<packaging>pom</packaging>
<!-- 统一管理jar包版本 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<junit.version>4.13.1</junit.version>
<log4j.version>1.2.17</log4j.version>
<lombok.version>1.18.12</lombok.version>
<mysql.version>8.0.25</mysql.version>
<druid.version>1.2.6</druid.version>
<mybatis.spring.boot.version>2.1.4</mybatis.spring.boot.version>
</properties>
<!-- 子模块继承之后,提供作用:锁定版本+子module不用写groupId和version -->
<dependencyManagement>
<dependencies>
<!-- spring boot 2.3.12 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.12.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring cloud Hoxton.SR12 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR12</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring cloud 阿里巴巴 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- druid 因jdk11有兼容问题,会报错,所以去除-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
<exclusions>
<exclusion>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun</groupId>
<artifactId>jconsole</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.spring.boot.version}</version>
</dependency>
<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<!-- log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<optional>true</optional>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.12.RELEASE</version>
<configuration>
<fork>true</fork>
<additionalProperties>true</additionalProperties>
</configuration>
</plugin>
</plugins>
</build>
</project>
查看springCloud和springBoot版本对应关系
配置的时候,SpringBoot 和 SpringCloud 的版本需要对应上,查看版本对应的方式如下:
进入官网
GA代表稳定版
若
org.springframework.boot
报错,如下所示:
解决方式:添加上SpringBoot版本号即可
<version>2.3.12.RELEASE</version>
三、创建服务提供者
1. 创建子模块
注:创建子模块命名格式为模块功能+端口号
创建方式选择maven,因为使用spring initializr创建在版本选择部分可能没有对应的spring boot版本
该模块为服务提供模块
2. 在 pom 文件中引包
<?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">
<parent>
<artifactId>SpringCloudDemo</artifactId>
<groupId>org.zjh.springclouddemo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-provider-payment8001</artifactId>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!--小辣椒-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
lombok介绍
lombok(小辣椒),自动创建实体类中的 get/set 等方法,以及有参和无参构造函数,使代码更加简洁
常用注解:
- @Data ——> 自动构建get、set方法
- @AllArgsConstructor ——> 全属性构造函数
- @NoArgsConstructor ——> 无参构造函数
3. 创建配置文件 YML
创建 application.yml
配置文件
4. 添加配置内容
server:
port: 8001
spring:
application:
name: cloud-payment-service
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/s_c_d?userUnicode=true&characterEncoding=utf-8&userSSL=false
username: root
password: root
mybatis:
# mapper-locations: classpath:/mapper/*.xml
type-aliases-package: org.zjh.provider.entities
5. 创建启动类
@SpringBootApplication
public class HelloSpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(HelloSpringBootApplication.class,args);
}
}
6. 创建实体类
新建 entities
/**
* @Data 是 pom 中引用的 lombok 中的注解,用来实现 get/set方法等
* @AllArgsConstructor 有参构造函数
* @NoArgsConstructor 无参构造函数
**/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private Integer id;
private String name;
private String phone;
private String sex;
}
7. 创建 Json 封装体 CommonResult
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult<T> implements Serializable {
private Integer code;
private String message;
private T data;
public CommonResult(Integer code,String message){
this(code,message,null); //报错需要安装lombok插件
}
}
lombok插件安装
安装成功后重启 Idea
需要注意的是,一旦启用lombok插件,那么团队中其他成员也必须安装此插件,否则会编译报错。
8. 创建 mapper、Service、Controller
UserMapper.java
@Mapper
public interface UserMapper {
@Select("select * from user where id = #{id}")
public User getByID(@Param("id")Integer id);
@Insert("insert into user values(default,#{name},#{phone},#{sex})")
public int addByUser(User user);
}
UserController.java
@RestController
@Slf4j
public class UserController {
@Autowired
private UserService usersvice;
@GetMapping("/user/get/{id}")
public CommonResult<User> getByID(@PathVariable("id")Integer id){
User user = usersvice.getByID(id);
log.info("******* 查询结果 *******" + user);
if(user != null){
return new CommonResult(200,"查询成功",user);
}else{
return new CommonResult(444,"没有记录,查询ID:" + id,null);
}
}
@PostMapping("/user/addByUser")
public CommonResult<User> addByUser(@RequestBody User user){
boolean boo = usersvice.addByUser(user);
log.info("******* 添加结果 *******" + boo);
if(boo){
return new CommonResult(200,"添加成功",boo);
}else{
return new CommonResult(444,"添加失败",boo);
}
}
}
目录结构:
测试:
四、创建消费者
消费者模块的创建流程与服务提供者流程类似,不再赘述,需要注意的是模块的包名尽量保持相同,这样在项目重构的时候不会因引包问题导致项目报错。
1. 修改pom文件
因该模块是消费者,所以不需要添加 mybatis 和 mysql 等内容。
<?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">
<parent>
<artifactId>SpringCloudDemo</artifactId>
<groupId>org.zjh.springclouddemo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-consumer-order80</artifactId>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!--小辣椒-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
2. 配置 yml
同理,yml中也不需要包含数据库连接等配置
server:
port: 80
spring:
application:
name: cloud-consumer-order80
3. 创建远程访问 RestTemplate
RestTemplate提供了多种便捷访问http服务的方法,是Spring提供用于访问 Rest 服务的客户端模板工具集
即:模块间的远程调用
请求参数分别为:url(请求地址) , requestMap(请求参数) , ResponseBean.class(Http响应转换被转换成的对象类型)
创建 config 配置类:ApplicationContextConfig.java
@SpringBootConfiguration
public class ApplicationContextConfig {
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
4. 创建controller
先将服务提供者的实体类(entities)复制到该模块,然后创建Controller
@RestController
@Slf4j
public class OrderController {
public static final String PAYMENT_URL = "http://localhost:8001";
@Resource
private RestTemplate restTemplate;
@PostMapping("/consumer/user/addByUser")
public CommonResult<User> addByUser(User user){
return restTemplate.postForObject(PAYMENT_URL + "/user/addByUser",user,CommonResult.class);
}
@GetMapping("/consumer/user/get/{id}")
public CommonResult<User> getByID(@PathVariable("id")Integer id){
return restTemplate.getForObject(PAYMENT_URL + "/user/get/" + id,CommonResult.class);
}
}
项目结构:
5. 启动服务并测试
注:先启动服务提供者,再启动消费者
以获取数据为例,访问消费者的80端口
五、工程重构
工程重构是项目创建过程中一定会经历的过程,创建项目的流程就是先实现功能,再进行工程优化和重构。
截止到目前,该项目就出现了一些问题 —— 实体类重复。
每个模块中都有重复的实体类,现在仅仅是数据库中的一张表和两个模块,多了以后简直无法想象。
所以进行工程重构,将实体类提出来,使其不再重复。
1. 创建实体类模块,修改pom
将模块命名为 cloud-api-commons
,依旧是Maven项目,修改pom
<?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">
<parent>
<artifactId>SpringCloudDemo</artifactId>
<groupId>org.zjh.springclouddemo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-api-commons</artifactId>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 糊涂工具包 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.11</version>
</dependency>
</dependencies>
</project>
hutool介绍
hutool官网地址
是一个封装好的小工具包,包括日期、配置文件、日志等,非常小巧方便
2. 创建项目包
创建包名与其余模块的包名相同,创建好后将实体类复制过来
复制完成后,将另外两个模块的 entities 删除。
3. 在 pom 中将引入模块
在各个模块的 pom 中引入 API 模块
<dependency>
<groupId>org.zjh.springclouddemo</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
若引入后报错
选择 Maven -> cloud-api-commons -> Lifecycle -> install 即可
4. 重启服务进行检验
工程重构完成。