springcloud学习笔记day01

本文介绍了Java8+Maven+Git等技术栈在微服务架构中的应用,涵盖了SpringBoot 2.2.2与SpringCloud Hoxton.SR1的版本选择,以及SpringCloud组件如服务注册、调用、配置等的详细解读。还展示了微服务架构在京东、阿里的实际案例。通过实践步骤,演示了如何构建微服务项目并进行模块化管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.技术要求:

java8+mven+git、github+Nginx+RabbitMQ+SpringBoot2.0

2.JVM/JUC/JMM/GC/Nginx……

2.微服务架构理论入门

2.1.微服务架构概述

什么是微服务?

image-20210614153704407

微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在器独立的进程中,服务与服务建采用轻量级的通信机制互相协作(通常是基于HTTP协议的RESTful API)。每个服务都围绕着具体业务进行构建,并且能够被独立的部署到生产环境、类生产环境等等。另外,应当尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。

image-20210614154245153

img001

主题词:基于分布式的微服务架构

满足哪些维度?

支持起这些维度的具体技术????

springcloud官网

image-20210614154742347

融合协调组装一切,使构建分布式系统更加容易。

image-20210614155012045

2.2.SpringCloud简介

什么是SpringCloud?

SpringCloud 分布式微服务架构的一站式解决方案,是多种微服务架构落地技术的集合体,俗称微服务全家桶。

SpringCloud这个大集合里有多少种技术?

image-20210614161055310

SpringCloud俨然已成为微服务开发的主流技术栈,在国内开发者社区非常火爆。

"微"力十足,互联网大厂微服务架构案例

京东促销节

image-20210614161341426

阿里

image-20210614161458673

京东物流

image-20210614161538412

image-20210614161639902

2.3.SpringCloud技术栈

各个技术栈功能介绍

image-20210614161831422

image-20210614162018896

总结回顾

image-20210614162149667

SpringCloud通过网关调用负载均衡,每个微服务A、B、C来进行调度。

3.Boot和Cloud版本选型

SpringBoot是一种技术;SpringCloud是分布式微服务架构的一揽子解决方案,有多种技术落地。

3.1.SpringBoot版本选择

git源码地址 : https://github.com/spring-projects/spring-boot/releases/

SpringBoot2.0新特性

https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Release-Notes

通过上面官网发现,Boot官方强烈建议你升级到2.X以上的版本。

image-20210614165233301

官网看Boot版本

3.2.SpringCloud版本选择

git源码地址:https://github.com/spring-projects/spring-cloud/wiki

官网: https://spring.io/projects/spring-cloud

官网看Cloud版本

Cloud命名规则

SpringCloud的版本关系

Spring Cloud 采用了英国伦敦地铁站的名称来明明,并由地铁站名称字母A-Z依次类推的形式来发布迭代版本。
SpringCloud是一个由许多子项目组成的综合项目,各子项目有不同的发布节奏。为了管理SpringCloud与各子项目的版本依赖关系,发布了一个清单,其中包括了某个SpringCloud版本对应的子项目版本。为了避免SpringCloud版本号与子项目版本号混淆,SpringCloud版本采用了名称而非版本号的明明,这些版本的名字采用了伦敦地铁站的名字,根据字母表的顺序来对应版本事件顺序。例如Angel是第一个版本,Brixton是第二个版本。
当SpringCloud的发布内容积累到临界点或者一个重大BUG被解决后,会发布一个"service release"版本,简称SRX版本,比如Greewich.SR2就是SpringCloud发布的Greenwich版本的第2个SRX版本。

3.3.SpringCloud和SpringBoot之间的依赖关系

https://spring.io/projects/spring-cloud#overview/

image-20210614170910746

更详细的版本对应查看方法

https://start.spring.io/actuator/info

打开一个在线的json处理工具https://tool.lu/json,将上面查询到的json串粘贴格式化

image-20210614171950244

