SpringCloud(一):SpringBoot、SpringCloud版本选择,微服务架构编码构建

在学习SpringCloud之前,我认为需要先去了解微服务的概念

参考:


目录

在学习SpringCloud之前,我认为需要先去了解微服务的概念

SpringCloud是什么?

SpringBoot、SpringCloud版本选择

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

微服务架构编码构建

IDEA创建project工作空间

父工程的Pom.xml的说明以及Maven细节复习

Rest微服务工程构建

支付模块的构建 cloud-provider-payment8001

cloud-provider-payment8001 的测试


本次学习参考:尚硅谷2020最新版SpringCloud(H版&alibaba)框架开发教程全套完整版从入门到精通(大牛讲授spring cloud)

强烈推荐这个SpringCloud学习视频,深入浅出,细致入微。

本次学习线路图:


 

SpringCloud是什么?

Spring Cloud是一套完整的微服务解决方案,基于Spring Boot框架,准确的说,它不是一个框架而是一个容器,它将市面上较好的微服务框架集成进来,从而简化了开发者的代码量。

一个微服务系统,它所需要包含的功能,Spring Cloud都帮忙集成了。

SpringBoot、SpringCloud版本选择

SpringBoot的版本更迭非常快,在SpringBoot2.0发布以后官方就强烈建议从SpringBoot1.5 升级到2.X以上的版本了。

在2020年这一年如果在经历SpringBoot的开发的人会有很明显的感觉,2、3月份用的SpringBoot2.2.1,用着用着发现到现在发现版本就变成了2.3。

技术的选型不是非要用最新的版本,SpringCloud的版本和SpringBoot的版本有着密切关系

SpringCloud的版本不是以数字编排的,而是使用了伦敦地铁站的站名,并且名称是按字母顺序排列的。比如Angel是第一个版本,Brixton是第二个版本。当SpringCloud的发布内容累计到临界点或者一个重大Bug被解决以后,会发布 "service release"版本,简称SRX版本。比如Greenwich.SR2就是SpringCloud发布的Greenwich版本的第二个SRX版本。

在写本文的时候,SpringCloud已更新到 HoxtonSR4的版本,SpringBoot更新到2.3.0的版本,那么都用最新的可以吗?

也不是那样的,SpringBoot和SpringCloud的版本有约束、有冲突,需要严格按照官网。 

SpringCloud官方文档:这上面写了,如果是Hoxton的版本,那么最好是2.2.x的版本。

2.2.x的版本看起来太模糊了,这里还有更详细的版本对应查看方法:https://start.spring.io/actuator/info,这里面是Json格式的数据,需要通过Json解析出来。通过Json解析以后,可以看到更详细的版本对应。

目前的最新的版本是SpringCloud Hoxton.SR4的版本要求SpringBoot的版本大于等于2.2.0M4并且小于2.3.1.BUILD的版本。

为什么要这么严格呢?因为环境造成的问题总是让人头疼,浪费时间又难定位。所以最好按照官方的说明选择SpringCloud和SpringBoot的版本。

但这依旧不是最后决定选择的版本,在同时使用SpringBoot和SpringCloud的时,需要照顾Cloud的版本,由Cloud决定Boot的版本。

打开官网,查看文档:

按照目前最新的SpringCloud Hoxton.SR4的版本,给予最好支持的是SpringBoot  2.2.5.RELEASE的版本。

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

SpringCloud是微服务的集大成者,里面包含了很多技术,而现在SpringCloud进行了一次大更新,很多技术现在已经不再使用,有了别的替代方案。

红叉的技术几乎已经停止更新了,绿勾的技术是目前的替换方案,虽然现在看着这些技术非常陌生,但接下来都是学习的目标。

这里先仅作为了解。

微服务架构编码构建

IDEA创建project工作空间

