当前位置 博文首页 > MPolaris:二. SpringCloud基本Rest微服务工程搭建

    MPolaris:二. SpringCloud基本Rest微服务工程搭建

    作者:MPolaris 时间:2021-01-30 19:01

    1. 父工程构建

    1.1 Maven项目搭建
    环境 版本
    JDK 1.8
    Maven 3.6+
    Maven模板 maven-archetype-size
    删除父工程src文件
    1.2 父工程pom文件

    回顾:

    ① Maven中dependencyManagement和dependencies的区别

    ? Maven使用dependencyManagement元素来提供一种管理依赖版本号的方式。通常会在一个组织或者项 目的最顶层的父POM中看到。使用pom.xml中 的dependencyManagement元素能让所有中引用一个依赖而不用显示的列出版本号。Maven会沿着父子层次向上找,直到找到一个拥有dependencyManagement元素的项目,然后它就会使用这个元素中指定的版本号。另外如果某个子项目需要使用另外的版本只需要声明version即可。注意:dependencyManagement里只是声明依赖,并不实现引入,因此子项目要显示的声明需要的依赖

    ② Maven中如何跳过单元测试

    ? 在Idea的Maven侧栏点击闪电图标,使Maven跳过test生命周期即可。

    <?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.polaris</groupId>
        <artifactId>springcloud2020</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>pom</packaging>
        
        <modules>
        
        </modules>
    
        <!-- 统一管理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>5.1.47</mysql.version>
            <druid.version>1.1.16</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>${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. 微服务提供者支付Module模块

    cloud-provider-payment8001

    2.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>com.polaris.springcloud</artifactId>
            <groupId>com.polaris</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>
    
    2.2 yml配置文件
    server:
      port: 8001
    
    spring:
      application:
        name: cloud-payment-service
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource            # 当前数据源操作类型
        driver-class-name: org.gjt.mm.mysql.Driver              # mysql驱动包
        url: jdbc:mysql://mpolaris.top:3306/cloud-test?useUnicode=true&characterEncoding=utf-8&useSSL=false
        username: root
        password: 123456
    
    mybatis:
      mapperLocations: classpath:mapper/*.xml
      type-aliases-package: com.polaris.springcloud.entities    # 所有Entity别名类所在包
    
    2.3 主启动类
    /**
     * @Author polaris
     * @Date 2021/1/21 1:00
     */
    @SpringBootApplication
    public class PaymentMain {
        public static void main(String[] args) {
            SpringApplication.run(PaymentMain.class,args);
        }
    }
    
    2.4 业务类(简单演示)

    建表

    image-20210124232157446

    entities

    主实体 与 Json封装体

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Payment implements Serializable {
        private Long id;
        private String serial;
    
    }
    
    @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);
        }
    }
    

    dao

    接口PaymentDao与mybatis映射文件PaymentMapper

    @Mapper
    public interface PaymentDao {
    
        int save(Payment payment);
    
        Payment getPaymentById(@Param("id") Long id);
    }
    
    <?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.polaris.springcloud.dao.PaymentDao">
    
        <insert  parameterType="Payment" useGeneratedKeys="true" keyProperty="id">
            insert into payment(serial)  values(#{serial});
        </insert>
    
    
        <resultMap  type="com.polaris.springcloud.entities.Payment">
            <id column="id" property="id" jdbcType="BIGINT"/>
            <id column="serial" property="serial" jdbcType="VARCHAR"/>
        </resultMap>
    
        <select  parameterType="Long" resultMap="BaseResultMap">
            select * from payment where id=#{id};
        </select>
    
    </mapper>
    

    service

    接口与实现类

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

    controller

    @RestController
    @Slf4j
    @RequestMapping("/payment")
    public class PaymentController {
        @Resource
        private PaymentService paymentService;
    
        @PostMapping("/save")
        public CommonResult save(Payment payment) {
            int result = paymentService.save(payment);
            log.info("===> result: " + result);
            if(result > 0) {
                return new CommonResult(200,"保存到数据库成功",result);
            }
            return new CommonResult(400,"保存到数据库失败",null);
        }
    
        @GetMapping("/get/{id}")
        public CommonResult<Payment> save(@PathVariable("id") Long id) {
            Payment paymentById = paymentService.getPaymentById(id);
            log.info("===> payment: " + paymentById);
            if(paymentById != null) {
                return new CommonResult(200,"查询成功",paymentById);
            }
            return new CommonResult(400,"查询失败",null);
        }
    }
    

    3. 开启Devtools热部署

    3.1 聚合父类总工程pom.xml添加配置
    <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>
    
    3.2 当前工程添加devtools依赖
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    
    3.3 Idea开启自动编译选项
    image-20210124211033737
    3.4 开启热注册

    快捷键 ctrl + shift + alt + /,打开Registry

    image-20210124230117788

    勾选

    image-20210124211807560

    重启Idea,即可测试代码时不用手动重启

    注意:该功能只能在开发阶段使用,上线前一定要关闭

    4. 微服务消费者订单Module模块

    cloud-consumer-order80

    4.1 pom.xml
    <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>
    
    4.2 yml配置文件
    server:
      port: 80
    
    4.3 主启动类
    4.4 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 REST请求地址
    • requestMap 请求参数
    • ResponseBean.classs HTTP响应转换被转换成的对象类型

    config配置类

    @Configuration
    public class ApplicationContextConfig {
        @Bean
        public RestTemplate getRestTemplate() {
            return new RestTemplate();
        }
    }
    
    4.5 业务类

    entities

    与提供者支付模块一致

    controller

    @RestController
    @Slf4j
    @RequestMapping("/consumer")
    public class OrderController {
        @Resource
        private RestTemplate restTemplate;
    
        private static final String PAYMENT_URL = "http://localhost:8001";
    
        @GetMapping("/payment/save")
        public CommonResult<Payment> save(Payment payment) {
            return restTemplate.postForObject(PAYMENT_URL + "/payment/save",
                    payment,CommonResult.class);
        }
    
        @GetMapping("/payment/get/{id}")
        public CommonResult<Payment> get(@PathVariable("id") Long id) {
            return restTemplate.getForObject(PAYMENT_URL + "/payment/get/" + id,
                    CommonResult.class);
        }
    }
    
    4.6 启动两个模块测试

    启动两个模块没有出现Run Dashbord的问题

    在工程目录下找.idea文件夹下的workspace.xml添加如下代码即可

    <component name="RunDashboard">
        <option name="configurationTypes">
          <set>
            <option value="SpringBootApplicationConfigurationType" />
          </set>
        </option>
        <option name="ruleStates">
          <list>
            <RuleState>
              <option name="name" value="ConfigurationTypeDashboardGroupingRule" />
            </RuleState>
            <RuleState>
              <option name="name" value="StatusDashboardGroupingRule" />
            </RuleState>
          </list>
        </option>
    </component>
    
    image-20210125000929350

    插入成功但是没有内容的问题

    image-20210125001626259

    解决:支付模块这里一定要加@RequestBody注解

    @PostMapping("/save")
    public CommonResult save(@RequestBody Payment payment) {
    	int result = paymentService.save(payment);
    	log.info("===> result: " + result);
    	if(result > 0) {
    	return new CommonResult(200,"保存到数据库成功",result);
    	}
    	return new CommonResult(400,"保存到数据库失败",null);
    }
    

    5. 工程重构 - 公共工程模块

    5.1 发现问题 - 系统中有重复代码 entities
    image-20210125002737878
    5.2 新建公共工程 cloud-api-common

    重复代码,公共接口,第三方接口,工具类等都可以放在这里

    pom.xml

    Hutool是一个小而全的Java工具类库,是项目中“util”包友好的替代

    <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>
        <!-- hutool工具类 -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.1.0</version>
        </dependency>
    </dependencies>
    
    5.3 抽取多个模块的共同代码
    image-20210125003847399

    将cloud-api-common安装到maven仓库

    修改订单80和支付8001代码

    • 删除各自原先的enntities

    • 各自添加pom内容

    <!-- 公共模块 -->
    <dependency>
        <groupId>com.polaris</groupId>
        <artifactId>cloud-api-common</artifactId>
        <version>${project.version}</version>
    </dependency>
    
    bk