天天看點

SpringCloud Day01---微服務架構編碼建構

1.微服務架構編碼

約定 > 配置 > 編碼

1.1 IDEA建立project工作空間

1.1.1 微服務cloud整體聚合父工程Project

  • New Project
SpringCloud Day01---微服務架構編碼建構
  • 聚合總父工程名字+項目名稱
SpringCloud Day01---微服務架構編碼建構
  • Maven選版本
SpringCloud Day01---微服務架構編碼建構
  • 字元編碼
SpringCloud Day01---微服務架構編碼建構
  • 注解生效激活
SpringCloud Day01---微服務架構編碼建構
  • java編譯版本選8
SpringCloud Day01---微服務架構編碼建構
  • File Type過濾

過濾掉無用的檔案(處理後隻是沒有顯示,但實際存在.)

SpringCloud Day01---微服務架構編碼建構

1.1.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">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.rg.springcloud</groupId>
  <artifactId>cloud2021</artifactId>
  <version>1.0-SNAPSHOT</version>
  <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.13</junit.version>
    <log4j.version>1.2.17</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>1.3.0</mybatis.spring.boot.version>
  </properties>

  <!-- 子子產品繼承之後,提供作用:鎖定版本+子modlue不用寫groupId和version  -->
  <dependencyManagement>
    <dependencies>
      <!--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 alibaba 2.1.0.RELEASE-->
      <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>
      <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>${mysql.version}</version>
      </dependency>
      <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>${druid.version}</version>
      </dependency>
      <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>${mybatis.spring.boot.version}</version>
      </dependency>
      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>${junit.version}</version>
      </dependency>
      <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>${log4j.version}</version>
      </dependency>
      <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.20</version>
        <optional>true</optional>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
          <fork>true</fork>
          <addResources>true</addResources>
        </configuration>
      </plugin>
    </plugins>
  </build>

</project>      

1.1.3 Maven工程落地細節複習

  1. Maven中的DependencyManagement和Dependencies差別

DependencyManagement

Maven 使用dependencyManagement 元素來提供了一種管理依賴版本号的方式。

通常會在一個組織或者項目的最頂層的父POM 中看到dependencyManagement 元素。

使用pom.xml 中的dependencyManagement 元素能讓所有在子項目中引用一個依賴而不用顯式的列出版本号。

Maven 會沿着父子層次向上走,直到找到一個擁有dependencyManagement 元素的項目,然後它就會使用這個dependencyManagement 元素中指定的版本号。

SpringCloud Day01---微服務架構編碼建構

這樣做的好處就是:如果有多個子項目都引用同一樣依賴,則可以避免在每個使用的子項目裡都聲明一個版本号,這樣當想更新或切換到另一個版本時,隻需要在頂層父容器裡更新,而不需要一個一個子項目的修改 ;另外如果某個子項目需要另外的一個版本,隻需要聲明version就可。

**dependencyManagement裡隻是聲明依賴,并不實作引入**,是以子項目需要顯示的聲明需要用的依賴。      
如果不在子項目中聲明依賴,是不會從父項目中繼承下來的;隻有在子項目中寫了該依賴項,并且沒有指定具體版本, 才會從父項目中繼承該項,并且version和scope都讀取自父pom;      
如果**子項目中指定了版本号,那麼會使用子項目中指定的jar版本**。      
  1. maven中跳過單元測試

1.配置

<build><!-- maven中跳過單元測試 -->
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <skip>true</skip>
            </configuration>
        </plugin>
    </plugins>
</build>      

2 IDEA工具支援(推薦)

SpringCloud Day01---微服務架構編碼建構

1.2 Rest微服務工程建構

1.2.1 cloud-provider-payment8001微服務生産者支付Module子產品

  • 建cloud-provider-payment8001

建立完成後請回到父工程檢視pom檔案變化:

SpringCloud Day01---微服務架構編碼建構
  • 改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>cloud2021</artifactId>
        <groupId>com.rg.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-provider-payment8001</artifactId>

    <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.17</version>
        </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>      
  • 寫YML
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/db2021?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 186259

mybatis:
  mapperLocations: classpath:mapper/*.xml               # 配置Mapper所有接口配置檔案的位置.
  type-aliases-package: com.rg.springcloud.entities    # 所有Entity别名類所在包      
  • 主啟動
@SpringBootApplication
public class PaymentMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentMain8001.class,args);
    }
}      
  • 業務類
  • 建表
CREATE TABLE `payment` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `serial` varchar(200) DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8      
  • pojo實體類

主實體Payment

/**
 * Description 支付類
 * @author lxy
 * @version 1.0
 * @date 2021/12/23 9:50
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Payment implements Serializable {
    private Long id;
    private String serial;
}      

Json封裝體CommonResult

/**
 * @author lxy
 * @version 1.0
 * @Description 前後端進行互動的結果類
 * @date 2021/12/23 11:01
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult<T> {
    private Integer code;//狀态碼
    private String message;//狀态資訊
    private T data;//傳回的json資料

    public CommonResult(Integer code,String message){//失敗時調用的方法.
        this(code,message,null);
    }
}      
  • DAO層

PaymentDao

/**
 * @author lxy
 * @version 1.0
 * @Description 支付dao類
 * @date 2021/12/23 11:06
 */
@Mapper
@Repository
public interface PaymentDao {
    public int create(Payment payment);

    public Payment getPaymentById(@Param("id") Long id);
}      

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.rg.springcloud.dao.PaymentDao">
    <!--設定useGeneratedKeys參數值為true,在執行添加記錄之後可以擷取到資料庫自動生成的主鍵ID。-->
    <insert id="create" parameterType="com.rg.springcloud.pojo.Payment" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO payment(serial) VALUES(#{serial})
    </insert>
    <resultMap id="BaseResultMap" type="com.rg.springcloud.pojo.Payment">
        <!--jdbcType這個參數的應用場景就是,當執行mapping檔案的時候,有個映射的參數為空,那麼無法确定他的類型,這個時候就需要jdbcType來确定類型。-->
        <id column="id" property="id" jdbcType="BIGINT"/>
        <result column="serial" property="serial" jdbcType="VARCHAR"/>
    </resultMap>
    <select id="getPaymentById" resultMap="BaseResultMap" parameterType="long">
        SELECT * FROM payment WHERE id = #{id}
    </select>


</mapper>      
  • service層
public interface PaymentService {
    public int create(Payment payment);

    public Payment getPaymentById(@Param("id") Long id);
}      
@Service
public class PaymentServiceImpl implements PaymentService {
    @Autowired
    private PaymentDao paymentDao;
    @Override
    public int create(Payment payment) {
        return paymentDao.create(payment);
    }

    @Override
    public Payment getPaymentById(Long id) {
        return paymentDao.getPaymentById(id);
    }
}      
  • controller層
/**
 * @author lxy
 * @version 1.0
 * @Description PaymentController
 * @date 2021/12/23 11:27
 */

@Slf4j
@RestController
public class PaymentController {
    @Resource
    private PaymentService paymentService;

    @PostMapping(value = "/payment/create")
    public CommonResult create(Payment payment){ // ??? 為啥這裡不需要@RequestBody呢??
        int result = paymentService.create(payment);
        log.info("*****插入操作傳回結果*:"+result);
        if(result>0) {
            return new CommonResult(200, "插入資料成功", result);
        }else
        {
            return new CommonResult(444, "插入資料失敗");
        }
    }

    @GetMapping(value = "/payment/get/{id}")
    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);
        }
    }
}      
  • 測試
SpringCloud Day01---微服務架構編碼建構
SpringCloud Day01---微服務架構編碼建構
SpringCloud Day01---微服務架構編碼建構
  • 小結

SpringBoot建立子產品的五個步驟:

1.建module

2.改POM

3.寫YML

4.主啟動

5.業務類

1.2.2 熱部署Devtools

1.Adding devtools to your project

<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裡

<build>
    <!--finalName:工程名稱-->
    <finalName>cloud2021</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

SpringCloud Day01---微服務架構編碼建構

4.Update the value of

SpringCloud Day01---微服務架構編碼建構
SpringCloud Day01---微服務架構編碼建構

5.重新開機IDEA

6.進行測試

SpringCloud Day01---微服務架構編碼建構
SpringCloud Day01---微服務架構編碼建構

1.2.3 cloud-consumer-order80:微服務消費者訂單Module子產品

  • 建cloud-consumer-order80
  • 改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>cloud2021</artifactId>
        <groupId>com.rg.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-consumer-order80</artifactId>

    <dependencies>
        <!-- 引入自己定義的api通用包,可以使用Payment支付Entity -->
        <dependency>
            <groupId>com.rg.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <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>      
  • 寫YML
server:
  port: 80      
  • 主啟動
@SpringBootApplication
public class OrderMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderMain80.class,args);
    }
}      
  • 業務類
  1. pojo

同cloud-provider-payment8001子產品的pojo

  1. 首說RestTemplate

RestTemplate提供了多種便捷通路遠端Http服務的方法,

是一種簡單便捷的通路restful服務模闆類,是Spring提供的==用于通路Rest服務==的用戶端模闆工具集

官網:https://docs.spring.io/spring-framework/docs/5.2.2.RELEASE/javadoc-api/org/springframework/web/client/RestTemplate.html

使用:

使用restTemplate通路restful接口非常的簡單粗暴無腦。

(url, requestMap, ResponseBean.class)這三個參數分别代表 REST請求位址、請求參數、HTTP響應轉換被轉換成的對象類型。

  1. config配置類
@Configuration
public class ApplicationContextConfig {
    //向SpringBoot容器中加入該元件
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}      

4.controller

@RestController
@Slf4j
public class OrderController {
    public static final String PAYMENT_URL = "http://localhost:8001";

    @Resource
    private RestTemplate restTemplate;

    @GetMapping("/consumer/payment/create")用戶端用浏覽器是get請求,但是底層實質發送post調用服務端8001
    public CommonResult<Payment> create(Payment payment){
        return restTemplate.postForObject(PAYMENT_URL+"/payment/create",payment,CommonResult.class);
    }

    @GetMapping("/consumer/payment/get/{id}")
    public CommonResult<Payment> getPayment(@PathVariable("id") Long id){
        return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);
    }
}      
  • 測試
SpringCloud Day01---微服務架構編碼建構
SpringCloud Day01---微服務架構編碼建構

備注:

使用postman或者rest client測試報出Required request body is missing 錯誤(而在其他場合發送post請求時根據需要進行添加該注解.)

解決:把 ​

​@RequestBody​

​去掉

1.2.4 工程重構

  • 觀察問題
SpringCloud Day01---微服務架構編碼建構

系統中有重複部分,是以應該重構

  • 建立 cloud-api-commons
  • 改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>cloud2021</artifactId>
        <groupId>com.rg.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-api-commons</artifactId>
    <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>
</project>      
  • pojo

添加Payment實體和CommonResult通用封裝類

  • maven指令clean install
  • 訂單80和支付8001分别改造
<!-- 引入自己定義的api通用包,可以使用Payment支付Entity -->
<dependency>
    <groupId>com.rg.springcloud</groupId>
    <artifactId>cloud-api-commons</artifactId>
    <version>${project.version}</version>
</dependency>      

1.2.5 目前工程樣圖