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說明
- Maven 使用 dependencyManagement 元素來提供了一種管理依賴版本号的方式。通常在packaging為pom的項目中使用該元素
- 使用 pom.xml 中的 dependencyManagement 元素能讓所有子項目引用一個依賴 ,Maven 會沿着父子層次向 上走,直到找到一個擁有dependencyManagement元素的項目,然後它就會使用這個dependencyManagement 元素中指定的版本号。
- 好處∶如果有多個子項目都引用同一樣依賴,則可以避免在每個使用的子項目裡都聲明一個版本号,當更新或切換到另一個版本時,隻需要在頂層父容器裡更新,而不需要分别在子項目中修改;另外如果某子項目需要另外的版本時,子項目隻需要聲明 version 就可。
- dependencyManagement 裡隻是聲明依賴,并不實作引入,是以子項目需要顯示的聲明需要用的依賴。
- 如果不在子項目中聲明依賴,是不會從父項目中繼承下來的;隻有在子項目中寫了該依賴項,并且沒有指定具體版本時,才會從父項目中繼承該項,并且version 和 scope 都讀取自父 pom。作用範圍一覽圖:
- 如果子項目中指定了版本号,那麼會使用子項目中指定的 jar 版本
2.建立會員中心微服務子產品-service provider
2.1需求分析
- 通過浏覽器可以擷取會員資訊(通過會員中心微服務子產品)
- 可以通過postman進行測試查詢和添加資料
2.2思路分析
- 建立Module & 完成配置
- 建立資料庫 & 表
- 建立 entity-dao/mapper.xml-service-controller
- 完成測試
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注意事項和細節
- 如果前端是以json格式來發送資料的,需要在controller層的方法參數前使用@RequestBody,來将json資料封裝成對應的Javabean。同時需要保證前端發送的http請求頭中,Content-Type指定的是json格式。
- 如果前端是以表單或者參數送出的,則不需要@RequestBody
- 在進行springboot應用程式測試時,引入的JUnit是 org.junit.jupiter.api.Test 包的
- 在運作程式時,一定要確定你的 XxxMapper.xml檔案被自動放到了 target 目錄的 classes 指定的目錄下
3.建立使用會員微服務子產品-service consumer
3.1需求分析
浏覽器向service consumer請求某個資料,service consumer會去向service provider請求資料,然後将service provider傳回的資料傳回給浏覽器。
添加資料同理。
3.2思路分析
- 建立Module(member-service-consumer-80) & 完成配置
- 建立controller
- 完成測試
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思路分析
- 建立Module & 完成配置
- 建立Entity,把共用的實體類放到對應的包下
- 完成測試
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/類,然後通過引入公共子產品的方式來簡化代碼。