【Spring Cloud】2.微服务架构设计

1.创建Maven项目

1.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>org.example</groupId>
  <artifactId>SpringCloud</artifactId>
  <version>1.0-SNAPSHOT</version>
  <modules>
    <module>test01-payment8001</module>
  </modules>
  <!--
  项目的打包类型默认为jar,现在改成pom类型,是为了聚合项目,通常由一个父模块和若干个子模块构成。
  以<modules>给出所有的子模块,其中的每个module,都是另外一个Maven项目
  -->
  <packaging>pom</packaging>

  <name>Maven</name>
  <!-- FIXME change it to the project's website -->
  <url>http://maven.apache.org/</url>
  <inceptionYear>2001</inceptionYear>

  <distributionManagement>
    <site>
      <id>website</id>
      <url>scp://webhost.company.com/www/website</url>
    </site>
  </distributionManagement>

  <!-- 统一管理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.16.18</lombok.version>
    <mysql.version>8.0.20</mysql.version>
    <druid.version>1.1.16</druid.version>
    <mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
  </properties>

<!--  Maven 使用dependencyManagement元素来提供了一种管理依赖版本号的方式。-->
<!--  通常会在一个项目的最顶层的父POM中看到dependencyManagement元素。-->
<!--  使用pom.xml 中的dependencyManagement元素能让所有在子项目中引用一个依赖而不用显式的列出版本号。Maven会沿着父子层次向上走,
      直到找到一个拥有dependencyManagement元素的项目,然后它就会使用这个dependencyManagement元素中指定的版本号。-->
<!--  dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。-->
<!--  如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,-->
<!--  才会从父项目中继承该项,并且version和scope都读取自父pom;-->

  <!-- 子模块继承之后,提供作用:锁定版本+子modlue不用写groupId和version 子pom文件不用添加版本号 -->
  <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>${lombok.version}</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>

2.支付模块-payment8001

在这里插入图片描述

2.1 创建Maven项目_子工程Pom

<dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-jdbc -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

2.2 PaymentMain8001.java

package com.node;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class PaymentMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentMain8001.class,args);
    }
}

2.3 application.yml

server:
  port: 8001


spring:
  datasource:
    url: jdbc:mysql://192.168.3.108:3306/springcloud?characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver

mybatis:
  mapperLocations: classpath:mapper/*.xml
  type-aliases-package: com.node

2.4 运行检查是否导入错误jar

2.5 建表

DROP TABLE IF EXISTS `payment`;
CREATE TABLE `payment` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `serial` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

2.6 entities实体层

2.6.1 Payment.java

package com.node.entities;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Payment {
    private long id;
    private String serial;
}

2.6.2 CommonResult.java

package com.node.entities;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 传给前端通用的json数据类(Json封装体CommonResult)
 */
@Data
@AllArgsConstructor
@NoArgsConstructor

public class CommonResult<T> {
    // 404 丢失
    private Integer code;  //编码
    private String message; //提示
    private  T data; 泛型T,代表着返回的对应的是哪一个实体类(表数据)

    public CommonResult(Integer code,String message){
        this(code,message,null);
    }
}

2.7 Dao层

2.7.1 PaymentDao.java

package com.node.dao;

import com.node.entities.Payment;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
//或@Repository
public interface PaymentDao {
    /**
     * 添加数据
     * @param payment
     * @return
     */
     public int create(Payment payment);

    /**
     * 根据id查找数据
     * @param id
     * @return
     */
     public Payment getPaymentId(@Param("id") Long id); //#{id] 获取 字符串用${} 获取
}

2.7.2 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.node.dao.PaymentDao">

<!--parameterType 传入的值-->
<!--useGeneratedKeys: 如果是true 返回一个id(keyProperty)  所以这个方法返回值为int 型    -->
<insert id="create" parameterType="Payment" useGeneratedKeys="true" keyProperty="id">
    insert into payment(serial) value (#{serial});
</insert>

<!--由于数据库用些表用用‘_’,所以需要一个resultMap来映射对应数据库字段和实体类属性-->
<!--colum对应数据库字段(pay_name),property对应实体类属性(payName),javaType对应数据库字段类型-->
    <resultMap id="BaseResultMap" type="com.node.entities.Payment">
        <id column="id" property="id" javaType="BIGINT"/>
        <id column="serial" property="serial" javaType="VARCHAR"/>
    </resultMap>
    <select id="getPaymentById" parameterType="Long" resultMap="BaseResultMap">
        select * from payment where id=#{id};
    </select>


</mapper>

2.8 Service层

2.8.1 PaymentService.java

package com.node.service;

import com.node.entities.Payment;
import org.apache.ibatis.annotations.Param;

public interface PaymentService {

    public int create(Payment payment); //写

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

2.8.2 PaymentServiceImpl.java

package com.node.service;

import com.node.dao.PaymentDao;
import com.node.entities.Payment;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class PaymentServiceImpl implements PaymentService{

    @Resource
    private PaymentDao paymentDao;

    @Override
    public int create(Payment payment) {
        return paymentDao.create(payment);
    }

    @Override
    public Payment getPaymentById(Long id) {
        return paymentDao.getPaymentId(id);
    }
}

2.9 Controller层

2.9.1 PaymentController.java

package com.node.controller;

import com.node.entities.CommonResult;
import com.node.entities.Payment;
import com.node.service.PaymentServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

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

    //localhost:8001/Payment/create?=002
    /*
    * Rest风格:@PostMapping不能用于ip地址测试 所以需要普通的RequestMapping
    *          如果使用@PostMapping,只能在Postman中则需要Post请求才能插入
    * */
    @RequestMapping(value = "/Payment/create")  
    public CommonResult create(Payment payment){
        int result=paymentService.create(payment);
        log.info("****插入结果: "+result);
        if (result>0){
            return new CommonResult(200,"插入成功",result);
        }else {
           return new CommonResult(500,"插入失败",result);
        }
    }

    @GetMapping(value = "/Payment/get/{id}")  //Rest分格
    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(500,"没有对应记录",payment);
        }
    }
}

2.10 测试

在这里插入图片描述
在这里插入图片描述

3.热部署自动化配置

修改完代码后不需要每次都关闭再重启项目。热部署不需要重启就会自动更新项目
不好的地方是,对电脑内存配置较高。且应该在开发阶段使用,实际上线不该使用

3.1 Pom.xml

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <version> 2.3.6.RELEASE</version>
        </dependency>

3.2 开启自动编译选项

在这里插入图片描述

3.3 开启修改自动run

Ctrl+Shift+Alt+/
在这里插入图片描述

在这里插入图片描述

3.4重启即可

4.消费者订单模块80

要求:调用支付模块8001的数据

4.1 创建Maven项目_子工程

<dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web  -->
        <!-- 监控,启动可看-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

4.2 OrderMain80.java

package com.node;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

4.3 application.yml

server:
  port: 80

4.4 entities实体层

与支付模块payment8001一致

4.5 RestTemlate

RestTemplate 是从 Spring3.0 开始支持的一个 HTTP 请求工具,它提供了常见的REST请求方案的模版用于便捷访问远程Http服务的方法,例如 GET 请求、POST 请求、PUT 请求、DELETE 请求以及一些通用的请求执行方法 exchange 以及 execute。RestTemplate 继承自 InterceptingHttpAccessor 并且实现了 RestOperations 接口,其中 RestOperations 接口定义了基本的 RESTful 操作,这些操作在 RestTemplate 中都得到了实现。

使用restTemplate访问restful接口非常的简单粗暴无脑。(url, requestMap, ResponseBean.class)这三个参数分别代表REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。

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

4.6 config层

4.6.1 ApplicationContextConfig.java

package com.node.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ApplicationContextConfig {
    @Bean
   	@LoadBalanced //开启负载均衡的功能
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

4.7 Controller层

4.8 OrderController.java

package com.node.controller;

import com.node.entities.CommonResult;
import com.node.entities.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

@RestController
@Slf4j
public class OrderController {

    public static final String PAYMENT_URL="http://localhost:8001";

    @Resource
    private RestTemplate restTemplate;


    @PostMapping("/consumer/Payment/create") //用 @PostMapping就要使用@RequestBody请求体
    public CommonResult<Payment> create(@RequestBody Payment payment){
        //(url, requestMap, ResponseBean.class)这三个参数分别代表REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。
        return restTemplate.postForObject(PAYMENT_URL+"/Payment/create",payment,CommonResult.class);
    }
    /*
     * Rest风格:@PostMapping不能用于ip地址测试 所以需要普通的RequestMapping
     *          如果使用@PostMapping,只能在Postman中则需要Post请求才能插入
     * */
    @RequestMapping("/consumer/Payment/get/{id}")
    public CommonResult<Payment> getPayment(@PathVariable("id") Long id){
        return restTemplate.getForObject(PAYMENT_URL+"/Payment/get/"+id,CommonResult.class);
    }
}

4.8 测试

在这里插入图片描述

在这里插入图片描述

8.重构

在这里插入图片描述

目的:由于代码中有重复的类或代码(从上可知重复的实体类),则需重构只写一次

8.1 新建一个工程——cloud-api-commons

8.1.1 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>SpringCloud</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-api-commons</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools -->
        <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>

        <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.1.0</version>
        </dependency>
    </dependencies>
</project>

8.1.2 把实体类移到工具工程且把其他项目删除

在这里插入图片描述

8.1.3 各个工程添加Pom.xml

<!--调用工具工程的项目内容-->
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>

在这里插入图片描述

8.1.4 测试

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值