查看json串返回结果

3.4.本次开发的版本选择

cloud ——》Hoxton.SR1

boot ——》 2.2.2.RELEASE

cloud ——》 2.1.0.RELEASE

Java ——》 Java8

Maven ——》3.5及以上

Mysql ——》 5.7及以上

只用boot,直接用最新

同时用boot和cloud,需要照顾cloud,由cloud决定boot版本

image-20210614173051757

SpringCloud和SpringBoot版本对应关系

3.5. 2.X版本常用的组件pom

<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>
</dependencies>

4.Cloud组件停更说明

停更不停用:

  • 被动修复bugs
  • 不再接受合并请求
  • 不再发布新版本

Cloud升级

  • 服务注册中心

    • × Eureka
    • √ Zookeeper
    • √ Consul
    • √ Nacos
  • 服务调用

    • √ Ribbon
    • √ LoadBalancer
  • 服务调用2

    • × Feign
    • √ OpenFeign
  • 服务降级

    • × Hystrix
    • √ resilience4j
    • √ sentinel
  • 服务网关

    • × Zuul
    • ! Zuul2
    • √ gateway
  • 服务配置

    • × Config
    • apolo (主要是上海携程开源后用的比较不错)
    • √ Nacos (推荐使用)
  • 服务总线

    • × Bus
    • √ Nacos

image-20210614212427235

参考资料见官网

SpringCloud

​ H版文档:https://cloud.spring.io/spring-cloud-static/Hoxton.SR1/reference/htmlsingle/

​ SpringCloud中文文档 : https://www.bookstack.cn/read/spring-cloud-docs/docs-index.md

SpringBoot

​ https://docs.spring.io/spring-boot/docs/2.2.2.RELEASE/reference/htmlsingle/

5.父工程Project空间构建

微服务架构编码构建

5.1编程风格

约定 > 配置 > 编码

约定:硬性的举例:Java编程规范、Sql编程规范、Git的提交流程、Sql编写的大小写敏感程度。

配置:分布式微服务架构的组件,比如说服务注册中心用的是Eureka还是Nacos,服务降级熔断框架用的是Hystrix还是sentinel。

做好这些配置和约定,也就是说大环境配置好了,再进行编码。

5.2.IDEA新建project工作空间

5.2.1.微服务cloud整体聚合父工程Project
父工程步骤

image-20210614214750356

1.【New Project】–》【Maven】–》【Project SDK 1.8】–》【Create from archetype】–》【org.apache.maven.archetypes:maven-archetype-site】–》【Next】

image-20210614215537178

2.聚合总父工程名字

GroupId :com.fan.springcloud

ArtifactId:cloud2020

Version:1.0-SNAPSHOT

image-20210614220052106

3.maven选版本,选择自己的

image-20210614220210060

4.工程名字

image-20210614220810723

5.字符编码

image-20210614221149024

6.注解生效激活

image-20210614221924561

7.java编译版本选8

image-20210614222127966

8.File Type过滤

image-20210614222342715

这一步可选,也可以不操作。

5.2.2.父工程POM

1.删掉父工程的src目录,只保留pom.xml

2.在pom.xml中添加打包方式

<packaging>pom</packaging>

父工程只有一个总的pom.xml文件,通过dependencyManager标签,进行一些子模块来继承父工程,拥有统一的版本号。

3.统一设置依赖版本号,添加依赖

<?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.fan.springcloud</groupId>
  <artifactId>cloud2020</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.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>

  <!-- 子模块继承之后,提供作用:锁定版本+子module不用写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>
      <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
      <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>${mysql.version}</version>
      </dependency>
      <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
      <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>${druid.version}</version>
      </dependency>

      <!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
      <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>${mybatis.spring.boot.version}</version>
      </dependency>
      <!-- https://mvnrepository.com/artifact/junit/junit -->
      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>${junit.version}</version>
        <scope>test</scope>
      </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>
        <version>2.2.2.RELEASE</version>
        <configuration>
          <fork>true</fork>
          <addResources>true</addResources>
        </configuration>
      </plugin>
    </plugins>
  </build>

</project>

5.2.3.Maven工程落地 细节复习
1.Maven中的DependencyManagement和Dependencies

Maven 使用dependencyManagement 元素来提供了一种管理依赖版本号的方式

通常会在一个组织或者项目的最顶层的父POM中看到dependencyManagement元素

使用pom.xml中的dependencyManagement元素能让所有子项目中引用一个依赖而不用显式的列出版本号。

Maven会沿着父子项目向上走,直到找到一个拥有dependencyManagement元素的项目,然后它就会使用这个dependencyManagement元素中指定的版本号。

例如在父项目里:

xml代码:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.20</version>
        </dependency>
        ......
    </dependencies>
</dependencyManagement>

然后在子项目里就可以添加mysql-connector时就可以不指定版本号,例如:

xml代码:

<dependencies>
    <dependency>
    	<groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
</dependencies>

这样做的好处是:如果有多个子项目都引用同一样的依赖,则可以避免在每个使用的子项目里都声明一个版本号,这样当想升级或切换到另一个版本时,只需要在顶层父容器里更新,而不需要一个一个子项目的修改;另外如果某个子项目需要另外的一个版本,只需要声明version就可。

  • dependencyManagement 里只是声明依赖,并不实现引入,因此子项目需要显示的声明要用的依赖。
  • 如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom;
  • 如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。
2.maven中跳过单元测试

点击像闪电一样的标志,【Toggle ‘Skip Tests’ Mode】

image-20210702155333643

点击该标志的话,test会有个删除线,即maven跳过单元测试

image-20210702155543521

5.2.4.父工程创建完成执行mvn:install将父工程发布到仓库方便子工程继成

选中install,点击 【Run Maven Build】的标志

image-20210702160626303

控制台看到 BUILD SUCCESS,说明本机的maven和IDEA的整合是OK的。

image-20210702160857022

如果不需要,点击 clean, 点击【Run Maven Build】的标志

image-20210702161039908

image-20210702161055336

以后如果发布一些包给其他工程公用的时候,可以先 clean,再install

6.支付模块

订单调用支付模块。

image-20210702165305714

微服务工程构建步骤:

1.建Module

2.改POM

3.写YML

4.主启动

5.业务类

1.建Module

新建cloud-provider-payment8001 微服务提供者支付模块Module模块.

创建完成后请回到父工程查看pom文件变化

<modules>
	<module>cloud-provider-payment8001</module>
</modules>

image-20210702170526623

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.fan.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>
        <!-- mybatis和springboot的整合 -->
        <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.10</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>

spring-boot-starter-web 和 spring-boot-starter-actuator
几乎是永远绑定到一起的,后面的图形化显示、坐标监控和图形处理等比较重要。

3.写YML

在resources目录下新建application.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
  type-aliases-package: com.fan.springcloud.entities  # 所有Entity别名类所在包

补充:

springboot官方是支持yml格式,其实用properties文件也是可以的。

4.主启动

package com.fan.springcloud;

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);
    }
}

5.业务类

1.建表SQL
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=utf8mb4
2.entities

主实体 Payment

package com.fan.springcloud.entities;

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

import java.io.Serializable;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Payment implements Serializable { //将实体类序列化,后面分布式部署可能会用得到
    private Long id;
    private String serial;
}

Json封装体CommonResult

package com.fan.springcloud.entities;

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