微服务cloud整体聚合父工程Project,万物之初,环境得搞好,父工程步骤:

  • New Project
    • 聚合总工程名字
    • Maven 选择版本
  • 字符编码
  • 注解生效激活
  • java编译版本选择
  • File Type过滤(可选)

新建一个Maven工程,这里选择的是 org.apache.maven.archetypes:maven-archetype-site 这个模板

确定好聚合总工程的名字 

选择Maven版本,请选择3.5及以上的版本。

 在Editor-File Encoding里确定好字符编码,这里统一为UTF-8

在Build,Execution,Deployment-compiler-Annotation Processors 把 Enable annotation processing打钩,使注解生效激活 。

(百度了一下这个设置主要是为lombok所使用)

java版本的选择,新建的工程这里默认为1.5的话,这里需要改成对应的版本。

File Types的设置,IDEA自动生成的.idea和.iml 文件看着很烦,用File types忽略掉它们。

这样,父工程就搭建好了。

父工程的Pom.xml的说明以及Maven细节复习

有几点需要注意:

  •  <packaging>pom</packaging>
    • <packaging>pom</packaging>的意思是使用maven分模块管理,都会有一个父级项目,pom文件一个重要的属性就是packaging(打包类型),一般来说所有的父级项目的packaging都为pom,packaging默认类型jar类型,如果不做配置,maven会将该项目打成jar包。
  • <properties>:
    • 统一管理jar包版本
  • <dependencyManagement>:
    • dependencyManagement用在父工程,子模块继承之后,提供作用:锁定版本+子module不用再写groupId和version
    •  dependencyManagement和dependencies的区别:dependencies即使在子项目中不写该依赖项,那么子项目仍然会从父项目中继承该依赖项(全部继承),dependencyManagement里只是声明依赖,并不实现引入因此子项目需要显示的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom;另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。

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

  • org.springframework.boot、org.springframework.cloud、com.alibaba.cloud是搭建一个SpringCloud工程的必备依赖

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         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.claw</groupId>
    <artifactId>springcloud</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <!--统一管理jar包版本-->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>12</maven.compiler.source>
        <maven.compiler.target>12</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.10</druid.version>
        <mybatis.spring.boot.version>2.1.1</mybatis.spring.boot.version>
    </properties>

    <!--dependencyManagement用在父工程,子模块继承之后,提供作用:锁定版本+子module不用再写groupId和version-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-project-info-reports-plugin</artifactId>
                <version>3.0.0</version>
            </dependency>
            <!--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 阿里巴巴-->
            <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</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>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
            <plugins>
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-site-plugin</artifactId>
                    <version>3.7.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-project-info-reports-plugin</artifactId>
                    <version>3.0.0</version>
                </plugin>
            </plugins>
        </pluginManagement>
        <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>

ok,Project和父工程已经搭建完成,该编码辣。

Rest微服务工程构建

目标:使用订单模块调用支付模块

那么该如何构建呢? 

大步骤:

  1. cloud-provider-payment8001微服务提供者支付Module模块
  2. 热部署Devtools
  3. cloud-consumer-order80微服务消费者订单Module模块

支付模块的构建 cloud-provider-payment8001

构建cloud-provider-payment8001的步骤

  • 建立Module
  • Pom文件的编写
  • 配置文件 application.yaml的编写
  • 主启动
  • 业务类编写

接下来一一讲解:

在父工程的基础上新建一个module,就创建一个普通的Maven工程。

 

cloud-provider-payment8001 的pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         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>com.claw</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.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>

 配置文件 application.yaml

# 端口号
server:
  port: 8001
spring:
  application:
    name: cloud-payment-service
  # 数据库配置  
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/eesy_mybatis?serverTimezone=GMT%2B8&userUnicode=true&characterEncoding=utf-8
    username: root
    password: password
# mybatis 配置
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.claw.springcloud.entities

主启动文件的编写,当然也可以直接创建一个SpringBoot,不知道为什么老师没有这样做。

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

}

