1--SpringCloud周阳老师

2021:1--SpringCloud

https://www.cnblogs.com/coderD/p/14350076.html SpringCloud

https://www.cnblogs.com/coderD/p/14350073.html SpringCloud 和 Eureka

https://www.cnblogs.com/coderD/p/14350082.html SpringCloud 和 Zookeeper

https://www.cnblogs.com/coderD/p/14350086.html SpringCloud-Ribbon/OpenFeign

https://www.cnblogs.com/coderD/p/14350091.html SpringCloud:Hystrix 断路器

https://www.cnblogs.com/coderD/p/14350097.html SpringCloud:服务网关 gateway

https://www.cnblogs.com/coderD/p/14350099.html SpringCloud:Config/Bus

https://www.cnblogs.com/coderD/p/14350103.html SpringCloud:Stream/Sleuth

https://www.cnblogs.com/coderD/p/14350110.html SpringCloud Alibaba:Nacos

https://www.cnblogs.com/coderD/p/14350114.html SpringCloud Alibaba:Sentinel

https://www.cnblogs.com/coderD/p/14350119.html SpringCloud Alibaba:Seata

代码:https://gitee.com/xue--dong/spring-cloud

阳哥脑图:https://gitee.com/xue--dong/spring-cloud

Cloud-Boot 兼容性

img

4.  更详细的版本对应查看方法
复制代码

内容是 json 串,找在线工具解析

img

img

    不仅有Cloud和Boot的选择约束,还有其他。
复制代码

img

img

5.  最终选择

    cloud               Hoxton.SR1
    boot                2.2.2.RELEASE
    cloud alibaba       2.1.0.RELEASE
    JAVA                JAVA8
    Maven               3.5及以上
    Mysql               5.7及以上
    
    boot最新版已经到2.4.x了,为什么用2.2.2呢?
    需要照顾到cloud,由cloud来选择boot的版本。
复制代码

支持依赖

img

6.  参考资料
复制代码

SpringCloud

cloud 中文

springboot

1 父工程

1.1 父工程环境

1.  父工程
复制代码

img

2.  工程名
复制代码

img

3.  字符编码
复制代码

img

4.  注解生效激活
复制代码

img

5.  java编译版本 1.8
复制代码

img

6.  File Type过滤
复制代码

img

得到效果:

img

1.2 父工程 POM:

此处只是约定了下子工程引入依赖时的版本号。
如果不想用这个版本,子模块可以自行决定,也不行加别的依赖。

1.  <packaging>pom</packaging>
复制代码

img

2.  删掉src等文件夹,只留一个pom.xml
复制代码

img

3.  dependencyManagement和dedependencies

    1.  <dependencyManagement>:
    
    Maven使用dependencyManagement元素来提供一管理依赖版本号的方式。
    通常会在一个组织或者项目的最顶层POM中看到dependencyManagement元素。
    
    使用pom.xml中的dependencyManagement元素能让所有在子项目中引用一个依赖而不用显式
    的列出版本号。
    
    Maven会沿着父子层次向上走,直到找到一个拥有dependencyManagement元素的项目,然后
    它就会使用这个dependencyManagement元素中指定的版本号,
    
    即:一般用在父工程,子模块继承之后,提供作用:锁定版本+子module不用写groupId和version
    
    例如在父项目中:
复制代码
     <dependencyManagement>
        <dependencies>
          <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.2</version>
          </dependency>
          ...
        </dependencies>
    </dependencyManagement>

复制代码
    在子项目里就可以添加mysql-connector-java时可以不指定版本号,例如:
复制代码
     <dependencyManagement>
        <dependencies>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependencies>
    </dependencyManagement>
复制代码
    这样做的好处就是:如果有多个子项目都引用同一样的依赖,则可以避免在每个使用的子项目里都声明
    一个版本号,这样当想升级或切换到另一个版本时只需在顶层改即可,就很方便。
    如果某个子项目需要另外的一个版本,只需单独声明version即可。
复制代码

注意:dependencyManagement 里只是声明依赖,并不实现引入,因此子项目需要显示的声明去要用的依赖。子项目没有指定版本号时,才会从父项目处继承依赖。

4.  Maven中跳过单元测试
    
    跳过maven生命周期的test阶段(为了节省时间)。
复制代码

img

5.  父工程创建完成执行mvn:install将父工程发布到仓库方便子工程继承。

    注意:mysql-connector-java与Mysql、Java的对应版本
复制代码
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
复制代码

img

    所以MySQL我重新安装了一个5.7的版本
    <mysql.version>8.0.18</mysql.version>
复制代码
  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>com.atguigu.springcloud</groupId>
  <artifactId>cloud2020</artifactId>
  <version>1.0-SNAPSHOT</version>
  <!--这是一个总的maven父工程-->
  <packaging>pom</packaging>

  <!--统一管理jar包版本-->
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <junit.version>4.12</junit.version>
    <log4j.version>1.2.17</log4j.version>
    <lombok.version>1.18.10</lombok.version>
    <mysql.version>8.0.18</mysql.version>
    <druid.version>1.1.16</druid.version>
    <mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
  </properties>

  <!--子模块继承之后,提供作用:锁定版本+子module不用写groupId和version-->
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-project-info-reports-plugin</artifactId>
        <version>3.0.0</version>
      </dependency>
      <!--spring boot 2.2.2-->
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>2.2.2.RELEASE</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <!--spring cloud Hoxton.SR1-->
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>Hoxton.SR1</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>
        <scope>runtime</scope>
      </dependency>
      <!-- druid-->
      <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>${druid.version}</version>
      </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>
    </dependencies>

  </dependencyManagement>

</project>
复制代码

2 Rest 微服务工程构建

    1.  建module
    2.  改pom
    3.  写yml
    4.  主启动
    5.  业务类
复制代码

2 微服务提供者 支付 Module 模块

2.1 建 Module: cloud-provider-payment8001

1.  建Module
复制代码

img

2.2 改 pom

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>cloud2020</artifactId>
        <groupId>com.atguigu.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <!--由于父类写了dependencyManagement,所以这里不用谢groupId和version-->
    <artifactId>cloud-provider-payment8001</artifactId>

    <dependencies>

        <!--web/actuator这两个一般一起使用,写在一起-->
        <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>

        <!--Mybatis和SpringBoot的整合-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <!--如果没写版本,从父层面找,找到了就直接用,全局统一-->
        </dependency>

        <!--mysql-connector-java-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--jdbc-->
        <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>
复制代码

2.3 写 yml

3.  写yml
复制代码
# 微服务端口号
server:
  port: 8001

# 微服务名称
spring:
  application:
    name: cloud-payment-service

  datasource:
    type: com.alibaba.druid.pool.DruidDataSource      # 数据源      
    driver-class-name: com.mysql.cj.jdbc.Driver     # mysql驱动包
    url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8
    username: root
    password: root


mybatis:
  mapper-locations: classpath:mapper/*.xml  # 扫描类路径下mapper文件夹下的.xml配置文件
  type-aliases-package: com.atguigu.springcloud.entities  # 该包所有Entity类,取默认别名
复制代码

2.4 主启动类

4.  主启动类
复制代码
    @SpringBootApplication
    public class PaymentMain8001 {
        public static void main(String[] args) {
            SpringApplication.run(PaymentMain8001.class, args);
        }
    }

复制代码

2.5 业务类

5.  业务类

    1.  建表 SQL
    2.  entities
    3.  dao
    4.  service
    5.  controller
复制代码

2.5.1 建表 SQL

    1.  SQL语句
复制代码
    CREATE TABLE `payment`(
    	#注释它是 'ID'
    	`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', 
    	# 单引号引住,默认值是空字符串
    	`serial` VARCHAR(200) DEFAULT'', 
    	PRIMARY KEY(`id`)
    )ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
复制代码

2.5.2 后端业务

    1.  主实体:Payment
复制代码
        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        public class Payment implements Serializable {
        
            private Long id;
            private String serial;
        }
复制代码
    2.  Json封装体CommonResult
    
        返回给前端的一个通用的JSON实体串,和前端沟通时,不讲具体后台业务。
复制代码
        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        public class CommonResult<T> {
        
            //404 not_found     :    Integer String
            private Integer code;
            private String message;
        
            //这不是针对某一个实体类的Josn串封装类
            private T data;
        
            //当T是null时,定义一个两个参数的构造
            public CommonResult(Integer code, String message){
                this(code, message, null);
            }
        }
复制代码
    3.  dao
        
        1.  dao接口
复制代码
        @Mapper
        public interface PaymentDao {
        
            public int create(Payment payment);
        
            public Payment getPaymentById(@Param("id") Long id);
        }

复制代码
        2.  classpath:mapper/PaymentMapper.xml
复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.atguigu.springcloud.dao.PaymentDao">

    <!--
        注意yml中:type-aliases-package: com.atguigu.springcloud.entities  # 该包所有Entity类,取默认别名
        useGeneratedKeys="true",keyProperty="id"
            设置插入成功时使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中
    -->
    <insert id="create" parameterType="Payment" useGeneratedKeys="true" keyProperty="id">
        insert into payment(serial) values(#{serial});
    </insert>

    <!--定义一个结果接和实体类的映射表-->
    <resultMap id="BaseResultMap" type="com.atguigu.springcloud.entities.Payment">
        <id column="id" property="id" jdbcType="BIGINT"/>
        <id column="serial" property="serial" jdbcType="VARCHAR"/>
    </resultMap>
    
    <select id="getPaymentById" parameterType="Long" resultMap="BaseResultMap">
        select * from payment where id=#{id};
    </select>

</mapper>
复制代码
    4.  service
    
        1.  PaymentService
复制代码
    public interface PaymentService {
    
        public int create(Payment payment);
    
        public Payment getPaymentById(@Param("id") Long id);
    }
复制代码
        2. PaymentServiceImpl
复制代码
    @Service
    public class PaymentServiceImpl implements PaymentService {
    
        @Resource
        private PaymentDao paymentDao;
    
        public int create(Payment payment){
            return paymentDao.create(payment);
        }
    
        public Payment getPaymentById(Long id){
            return paymentDao.getPaymentById(id);
        }
    
    }
复制代码
    5.  controller
复制代码
    @RestController
    @Slf4j
    public class PaymentController {
        
        @Resource
        private PaymentService paymentService;
        
        //传给前端JSON
        @PostMapping(value = "/payment/create")    //写操作POST
        public CommonResult create(Payment payment){
            
            //由于在mapper.xml配置了useGeneratedKeys="true" keyProperty="id",会将自增的id封装到实体类中
            int result = paymentService.create(payment);
    
            log.info("*****插入结果:" + result);
            
            if(result > 0){
                return new CommonResult(200, "插入数据库成功", result);
            }else {
                return new CommonResult(444,"插入数据库失败", null);
            }
        }
    
        //传给前端JSON
        @GetMapping(value = "/payment/get/{id}")    //写操作POST
        public CommonResult getPaymentById(@PathVariable("id") Long id){
            
            Payment payment = paymentService.getPaymentById(id);
    
            log.info("*****查询结果:" + payment);
    
            if(payment != null){
                return new CommonResult(200, "查询数据库成功", payment);
            }else {
                return new CommonResult(444,"查询ID:"+id+"没有对应记录", null);
            }
        }
    }
复制代码

2.6 测试

2.6.1 测试 @GetMapping(value = "/payment/get/{id}")

    1.  启动报错:
        
        Cause:
复制代码
        Error resolving class. Cause: org.apache.ibatis.type.TypeException: 
        Could not resolve type alias 'BaseResultMap'.  
        Cause: java.lang.ClassNotFoundException: Cannot find class: BaseResultMap
复制代码

img

    2.  启动报错:errorCode 1045, state 28000
复制代码
create connection SQLException, url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8, errorCode 1045, state 28000
        原因
复制代码

img

        改成password: root
        
    
    3.  测试失败:发送请求http://localhost:8001/payment/get/1
复制代码

img

        原因:
复制代码

img

        改成
复制代码

img

    4.  测试成功
复制代码

img

2.6.2 测试 @PostMapping(value = "/payment/create")

    1.  测试:发送请求http://localhost:8001/payment/create?serial=atguigu002
    
    2.  测试失败:403
    
        请求方法不支持:
复制代码

img

    3.  原因:
        
        controller中插入方法的接收POST请求,但是这样发送的却是GET请求。
        
    4.  POSTMAN 模拟发送POST请求
    
        测试成功
复制代码

img

    注意:浏览器不好直接发送POST请求。
复制代码

2.7 小结

    1.  建module
    2.  改pom
    3.  写yml
    4.  主启动
    4.  业务类
复制代码

3 热部署 Devtools

1.  Adding devtools to your project

    粘贴到子模块 cloud-provider-payment8001 的pom.xml中
复制代码
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
复制代码
2.  Adding plugin to your pom.xml
    
    粘贴到聚合父类总工程的pom.xml里
复制代码

img

      <build>
        <finalName>cloud2020</finalName>    # 可加可不加
        <plugins>
          <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
              <fork>true</fork>
              <addResources>true</addResources>
            </configuration>
          </plugin>
        </plugins>
      </build>

复制代码
3.  Enabling automatic build

    开启自动编译的选项
复制代码

img

4.  Update the value of

    热注册开启:
    
    ctrl+alt+shift+/:弹出一个选框,选第一个.
复制代码

img

    勾选:这两个
复制代码

img

5.  重启IDEA

    
6.  建议:只在开发阶段使用,实际上线生产部署阶段必须关闭。
    
    太慢了,效果不明显,吃配置,电脑会卡。
    而且如果热部署起效慢的话,我得请求资源会404。
复制代码

3 微服务消费者 消费 Module 模块

    1.  建module
    2.  改pom
    3.  写yml
    4.  主启动
    5.  业务类
复制代码

3.1 建 Module:cloud-consumer-order80

img

3.2 改 pom

    <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>
复制代码

3.3 写 yml

80端口是默认的http端口,可以默认不写
baidu.com  ====  baidu.com:80

8080和80端口无本质区别
Apache Tomcat web server安装后,默认的服务端口就是8080
复制代码

因为考虑到用户发送请求一般不会输入 80,所以给消费者模块加 80 端口。

3.5 主启动类

    @SpringBootApplication
    public class OrderMain80 {
        
        public static void main(String[] args) {
            SpringApplication.run(OrderMain80.class, args);
        }
    }
复制代码

3.6 业务类

    消费者要调用8001端口的生产者,那么在业务类中还要service/controller/dao等包吗?
    
    显然,消费者不需要访问数据库等操作,只需要一个controller控制层即可。
复制代码

3.6.1 后端代码

    1.  实体类Payment
复制代码
        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        public class Payment implements Serializable {
        
            private Long id;
            private String serial;
        }
复制代码
    2.  JSON封装类 CommonResult<T>
复制代码
        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        public class CommonResult<T> {
        
            //404 not_found     :    Integer String
            private Integer code;
            private String message;
        
            //这不是针对某一个实体类的Josn串封装类
            private T data;
        
            //当T是null时,定义一个两个参数的构造
            public CommonResult(Integer code, String message){
                this(code, message, null);
            }
        
        }
复制代码
    3.  controller控制层

        用restTemplate实现消费者和提供者微服务之间的横向调用
        
        1.  RestTemplate提供了多种便捷访问远程Http服务的方法,是一种简单便捷的访问restful
            服务模版类,是Spring提供的用于访问Rest服务的客户端模版工具。
            
        2.  使用
            使用restTemplate访问restful接口非常的简单粗暴无脑
            (url, requestMap, ResponseBean.class)这是那个参数分别代表:
            rest请求地址,请求参数,HTTP响应转换成的对象类型。
            
        3.  依靠一个配置类,将其注入到容器

        4.   配置类: 向容器中注入一个restTemplate Bean
复制代码
        @Configuration
        public class ApplicationContextConfig {
            
            @Bean
            public RestTemplate getRestTemplate(){
                return new RestTemplate();
            }
        }
复制代码
        5.  controller代码
        
            当消费者模块接收到请求时,会用restTemplate去调用生产者模块中的方法
            即用restTemplate实现消费者和提供者微服务之间的横向调用。
复制代码
        @RestController
        @Slf4j
        public class OrderController {
        
            //暂时在这里写死
            public static final String PAYMENT_URL = "http:localhost:8001";
        
            /**
             * 用restTemplate实现消费者和提供者微服务之间的横向调用
             */
            @Resource
            private RestTemplate template;
        
            //按理说插入数据应该是POST,可以从浏览器只能发GET请求,尽管不符合RESTFUL,
            // 但是下面的template.postForObject调用却是POST请求
            @GetMapping("/consumer/payment/create")
            public CommonResult<Payment> create(Payment payment){
                //调用生产者模块中的生产方法
                return template.postForObject(PAYMENT_URL+"payment/create", payment, CommonResult.class);
            }
        
            @GetMapping("/consumer/payment/get/{id}")
            public CommonResult<Payment> getPayment(@PathVariable("id") Long id){
                return template.getForObject(PAYMENT_URL+"/payment/get/"+id, CommonResult.class);
            }
        
        }
