Spring Cloud框架(原生Hoxton版本与Spring Cloud Alibaba)基础入门篇 ---- 搭建环境

2022-12-01 15:08:51 浏览数 (1)

springcloud官方文档(Hoxton SR5):https://cloud.spring.io/spring-cloud-static/Hoxton.SR5/reference/htmlsingle/ springcloud中文文档:https://www.springcloud.cc/ springcloud中国社区文档:http://docs.springcloud.cn/ https://www.bookstack.cn/read/spring-cloud-docs/docs-index.md

目录

  • 一、Spring Cloud简介
    • SpringCloud是分布式微服务架构的一站式解决方案,是多种微服务架构落地技术的集合体,俗称微服务全家桶
    • Spring Cloud 与 Spring Boot版本依赖关系
    • 学习环境版本
    • 关于Cloud各种组件的停更/升级/替换
  • 二、微服务架构编码实现
    • 搭建微服务总体父工程
    • 父工程pom文件
    • Rest微服务工程构建
      • 1.微服务提供者支付module模块cloud-provider-payment8001
        • 创建模块
        • 添加依赖树
        • 编写yml文件
        • 编写主启动类
        • 编写业务类
        • 测试
      • 2.热部署Dev-tools
      • 3.微服务消费者订单module模块cloud-consumer-order80
      • 4.工程重构

一、Spring Cloud简介

Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring Cloud并没有重复制造轮子,它只是将各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。

Spring Cloud专注于为典型的用例和扩展机制提供良好的开箱即用体验,以涵盖其他情况。

  • 分布式/版本化配置
  • 服务注册和发现
  • 路由
  • 服务到服务的呼叫
  • 负载均衡
  • 断路器
  • 分布式消息传递

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

京东内部微服务架构

通用微服务技术栈

Spring Cloud 与 Spring Boot版本依赖关系

Spring cloud 官网地址:https://spring.io/projects/spring-cloud

学习环境版本

  • jdk 1.8
  • maven 3,5 以上
  • mysql 5.7 以上
  • Spring Cloud Hoxton.SR1
  • Spring Cloud Alibaba 2.1.0
  • Spring Boot 2.2.2

关于Cloud各种组件的停更/升级/替换

二、微服务架构编码实现

约定>配置>编码

搭建微服务总体父工程

  1. Create New Project
  1. 填写工程名

3. 勾选本地maven

4.设置项目编码

5.设置注解激活生效

6.Java编译版本修改

父工程pom文件

代码语言:javascript复制
<packaging>pom</packaging>

项目所需的所有依赖树

代码语言:javascript复制
<?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.zhao.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>
        <lombok.version>1.18.10</lombok.version>
        <log4j.version>1.2.17</log4j.version>
        <mysql.version>8.0.18</mysql.version>
        <druid.version>1.1.20</druid.version>
        <mybatis.spring.boot.version>1.3.2</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-->
            <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>
                <scope>runtime</scope>
            </dependency>
            <!-- druid-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>${druid.version}</version>
            </dependency>

            <!--mybatis-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.spring.boot.version}</version>
            </dependency>
            <!--junit-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
            </dependency>
            <!--log4j-->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j.version}</version>
            </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>

Maven中dependencyManagement与dependencies区别

子项目中,如果不指定,默认和父项目dependencyManagement标签中的版本一致,并且父项目dependencyManagement标签只是规定了版本号,具体引入依赖还是子项目引入。

maven中跳过单元测试:

Rest微服务工程构建

最简单的支付模块

构建步骤:

  1. 建module
  2. 改pom
  3. 写yml
  4. 主启动
  5. 业务类
  6. 测试

1.微服务提供者支付module模块cloud-provider-payment8001

创建模块

填写模块名

创建完成

添加依赖树
代码语言:javascript复制
<?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.zhao.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-provider-payment-8001</artifactId>


    <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.2.8</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>
        <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>
</project>
编写yml文件
代码语言:javascript复制
server:
  port: 8001

spring:
  application:
    name: cloud-payment-service
    #数据库配置
    datasource:
      type: com.alibaba.druid.pool.DruidDataSource
      #mysql5.x的没有cj
      driver-class-name: com.mysql.cj.jdbc.Driver
      #记得先创建数据库
      url: jdbc:mysql://localhost:3306/db2020?useUnicode=true&characterEncoding=utf-8&useSSL=false
      username: root
      password: 123456

    #mybatis配置
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.zhao.springcloud.entities  #所有Entity别名类所在包
编写主启动类
代码语言:javascript复制
@SpringBootApplication
public class PaymentMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentMain8001.class);
    }
}
编写业务类

1.创建数据库

代码语言:javascript复制
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;

INSERT INTO payment(`serial`)VALUES("xxx");

2.创建实体类

代码语言:javascript复制
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PayMent implements Serializable {
    private Long id;
    private String serial;
   
}

返回前端的json数据对象

代码语言:javascript复制
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult<T> {
    private Integer code;
    private String message;
    private T data;

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

3.持久化层(dao) 持久化层接口:

代码语言:javascript复制
@Mapper
public interface PaymentDao {

    int add(Payment payment);

    //  加上@Param注解,mapper中就可以采用#{}的方式把@Param注解括号内的参数进行引用
    Payment getPaymentById(@Param("id") Long id);
}

mapper.xml文件

代码语言:javascript复制
<?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.zhao.springcloud.dao.PaymentDao">

    <insert id="add" parameterType="com.zhao.springcloud.entities.Payment" useGeneratedKeys="true" keyProperty="id">
        insert into payment(serial) value (#{serial})
    </insert>

    <select id="getPaymentById" parameterType="long" resultMap="BaseResultMap">
        select * from payment where id = #{id}
    </select>
    <resultMap id="BaseResultMap" type="com.zhao.springcloud.entities.Payment">
        <!--column 数据库字段   property Java字段-->
        <id column="id" property="id" jdbcType="BIGINT"></id>
        <result column="serial" property="serial" jdbcType="VARCHAR" />
    </resultMap>
</mapper>

4.服务层(service) 服务层接口

代码语言:javascript复制
public interface PaymentService {

    int add(Payment payment);

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

}

实现类

代码语言:javascript复制
@Service
public class PaymentServiceImpl implements PaymentService {

    @Resource
    private PaymentDao paymentDao;

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

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

5.控制器(controller)

代码语言:javascript复制
@RestController
@Slf4j
public class PaymentController {
    @Resource
    private PaymentService paymentService;

    @PostMapping("/payment/add")
    public CommonResult<Payment> add(@RequestBody Payment payment){
        int result = paymentService.add(payment);
        log.info("******插入结果:" result);
        if (result>0){
            return new CommonResult(200,"插入数据库成功",result);
        }else {
            return new CommonResult(444,"插入数据库失败",null);
        }
    }

    @GetMapping("/payment/get/{id}")
    public CommonResult<Payment> 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);
        }
    }

}
测试

启动项目,浏览器输入http://localhost:8001/payment/get/1,查询成功

因为浏览器一般不支持直接发送post请求,所以,需要使用工具apiPost进行测试

输入http://localhost:8001/payment/add发送post请求,往数据库中插入一条数据,需要把数据写到body中。

2.热部署Dev-tools

子工程添加依赖

代码语言:javascript复制
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

父工程添加插件

代码语言:javascript复制
    <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>

开启自动编译的权限

热键注册开启

重启IDEA即可生效!!

3.微服务消费者订单module模块cloud-consumer-order80

新建模块

添加依赖

代码语言:javascript复制
  <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>

新建yml文件

代码语言:javascript复制
server:
  port: 80

主启动类

代码语言:javascript复制
@SpringBootApplication
public class OrderMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderMain80.class);
    }
}

业务类 ① 复制cloud-provider-payment8001项目里的entities

② 添加配置类

代码语言:javascript复制
@Configuration
public class ApplicationContextConfig {

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

③ 创建controller

代码语言:javascript复制
@RestController
@Slf4j
public class OrderController {

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

    @Resource
    private RestTemplate restTemplate;

    @GetMapping("/consumer/payment/add")
    public CommonResult<Payment> add(Payment payment){
        return restTemplate.postForObject(PAYMENT_URL "/payment/add",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);
    }
}

测试

启动两个项目进行测试,两个都启动后,右下角会弹出个services提示,点击show。

用户支付订单,服务与服务之间的调用,输入地址http://localhost/consumer/payment/get/1,查询成功

添加操作在页面上显示添加成功,查看数据库数据正常

4.工程重构

由于目前构建的两个微服务项目有重复的部分,需要将其提取出来,一次打包,到处运行,所以将项目进行重构。

新建模块

添加依赖

代码语言:javascript复制
   <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>
        <!--   一个Java工具包     -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.1</version>
        </dependency>
    </dependencies>

将实体类放入commons模块

本项目进行打包

删除 80 和 8001中的实体,引入自定义的依赖

代码语言:javascript复制
        <!--引入自定义的api通用包,使用payment实体-->
        <dependency>
            <groupId>com.zhao.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

重新启动,并测试

查询数据成功!

插入数据成功!

至此,Spring Cloud框架(原生Hoxton版本与Spring Cloud Alibaba)基础入门篇 就结束了

0 人点赞