接下来该编写业务相关的类了,考虑到前后端分离的情况,我们最终传递给前端的是Json字符串,比如说CommonResult{200,success},200这个数字就是代表执行成功的code,success就是对这个code的补充说明。前端的事情我们暂且先不去管,专注后端的话,那么就是 controller-service-dao-mysql 这四个部分。

所以业务类的编写步骤为:

  • 建表
  • 实体类
    • 主实体Payment
    • Json封装体CommonResult
  • Dao
  • Service
  • Controller

建表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 = utf8

实体类 - 主实体Payment

/**
 * 实体类
 * @author Claw
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Payment {
    private Long id;
    private String serial;
}

实体类 -Json封装类,我们前面已经说到了,考虑到前后端分离情况,我们需要告诉前端的只是结果,所以我们需要正ComonResult这个Json封装类。

/**
 * Json封装
 * @author Claw
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult<T> {

    private Integer code;
    private String message;
    /**
     * 这里泛型的作用:显示我们传入类的信息,比如我们传入的Payment类 就能获取Payment类的信息
     */
    private T data;

    /**
     * 两个参数的构造器
     * @param code
     * @param message
     */
    public CommonResult(Integer code,String message){
        this(code,message,null);
    }
}

dao层:增删改查并不是本次学习的目的,所以现在暂时两个简单的方法,读取的操作和写入的操作


/**
 * Dao 接口
 * @author Claw
 */
@Mapper
public interface PaymentDao {
    /**
     * 读 操作
     * @param payment
     * @return
     */
    public int create(Payment payment);

    /**
     * 写 操作
     * @param id
     * @return
     */
    public Payment getPayment(@Param("id") Long id);
}

Mapper映射文件:

<?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.claw.springcloud.dao.PaymentDao">
    <insert id="create" parameterType="payment" useGeneratedKeys="true" keyProperty="id">
        insert into payment(serial)
        values (#{serial})
    </insert>
    <!--使用结果集进行映射 确保真实开发中字段对应的准确性 -->
    <resultMap id="BaseResultMap" type="com.claw.springcloud.entities.Payment">
        <id column="id" property="id" jdbcType="BIGINT"></id>
        <id column="serial" property="serial" jdbcType="VARCHAR"></id>
    </resultMap>
    <select id="getPayment" parameterType="Long" resultMap="BaseResultMap">
        select *
        from payment
        where id = #{id}
    </select>
</mapper>
 

 

Service层:

/**
 *Service接口
 * @author Claw
 */
public interface PaymentService {
    /**
     * 读 操作
     * @param payment
     * @return
     */
    public int create(Payment payment);

    /**
     * 写 操作
     * @param id
     * @return
     */
    public Payment getPayment(@Param("id") Long id);
}

Service实现类:


/**
 * @author Claw
 */
@Service
public class PaymentServiceImpl implements PaymentService {
    @Resource
    private PaymentDao paymentDao;

    @Override
    public int create(Payment payment) {
        return paymentDao.create(payment);
    }
    @Override
    public Payment getPayment(@Param("id") Long id) {
        return paymentDao.getPayment(id);

    }
}

 Controller层:

/**
 * Controller层
 * @author Claw
 */
@RestController
@Slf4j
public class PaymentController {
    @Resource
    private PaymentServiceImpl paymentService;

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

    @GetMapping("/payment/get/{id}")
    public CommonResult getPaymentById(@PathVariable("id") Long id) {
        Payment payment = paymentService.getPayment(id);
        log.info("----------结果:" + payment);
        if (payment != null) {
            return new CommonResult(200, "查询成功", payment);
        } else {
            return new CommonResult(444, "查询失败", null);
        }
    }
}

cloud-provider-payment8001 的测试

启动启动程序,在浏览器输入访问路径,第一个方法 getPaymentById()已经成功拿到数据

因为create方法是post请求,所以使用了PostMan进行模拟,ok,也执行成功了。

现在我们第一个微服务就写完了~!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值