复制代码

3.7 测试查询操作

    1.  先启动生产者8001 模块
    
    2.  在启动消费者80 模块
    
    3.  Services
        当我启动第二个模块时,IDEA给了我提示,按照提示点击。
复制代码

img

    4.  生产者8001 自测通过
复制代码

img

    5.  用消费者80模块,调用生产者8080中的接口
        
        注意:我们默认消费者是不知道端口的,所以消费者端口是80可以默认不写。
        
        http://localhost/consumer/payment/get/2
        
    6.  测试成功
复制代码

img

3.8 测试插入操作

    1. 发送请求:http://localhost/consumer/payment/create?serial=ttxxll
复制代码

img

        说明调用流程成功了。
        
    2.  但是数据库中的结果:
复制代码

img

        说明插入操作的确插入了,但是插入的是一个空值。
        
    3.  不要忘了@RequestBody注解
复制代码

@RequestBody 注解对应的类在将 HTTP 的输入流 (含请求体) 装配到目标类(即:@RequestBody 后面 的类)时,会根据 json 字符串中的 key 来匹配对应实体类的属性,如果匹配一致且 json 中的该 key 对应的值符合 (或可转换为) 实体类的对应属性的类型要求时,会调用实体类的 setter 方法将值赋给该属性。

        原因:
复制代码
    @GetMapping("/consumer/payment/create")
    public CommonResult<Payment> create(Payment payment){

        /**
         * 调用生产者模块中的生产方法
         *
         * 这里要注意一下:restTemplate是访问Rest服务的客户端模版工具类,这里类似于又发送一个http请求,
         * 但是第二个参数payment对象在传递(http传输)的过程中,肯定要序列化,这里肯定是Json字符串了,
         * 所以在生产者那边根据默认的参数封装规则,封装不进去。
         * --->所以生产者中的接收该参数的方法要加上@RequestBody注解
         */
        return template.postForObject(PAYMENT_URL+"/payment/create", payment, CommonResult.class);
    }
复制代码
    4.  在生产者接收该参数的方法要加上@RequestBody注解
复制代码

img

    5.  插入操作测试成功
复制代码

img

4. 工程重构

    我们发现了一个问题:
复制代码

img

    两个微服务模块中都有entities,而且一模一样。如果程序中有很多这样的代码,那么这就有冗余。
    
    我们要将其抽取出来,形成我们自己的jar包。
    
    打成一份,一分部署,处处共用。
    
    思想:
        将相同重复的代码,将其抽取到一个公开共用的一个工程里面,供大家统一调配使用。
复制代码

4.1 新建一个公开共用的木块: cloud-api-commons

    这个模块不对外暴露,所以不像前面的两个微服务命名上有接口。
复制代码

img

4.2 改 pom

        <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.1.0</version>
            </dependency>
            
        </dependencies>
复制代码

4.3 将 entities 包放到 cloud-api-commons 模块

img

4.4 打包发布

    将其maven打包,发布上传到我们共用的本地库,供其他两个模块调用。
    
    clean + install
    
    发布到了我的本地仓库:
复制代码
D:Developer_Toolsmaven_repositorycomatguiguspringcloudcloud-api-commons1.0-SNAPSHOT

img

4.5 改造生产者和消费者模块

    1.  删除各自的原先有的entities文件夹
    
    2.  引入刚才发布的jar包
复制代码
        <!--引入我们自定义的公共api jar包-->
        <dependency>
            <groupId>com.atguigu.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
复制代码

img

4.6 测试

测试成功。
复制代码

img

原文地址:https://www.cnblogs.com/coderD/p/14350076.html