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_Tools\maven_repository\com\atguigu\springcloud\cloud-api-commons\1.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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM