天天看點

搭建微服務基礎環境

作者:湯圓說Java

1.建立父工程,用于聚合其他微服務子產品

1.1建立父項目

說明:我們先建立一個父項目,該父項目會去管理多個微服務子產品(module),如下:

搭建微服務基礎環境

(1)File-New-Project-Maven,選擇如下:

搭建微服務基礎環境

(2)輸入項目名稱等資訊,然後next

搭建微服務基礎環境

(3)選擇Maven,然後Finish

搭建微服務基礎環境

1.2項目設定

(1)File-Settings-Editor-File Encodings,将編碼改為UTF-8,點選Apply

搭建微服務基礎環境

(2)Settings-Build,Execution,Deployment-Compiler-Java Compiler,将項目的編譯版本改為8,點選OK

搭建微服務基礎環境

(3)删除父項目的src目錄

搭建微服務基礎環境

(4)配置父項目的pom.xml,配置各個依賴版本

<?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>com.li.springcloud</groupId>  <artifactId>E-Commerce-Center</artifactId>  <version>1.0-SNAPSHOT</version>  <!--将packaging的值改為pom,表明是一個父工程,聚合管理其他子產品-->  <packaging>pom</packaging>   <name>E-Commerce-Center</name>  <!-- FIXME change it to the project's website -->  <url>http://www.example.com</url>   <!--統一配置各個依賴版本-->  <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 , 防止安全漏洞-->    <log4j.version>2.17.2</log4j.version>    <lombok.version>1.18.20</lombok.version>    <mysql.version>5.1.47</mysql.version>    <druid.version>1.1.17</druid.version>    <mybatis.spring.boot.version>2.2.0</mybatis.spring.boot.version>  </properties>   <!--dependencyManagement 作用:子子產品繼承後,鎖定版本,子子產品不用再寫version-->  <dependencyManagement>  <dependencies>     <!--配置Spring-Boot的依賴-->    <dependency>      <groupId>org.springframework.boot</groupId>      <artifactId>spring-boot-dependencies</artifactId>      <version>2.2.2.RELEASE</version>      <!--1.type:pom 和 scope import配合使用          2.表示父項目的子子產品,在引入springboot相關依賴時,鎖定版本為2.2.2.RELEASE          3.通過pom+import 解決 maven 單繼承機制-->      <type>pom</type>      <scope>import</scope>    </dependency>     <!--配置SpringCloud(注意和spring-boot版本對應關系)-->    <dependency>      <groupId>org.springframework.cloud</groupId>      <artifactId>spring-cloud-dependencies</artifactId>      <version>Hoxton.SR1</version>      <type>pom</type>      <scope>import</scope>    </dependency>     <!--SpringCloud Alibaba-->    <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資料源-->    <dependency>      <groupId>com.alibaba</groupId>      <artifactId>druid</artifactId>      <version>${druid.version}</version>    </dependency>     <!--SpringBoot 整合 mybatis 的 starter-->    <dependency>      <groupId>org.mybatis.spring.boot</groupId>      <artifactId>mybatis-spring-boot-starter</artifactId>      <version>${mybatis.spring.boot.version}</version>    </dependency>     <!--log4j-->    <dependency>      <groupId>org.apache.logging.log4j</groupId>      <artifactId>log4j</artifactId>      <version>${log4j.version}</version>    </dependency>     <!--Junit-->    <dependency>      <groupId>junit</groupId>      <artifactId>junit</artifactId>      <version>${junit.version}</version>    </dependency>     <!--Lombok-->    <dependency>      <groupId>org.projectlombok</groupId>      <artifactId>lombok</artifactId>      <version>${lombok.version}</version>    </dependency>   </dependencies>  </dependencyManagement>    <!--<!--删除 build 和 reporting 節點-->--></project>           