/**
 * 返回给前端的通用的Json实体串
 * @param <T>
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult<T> {
    private Integer code;
    private String message;
    private T      data; //返回的实体类

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

3.dao

接口PaymentDao

package com.fan.springcloud.dao;

import com.fan.springcloud.entities.Payment;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

@Mapper
public interface PaymentDao {
    public int create(Payment payment); //写操作

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

新增:add 、save、create

在resources目录下新建mapper目录。

mybatis的映射文件PaymentMapper.xml

路径:src\main\resources\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.fan.springcloud.dao.PaymentDao">

    <insert id="create" parameterType="Payment" useGeneratedKeys="true" keyProperty="id">
        insert into payment(serial) values(#{serial})
    </insert>

    <resultMap id="BaseResultMap" type="com.fan.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

接口PaymentService

package com.fan.springcloud.service;

import com.fan.springcloud.entities.Payment;
import org.apache.ibatis.annotations.Param;

public interface PaymentService {
    public int create(Payment payment); //写操作

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

实现类

package com.fan.springcloud.service.impl;

import com.fan.springcloud.dao.PaymentDao;
import com.fan.springcloud.entities.Payment;
import com.fan.springcloud.service.PaymentService;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class PaymentServiceImpl implements PaymentService {
    @Resource
    private PaymentDao paymentDao;

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

    public Payment getPaymentById(@Param("id") Long id){
        return paymentDao.getPaymentById(id);
    }
}

5.controller
package com.fan.springcloud.controller;

import com.fan.springcloud.entities.CommonResult;
import com.fan.springcloud.entities.Payment;
import com.fan.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
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 javax.annotation.Resource;

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

    @PostMapping(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(444,"插入数据库失败",result);
        }
    }

    @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,null);
        }
    }
}

6.测试

启动微服务,看下写操作和查询操作能不能插入成功并且查询出来。

保证测试成功,在数据库里插入一条记录。

insert into payment(id,serial) values(31,"Jack");

启动微服务,启动成功后,在浏览器中访问http://localhost:8080/payment/get/31

image-20210702195937940

Postman测试:http://localhost:8001/payment/create?serial=at002

{
    "code": 200,
    "message": "插入数据库成功",
    "data": 1
}

然后在数据库里查看是否插入数据库成功。

浏览器对post请求不支持,使用Postman工具进行模拟post测试

运行

1.通过修改idea的workspace.xml的方式快速打开Run DashBoard窗口

选中项目,右键 Show in Explorer,打开项目所在的本地目录中的idea中的workspace.xml

image-20210702233313451

你自己路径:E:\code\springcloud\cloud2020.idea

ctrl + F,查找定位到 RunDashboard,添加如下代码

<option name="configurationTypes">
	<set>
    	<option value="SpringBootApplicationConfigurationType"/>
    </set>
</option>

image-20210702233812511

2.开启Run DashBoard

如果自动出现Run DashBoard的窗口,打开View ——》Tool Windows ——》出现Run Dashboard

image-20210702234030262

3.不同的人由于idea版本不同,需要关闭重启

7.总结

1.建module

2.改POM

3.写YML

4.主启动

5.业务类

7.热部署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>你自己的工程名字</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

image-20210702211257184

4.Update the value of

快捷键 ctrl + shift + alt + / ,选择 Registry…

image-20210702211453956

勾选

  • compiler.automake.allow.when.app.running
  • actionSystem.assertFocusAccessFromEdt

image-20210702213602820

5.重启IDEA

修改代码后,可以观察控制台可以看到重启

image-20210702214034800

开发阶段必须开启热部署,实际上线生产部署之后,必须关闭热部署。

8.消费者订单模块

1.建Module

cloud-consumer-order80

微服务消费者订单Module模块

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.fan.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-consumer-order80</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.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>

3.写YML

application.yml

server:
  port: 80

image-20210702215540112

客户端用户消费者这边都是用80端口,正常的微服务都会绑定一个服务端口,而且不用给用户添加80端口,比如你搜百度 www.baidu.com。模拟用户下订单,不用去关心端口号。

4.主启动

package com.fan.springcloud;

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);
    }
}

5.业务类

80客户端这边只应该有controller层。

1.entities实体类

主实体 Payment

package com.fan.springcloud.entities;

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

import java.io.Serializable;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Payment implements Serializable { 
    private Long id;
    private String serial;
}

Json封装体CommonResult

package com.fan.springcloud.entities;

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

@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult<T> {
    private Integer code;
    private String message;
    private T      data; 

    public CommonResult(Integer code,String message){
        this(code,message,null);
    }
}
2.首说RestTemplate

image-20210702220709328

两个服务之间进行调用,在最原始阶段是使用的技术是 httpClient。

现在封装之后,需要用到 restTemplate,相当于将httpClient做了一次封装,实现了订单微服务和支付微服务之间的横向调用。

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响应被转换成的对象类型。

3.config配置类

ApplicationContextConfig类

package com.fan.springcloud.config;

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

@Configuration
public class ApplicationContextConfig {

    @Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

4.controller
package com.fan.springcloud.controller;

import com.fan.springcloud.entities.CommonResult;
import com.fan.springcloud.entities.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
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;

    @GetMapping("/consumer/payment/create")
    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);
    }

}

5.测试

启动cloud-consumer-order80(微服务的消费者)与cloud-provider-payment8001(微服务的提供者)。

订单消费者下订单调用支付服务。

启动多个微服务的时候,会出现Run Dashboard的窗口,点击 Show run configurations in Run Dashboard.

image-20210702224622418

image-20210702224707476

image-20210702230251531

在浏览器中访问http://localhost:8001/payment/get/31

image-20210702230532768

消费者微服务调用支付微服务: http://localhost/consumer/payment/get/31

image-20210702230507144

消费者由于是80端口,可以不用写端口号,不需要知道端口的概念。

读操作完成。

测试写操作

http://localhost/consumer/payment/create?serial=111

image-20210702231121287

查询数据库,可以发现数据并没有插入成功

image-20210702231230280

不要忘记@RequestBody注解

找到8001项目中的PaymentController。

image-20210702232302650

访问 http://localhost/consumer/payment/create?serial=111

image-20210702232446776

观察数据库,发现数据插入成功

image-20210702232519911

9.工程重构

现在80和8001中有重复的实体类,代码冗余。现在要进行工程重构的话,把重复的代码文件,比如重复的实体类提出来,形成我们自己的jar包,打成一份,一处部署,处处通用。

1.观察问题

系统中有重复的代码,重构

image-20210702234757819

解决:将相同相似的重复的代码,提取到公开公用的工程中,供大家统一调配使用。比如公用的实体类,服务接口,第三方接口,工具类都可以放在公用的工程中。

新建工程Module,命名为 cloud-api-commons

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.fan.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>

3.entities

将cloud-consumer-order80与cloud-provider-payment8001的公有entities包移动到cloud-api-commons工程下,删掉80和8001中的entities

4.maven命令 clean install

现在需要把公用模块maven打包发布上传到公用的本地库里,供其他工程调用。

选中公用的工程,跳过测试步骤,点击clean,然后install到本地库。BUILD SUCCESS打包发布成功。

如果没有发布成功,点击m的标志,在输入框中输入 mvn clean install,点击Execute即可。

5.订单80和支付8001分别改造

删除各自的原先有过的entities文件夹

各自粘贴POM内容

<!--引入自己定义的api通用包,可以使用Payment支付Entity-->
<dependency>
    <groupId>com.fan.springcloud</groupId>
    <artifactId>cloud-api-commons</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

80

<?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.fan.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.fan.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</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>

8001

<?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.fan.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

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

    <dependencies>
        <!--引入自己定义的api通用包,可以使用Payment支付Entity-->
        <dependency>
            <groupId>com.fan.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</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>
        <!-- mybatis和springboot的整合 -->
        <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.10</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>

6.测试

测试访问,检查下是否可以插入数据库成功

下一篇:springcloud学习笔记day02——Eureka

教学视频 p01~p14

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值