1.3dependencyManagement說明

  1. Maven 使用 dependencyManagement 元素來提供了一種管理依賴版本号的方式。通常在packaging為pom的項目中使用該元素
  2. 使用 pom.xml 中的 dependencyManagement 元素能讓所有子項目引用一個依賴 ,Maven 會沿着父子層次向 上走,直到找到一個擁有dependencyManagement元素的項目,然後它就會使用這個dependencyManagement 元素中指定的版本号。
  3. 好處∶如果有多個子項目都引用同一樣依賴,則可以避免在每個使用的子項目裡都聲明一個版本号,當更新或切換到另一個版本時,隻需要在頂層父容器裡更新,而不需要分别在子項目中修改;另外如果某子項目需要另外的版本時,子項目隻需要聲明 version 就可。
  4. dependencyManagement 裡隻是聲明依賴,并不實作引入,是以子項目需要顯示的聲明需要用的依賴。
  5. 如果不在子項目中聲明依賴,是不會從父項目中繼承下來的;隻有在子項目中寫了該依賴項,并且沒有指定具體版本時,才會從父項目中繼承該項,并且version 和 scope 都讀取自父 pom。作用範圍一覽圖:
  6. 如果子項目中指定了版本号,那麼會使用子項目中指定的 jar 版本

2.建立會員中心微服務子產品-service provider

2.1需求分析

  1. 通過浏覽器可以擷取會員資訊(通過會員中心微服務子產品)
  2. 可以通過postman進行測試查詢和添加資料

2.2思路分析

  1. 建立Module & 完成配置
  2. 建立資料庫 & 表
  3. 建立 entity-dao/mapper.xml-service-controller
  4. 完成測試

2.3實作步驟

2.3.1建立Module&完成配置

(1)建立名為 member-service-provider-10000 的微服務子產品,提供會員服務。member代表會員服務,service-provider代表這是一個提供服務的子產品,10000代表端口。

依次選擇:File-New-Module

搭建微服務基礎環境

(2)選擇Maven,直接下一步

搭建微服務基礎環境

(3)idea會自動識别父工程,如下,然後點選Finish

搭建微服務基礎環境

(4)如果建立成功,父項目會自動聚合子子產品。父項目的pom.xml檔案:

搭建微服務基礎環境

(5)修改member-service-provider-10000子子產品的pom.xml,加入相關依賴

<?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>E-Commerce-Center</artifactId>        <groupId>com.li.springcloud</groupId>        <version>1.0-SNAPSHOT</version>    </parent>    <modelVersion>4.0.0</modelVersion>     <artifactId>member-service-provider-10000</artifactId>     <properties>        <maven.compiler.source>8</maven.compiler.source>        <maven.compiler.target>8</maven.compiler.target>    </properties>     <!--引入相關的依賴,版本都使用父項目聲明的版本-->    <dependencies>         <!--web-starter-->        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>        </dependency>         <!--actuator-starter 是 springboot程式的監控系統,可以實作系統的健康監測            可以通過http://localhost:10000/actuator看到相關的連接配接和資訊-->        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-actuator</artifactId>        </dependency>         <!--引入mybatis-starter,整合到springboot中-->        <dependency>            <groupId>org.mybatis.spring.boot</groupId>            <artifactId>mybatis-spring-boot-starter</artifactId>        </dependency>         <!--druid-starter-->        <dependency>            <groupId>com.alibaba</groupId>            <artifactId>druid-spring-boot-starter</artifactId>            <!--這裡父項目沒有指定版本,需要手動指定-->            <version>1.1.17</version>        </dependency>         <!--mysql驅動-->        <dependency>            <groupId>mysql</groupId>            <artifactId>mysql-connector-java</artifactId>        </dependency>         <!--jdbc-starter-->        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-jdbc</artifactId>        </dependency>         <!--lombok-->        <dependency>            <groupId>org.projectlombok</groupId>            <artifactId>lombok</artifactId>        </dependency>         <!--test-starter-->        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-test</artifactId>        </dependency>    </dependencies></project>           

(6)在member-service-provider-10000子子產品中建立resources/application.yml檔案

server:  port: 10000spring:  application:    name: member-service-provider-10000 #配置應用的名稱  datasource:    type: com.alibaba.druid.pool.DruidDataSource #指定資料源類型    url: jdbc:mysql://localhost:3306/e_commerce_center_db?useSSL=true&useUnicode=true&characterEncoding=UTF-8    username: root    password: 123456mybatis:  mapper-locations: classpath:mapper/*.xml #指定mapper.xml檔案位置  type-aliases-package: com.li.springcloud.entity #實體類的包,這樣通過類名就可以引用           

(7)啟動子子產品的主程式:

package com.li.springcloud; import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication; /** * @author 李 * @version 1.0 */@SpringBootApplicationpublic class MemberApplication {    public static void main(String[] args) {        SpringApplication.run(MemberApplication.class, args);    }}           

測試結果:運作成功。

搭建微服務基礎環境

2.3.2建立資料庫&表

-- 建立資料庫CREATE DATABASE e_commerce_center_dbUSE e_commerce_center_db -- 建立member表CREATE TABLE `member`(`id` 		BIGINT NOT NULL AUTO_INCREMENT COMMENT 'id',`name` 		VARCHAR(64) COMMENT '使用者名',`pwd` 		CHAR(32) COMMENT '密碼',`mobile` 	VARCHAR(20) COMMENT '手機号碼',`email` 	VARCHAR(64) COMMENT '郵箱',`gender` 	TINYINT COMMENT '性别', PRIMARY KEY (id)); -- 測試資料INSERT INTO member VALUES(NULL, 'smith', MD5('123'), '123456789000', '[email protected]', 1); SELECT * FROM member;           
搭建微服務基礎環境

2.3.3業務實作

2.3.3.1utils層

Result工具類,用于同一傳回的資料類型

package com.li.springcloud.utils; /** * @author 李 * @version 1.0 傳回結果對象,以json格式傳回 */public class Result<T> {    private String code;//狀态碼 200-success 400-fail    private String msg;//狀态說明    private T data;//傳回的資料,使用泛型     public Result() {    }     public Result(T data) {        this.data = data;    }     //傳回需要的result對象,表示成功    public static Result success() {        Result result = new Result<>();        result.setCode("200");        result.setMsg("success");        return result;    }     //傳回成功的result對象,表示成功,同時攜帶資料    //如果需要在static方法中使用泛型,需要在static關鍵字後添加<T>    public static <T> Result<T> success(T data) {        Result<T> result = new Result<>(data);        result.setCode("200");        result.setMsg("success");        return result;    }        //傳回成功的result對象,表示成功,同時攜帶資料和自定義msg    public static <T> Result<T> success(String msg, T data) {        Result<T> result = new Result<>(data);        result.setCode("200");        result.setMsg(msg);        return result;    }     //傳回需要的result對象-表示失敗    //因為失敗的原因有很多中,是以直接将其作為參數傳進來    public static Result error(String code, String msg) {        Result result = new Result<>();        result.setCode(code);        result.setMsg(msg);        return result;    }     //傳回成功的result對象,表示失敗,同時攜帶資料    public static <T> Result<T> error(String code, String msg, T data) {        Result<T> result = new Result<>(data);        result.setCode(code);        result.setMsg(msg);        return result;    }     //getter、setter方法省略}           

2.3.3.2entity層

Member實體類:

package com.li.springcloud.entity; import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor; /** * @author 李 * @version 1.0 */@Data@AllArgsConstructor@NoArgsConstructorpublic class Member {    private Long id;    private String name;    private String pwd;    private String mobile;    private String email;    private Integer gender;}           

2.3.3.3dao層

Member對應的Dao層接口:MemberDao.java

package com.li.springcloud.dao; import com.li.springcloud.entity.Member; /** * @author 李 * @version 1.0 */public interface MemberDao {    //根據id傳回member對象    public Member queryMemberById(Long id);    //添加member    public int save(Member member);}           
如果在這裡不添加@Mapper注解,則需要在主程式中添加@MapperScan(basePackages = {"com.li.springcloud.dao"})

在 resources/mapper/MemberMapper.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.li.springcloud.dao.MemberDao">     <!--為了拓展,這裡使用resultMap-->    <resultMap id="BaseResultMap" type="com.li.springcloud.entity.Member">        <id column="id" property="id" jdbcType="BIGINT"></id>        <id column="name" property="name" jdbcType="VARCHAR"></id>        <id column="pwd" property="pwd" jdbcType="VARCHAR"></id>        <id column="mobile" property="mobile" jdbcType="VARCHAR"></id>        <id column="email" property="email" jdbcType="VARCHAR"></id>        <id column="gender" property="gender" jdbcType="TINYINT"></id>    </resultMap>     <!--配置實作queryMemberById()-->    <select id="queryMemberById" parameterType="Long" resultMap="BaseResultMap">        SELECT * FROM `member` WHERE `id` = #{id}    </select>     <!--配置實作save(),useGeneratedKeys=true,擷取自增長id-->    <insert id="save" parameterType="Member" useGeneratedKeys="true" keyProperty="id">        INSERT INTO `member` (`name`, `pwd`, `mobile`, `email`, `gender`)        VALUES (#{name}, MD5(#{pwd}), #{mobile}, #{email}, #{gender});    </insert></mapper>           

測試類:

注意:測試類需要和主程式在同一個路徑下,否則需要手動指定class
package com.li.springcloud; import ... /** * @author 李 * @version 1.0 */@SpringBootTest@Slf4jpublic class MemberApplicationTest {     //裝配MemberDao    @Resource    private MemberDao memberDao;     @Test //注意:引入的是 org.junit.jupiter.api.Test;    public void queryMemberById() {        Member member = memberDao.queryMemberById(1L);        log.info("member={}", member);    }     @Test //引入的是 org.junit.jupiter.api.Test;    public void save() {        Member member =                new Member(null, "牛魔王", "123456", "18077560000", "[email protected]", 1);        int save = memberDao.save(member);        log.info("受影響的行數={}", save);    }}           

queryMemberById()測試結果:

member=Member(id=1, name=smith, pwd=202cb962ac59075b964b07152d234b70, mobile=123456789000, [email protected], gender=1)           

save()測試結果:

受影響的行數=1           
搭建微服務基礎環境

2.3.3.4service層

MemberService接口:

package com.li.springcloud.service; import com.li.springcloud.entity.Member; /** * @author 李 * @version 1.0 */public interface MemberService {    //根據id傳回member    public Member queryMemberById(Long id);     //添加member    public int save(Member member);}           

MemberServiceImpl實作類:

package com.li.springcloud.service.impl; import ... /** * @author 李 * @version 1.0 */@Servicepublic class MemberServiceImpl implements MemberService {    @Resource    private MemberDao memberDao;     @Override    public Member queryMemberById(Long id) {        return memberDao.queryMemberById(id);    }     @Override    public int save(Member member) {        return memberDao.save(member);    }}           

測試類:

package com.li.springcloud; import ... /** * @author 李 * @version 1.0 */@SpringBootTest@Slf4jpublic class MemberApplicationTest {    //裝配MemberService    @Resource    private MemberService memberService;     @Test    public void queryMemberById() {        Member member = memberService.queryMemberById(3L);        log.info("member={}", member);    }     @Test    public void save() {        Member member =             new Member(null, "tomas", "hahah123", "0773-2345-678", "[email protected]", 0);        int save = memberService.save(member);        log.info("受影響的行數={}", save);    }}           

queryMemberById()測試結果:

member=Member(id=3, name=jack, pwd=202cb962ac59075b964b07152d234b70, mobile=123456789000, [email protected], gender=1)           

save()測試結果:

受影響的行數=1           
搭建微服務基礎環境

2.3.3.5controller層

package com.li.springcloud.controller; import ... /** * @author 李 * @version 1.0 */@Controller@Slf4jpublic class MemberController {    @Resource    private MemberService memberService;     @PostMapping("/member/save")    @ResponseBody    public Result save(Member member) {        int affected = memberService.save(member);        if (affected > 0) {            return Result.success("添加會員成功", affected);        } else {            return Result.error("401", "添加會員失敗");        }    }     @GetMapping("/member/get/{id}")    @ResponseBody    public Result getMemberById(@PathVariable("id") Long id) {        Member member = memberService.queryMemberById(id);        if (member != null) {            return Result.success("查詢成功", member);        } else {            return Result.error("402", "Id=" + id + "使用者不存在!");        }    }}           

2.3.4完成測試

(1)測試controller的save()方法

使用postman進行測試

搭建微服務基礎環境

傳回結果:

搭建微服務基礎環境

資料成功插入表中:

搭建微服務基礎環境

(2)測試controller的getMemberById()方法

搭建微服務基礎環境
搭建微服務基礎環境

測試成功。

2.4注意事項和細節

  1. 如果前端是以json格式來發送資料的,需要在controller層的方法參數前使用@RequestBody,來将json資料封裝成對應的Javabean。同時需要保證前端發送的http請求頭中,Content-Type指定的是json格式。
  2. 如果前端是以表單或者參數送出的,則不需要@RequestBody
  3. 在進行springboot應用程式測試時,引入的JUnit是 org.junit.jupiter.api.Test 包的
  4. 在運作程式時,一定要確定你的 XxxMapper.xml檔案被自動放到了 target 目錄的 classes 指定的目錄下

3.建立使用會員微服務子產品-service consumer

3.1需求分析

搭建微服務基礎環境

浏覽器向service consumer請求某個資料,service consumer會去向service provider請求資料,然後将service provider傳回的資料傳回給浏覽器。

添加資料同理。

3.2思路分析

  1. 建立Module(member-service-consumer-80) & 完成配置
  2. 建立controller
  3. 完成測試

3.3實作步驟

3.3.1建立Module&完成配置

步驟同上一篇的2.3.1

(1)建立Module:member-service-consumer-80

搭建微服務基礎環境

(2)在子子產品的pom.xml檔案中加入相關的依賴:

因為這個子產品不需要直接操作資料庫,相比于之間的子子產品,減少了和資料庫相關的依賴。
<?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>E-Commerce-Center</artifactId>        <groupId>com.li.springcloud</groupId>        <version>1.0-SNAPSHOT</version>    </parent>    <modelVersion>4.0.0</modelVersion>     <artifactId>member-service-consumer-80</artifactId>     <properties>        <maven.compiler.source>8</maven.compiler.source>        <maven.compiler.target>8</maven.compiler.target>    </properties>     <!--引入相關的依賴,版本都使用父項目聲明的版本-->    <dependencies>        <!--web-starter-->        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>        </dependency>         <!--actuator-starter 是 springboot程式的監控系統,可以實作系統的健康監測            可以通過http://localhost:10000/actuator看到相關的連接配接和資訊-->        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-actuator</artifactId>        </dependency>         <!--lombok-->        <dependency>            <groupId>org.projectlombok</groupId>            <artifactId>lombok</artifactId>        </dependency>    </dependencies></project>           

(3)建立resources/application.yml

server:  port: 80spring:  application:    name: member-service-consumer-80           

(4)建立啟動類

package com.li.springcloud; import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication; /** * @author 李 * @version 1.0 */@SpringBootApplicationpublic class MemberConsumerApplication {    public static void main(String[] args) {        SpringApplication.run(MemberConsumerApplication.class,args);    }}           

測試,啟動成功:

搭建微服務基礎環境

3.3.1業務實作

3.3.1.1utils層

建立工具類Result.java(略,見2.3.3.1)

3.3.1.2Entity層

Member.java

package com.li.springcloud.entity; import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor; /** * @author 李 * @version 1.0 */@Data@AllArgsConstructor@NoArgsConstructor//因為對象在網絡中以流的形式傳遞,這裡最好實作Serializable接口public class Member implements Serializable{    private Long id;    private String name;    private String pwd;    private String mobile;    private String email;    private Integer gender;}           

3.3.1.3注入RestTemplate

RestTemplate 基本介紹:RestTemplate 是 Spring 提供的用于通路Rest服務的模闆類,它提供來了許多便捷通路遠端 Http 服務的方法。

通過 RestTemplate,我們可以向另一個微服務子產品發出 Http 請求(支援 Restful 風格),去調用該子產品的 Controller 提供的 API 接口,就像浏覽器送出請求調用該 API 接口一樣。

RestTemplate 官網:RestTemplate (Spring Framework 5.2.2.RELEASE API)

建立配置類,注入RestTemplate對象:

package com.li.springcloud.config; import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.client.RestTemplate; /** * @author 李 * @version 1.0 * 注入RestTemplate Bean */@Configurationpublic class CustomInitBean {    @Bean    public RestTemplate getRestTemplate() {        return new RestTemplate();    }}           

3.3.1.4Controller層

MemberConsumerController.java:

package com.li.springcloud.controller; import com.li.springcloud.entity.Member;import com.li.springcloud.utils.Result;import lombok.extern.slf4j.Slf4j;import org.springframework.stereotype.Controller;import org.springframework.validation.annotation.Validated;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate; import javax.annotation.Resource; /** * @author 李 * @version 1.0 */@RestController@Slf4jpublic class MemberConsumerController {    @Resource    private RestTemplate restTemplate;     //定義一個基礎的url    public static final String MEMBER_SERVICE_PROVIDER_URL =            "http://localhost:10000";     //添加對象到資料庫表中    @PostMapping("/member/consumer/save")    public Result<Member> save(Member member) {        log.info("service-consumer member={}", member);        /**         * MEMBER_SERVICE_PROVIDER_URL + "/member/save":就是向對應子子產品發出的完整url請求         * member:就是通過 restTemplate 發出的 post 請求攜帶的資料(對象)         * Result.class:就是傳回的對象類型         */        return restTemplate.postForObject                (MEMBER_SERVICE_PROVIDER_URL + "/member/save",                        member,                        Result.class);    }     //根據id調用服務接口,傳回member對象資訊    @GetMapping("/member/consumer/get/{id}")    public Result<Member> getMemberById(@PathVariable("id") Integer id) {        return restTemplate.getForObject                (MEMBER_SERVICE_PROVIDER_URL + "/member/get/" + id,                        Result.class);    }}           

3.3.1完成測試

分别啟動兩個子子產品(service consumer、service provider)

(1)測試save方法:postman以表單形式發出資料:

搭建微服務基礎環境

結果顯示添加成功,但是我們在資料庫中看到的确是空值:

搭建微服務基礎環境

原因是因為使用RestTemplate,它會将資料以json格式發送。解決方法是在服務子產品對應方法參數中使用@RequestBody注解,将接收的json格式資料轉換成對象。

最好實體類實作Serializable,支援可序列化
搭建微服務基礎環境

重新啟動子產品,使用postman發送資料:資料庫添加成功。

搭建微服務基礎環境

(2)浏覽器測試getMemberById方法:

搭建微服務基礎環境

測試通過。

3.4注意事項和使用細節

當SpringCloud的服務有多個時,管理多個服務的啟動使用右上角的run會不好管理,我們可以使用Run Dashboard:idea中如何開啟Dashboard

搭建微服務基礎環境

4.建立共用子產品-供其他子產品使用

4.1需求分析

我們在 consumer 和 provider 子產品都使用到了 Member 和 Result 類,我們可以将它們抽取到共用子產品(e_commerce_center_common-api),使用Maven 打包成 jar包,其他子產品需要使用直接引入依賴即可。

4.2思路分析

  1. 建立Module & 完成配置
  2. 建立Entity,把共用的實體類放到對應的包下
  3. 完成測試

4.3實作步驟

4.3.1建立Module&完成配置

(1)建立Module--e_commerce_center_common-api

搭建微服務基礎環境

(2)在本子產品的pom.xml引入公共的依賴

<!--引入公共子產品需要的依賴-->    <dependencies>        <!--lombok-->        <dependency>            <groupId>org.projectlombok</groupId>            <artifactId>lombok</artifactId>            <!--<optional>true</optional>:防止将該依賴傳遞到其他子產品中                1. true 表示兩個項目之間依賴不傳遞                   比如 a 子產品依賴了本項目,那麼本項目不會把 lombok 的jar包給 a 子產品                   意義在于繼承依賴時,防止jar發生版本沖突(如,a子產品可以自定義需要的Lombok版本)                2. 不設定optional或optional=預設值false,都表示傳遞依賴            -->            <optional>true</optional>        </dependency>    </dependencies>           

4.3.2抽取共用的API/類

建立多個子子產品都要使用的公共類,注意路徑要和其他子產品的路徑相同。

搭建微服務基礎環境

4.3.3使用Maven打包成jar

(1)按如下步驟進行打包:

搭建微服務基礎環境
搭建微服務基礎環境

(2)成功後會在target目錄下生成對應的jar包:

搭建微服務基礎環境

并且maven-archiver下的pom.properties中生成了項目對應的坐标:

#Generated by Maven#Tue Apr 04 19:38:29 CST 2023version=1.0-SNAPSHOTgroupId=com.li.springcloudartifactId=e_commerce_center_common-api           

4.3.4工程重構

(1)在 member-service-provider-10000 子產品删除目前子產品的 entity 包和 utils 包

搭建微服務基礎環境

(2)在 member-service-provider-10000 的 pom.xml 引入公共子產品:

<dependency>    <groupId>com.li.springcloud</groupId>    <artifactId>e_commerce_center_common-api</artifactId>    <version>1.0-SNAPSHOT</version></dependency>           

然後點選重新整理Maven,這樣就可以引入之前打包好的jar包代碼了。

(3)同理,在 member-service-consumer-80 子產品中也删除 entity 和 utils 包,然後在本子產品的 pom.xml 檔案中也引入公共子產品,然後重新整理。

4.3.5完成測試

分别啟動 member-service-provider-10000 和 member-service-consumer-80 兩個子子產品,在浏覽器中發送請求進行測試:

如下,測試成功,工程進行重構之後沒有問題,公共子產品引入各個子產品之後依然可以工作。

搭建微服務基礎環境

之後如果多個子產品還有公共的類,依然可以通過這種方式來抽取共用的API/類,然後通過引入公共子產品的方式來簡化代碼。

繼續閱讀