美文网首页SpringCloud
SpringCloud微服务实战——搭建企业级开发框架(十一):

SpringCloud微服务实战——搭建企业级开发框架(十一):

作者: 全栈程序猿 | 来源:发表于2020-11-14 16:29 被阅读0次

      作为Spring Cloud的子项目之一,Spring Cloud OpenFeign以将OpenFeign集成到Spring Boot应用中的方式,为微服务架构下服务之间的调用提供了解决方案。首先,利用了OpenFeign的声明式方式定义Web服务客户端;其次还更进一步,通过集成Ribbon或Eureka实现负载均衡的HTTP客户端。
      OpenFeign 可以使消费者将提供者提供的服务名伪装为接口进行消费,消费者只需使用“Service 接口+ 注解”的方式。即可直接调用 Service 接口方法,而无需再使用 RestTemplate 了。其实原理还是使用RestTemplate,而通过Feign(伪装)成我们熟悉的习惯。
      GitEgg框架除了新建Fegin服务之外,还定义实现了消费者Fegin-api,在其他微服务调用的时候,只需要引入Fegin-api即可直接调用,不需要在自己重复开发消费者调用接口。

    1、在GitEgg-Platform工程的子工程gitegg-platform-cloud中引入spring-cloud-starter-openfeign依赖,重新install GitEgg-Platform工程,然后GitEgg-Cloud项目需要重新在IDEA中执行Reload All Maven Projects。

    <?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>GitEgg-Platform</artifactId>
            <groupId>com.gitegg.platform</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>gitegg-platform-cloud</artifactId>
        <name>${project.artifactId}</name>
        <version>${project.parent.version}</version>
        <packaging>jar</packaging>
    
        <dependencies>
            <!-- Nacos 服务注册发现-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            </dependency>
            <!-- Nacos 分布式配置-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            </dependency>
            <!-- OpenFeign 微服务调用解决方案-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>
        </dependencies>
    
    </project>
    

      我们从系统架构设计方面考虑,GitEgg-Cloud下的gitegg-service作为业务逻辑处理模块,gitegg-service-api作为微服务统一对外提供接口的模块,这里在测试的时候需要用到两个微服务之间的调用,我们这里在gitegg-service下gitegg-service-base里面新建测试代码,和gitegg-service-system之间相互调用。注意,这里需要说明,gitegg-service-api并不是继承gitegg-service做业务扩展,而是对外提供接口的抽象,比如现在有A、B、C三个系统A、B都需要调用C的同一个方法,如果按照业务逻辑来罗列代码的话,那么就需要在A和B中写相同的调用方法来调用C,这里我们抽出来一个api模块,专门存放调用微服务C的调用方法,在使用时,A和B只需要引入C的jar包即可直接使用调用方法。
    2、在gitegg-service-system-api工程中,引入SpringBoot,SpringCloud,Swagger2的依赖,新建ISystemFeign.java和ApiSystemDTO.java,作为OpenFeign调用微服务的公共方法:

    <?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>GitEgg-Cloud</artifactId>
            <groupId>com.gitegg.cloud</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>gitegg-service-api</artifactId>
        <name>${project.artifactId}</name>
        <version>${project.parent.version}</version>
        <packaging>pom</packaging>
        <modules>
            <module>gitegg-service-base-api</module>
            <module>gitegg-service-bigdata-api</module>
            <module>gitegg-service-system-api</module>
        </modules>
    
        <dependencies>
            <!-- gitegg Spring Boot自定义及扩展 -->
            <dependency>
                <groupId>com.gitegg.platform</groupId>
                <artifactId>gitegg-platform-boot</artifactId>
            </dependency>
            <!-- gitegg Spring Cloud自定义及扩展 -->
            <dependency>
                <groupId>com.gitegg.platform</groupId>
                <artifactId>gitegg-platform-cloud</artifactId>
            </dependency>
            <!-- gitegg swagger2-knife4j -->
            <dependency>
                <groupId>com.gitegg.platform</groupId>
                <artifactId>gitegg-platform-swagger</artifactId>
            </dependency>
        </dependencies>
    
    
    </project>
    
    package com.gitegg.service.system.api.feign;
    
    import com.gitegg.platform.boot.common.base.Result;
    import com.gitegg.service.system.api.dto.ApiSystemDTO;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestParam;
    
    @FeignClient(name = "gitegg-service-system")
    public interface ISystemFeign {
    
        /**
         * OpenFeign测试Get
         *
         * @param id
         * @return
         */
        @GetMapping("/system/api/by/id")
        Result<Object> querySystemById(@RequestParam("id") Long id);
    
        /**
         * OpenFeign测试Post
         *
         * @param apiSystemDTO
         * @return ApiSystemDTO
         */
        @PostMapping("/system/api/by/dto")
        Result<ApiSystemDTO> querySystemByDto(@RequestBody ApiSystemDTO apiSystemDTO);
    }
    
    
    package com.gitegg.service.system.api.dto;
    
    import lombok.Data;
    
    import javax.validation.constraints.Max;
    import javax.validation.constraints.Min;
    import javax.validation.constraints.NotNull;
    import javax.validation.constraints.Size;
    
    @Data
    public class ApiSystemDTO {
    
        @NotNull
        @Min(value = 10, message = "id必须大于10")
        @Max(value = 150, message = "id必须小于150")
        private Long id;
    
        @NotNull(message = "名称不能为空")
        @Size(min = 3, max = 20, message = "名称长度必须在3-20之间")
        private String name;
        
    }
    
    

    2、在gitegg-service-system工程中,修改SystemController.java,添加需要被微服务调用的方法:

    package com.gitegg.service.system.controller;
    
    import com.gitegg.platform.boot.common.base.Result;
    import com.gitegg.service.system.dto.SystemDTO;
    import com.gitegg.service.system.service.ISystemService;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    import lombok.RequiredArgsConstructor;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    import org.springframework.web.bind.annotation.*;
    
    import javax.validation.Valid;
    
    @RestController
    @RequestMapping(value = "system")
    @RequiredArgsConstructor(onConstructor_ = @Autowired)
    @Api(tags = "gitegg-system")
    @RefreshScope
    public class SystemController {
    
        private final ISystemService systemService;
    
        @Value("${spring.datasource.maxActive}")
        private String nacosMaxActiveType;
    
        @GetMapping(value = "list")
        @ApiOperation(value = "system list接口")
        public Object list() {
            return systemService.list();
        }
    
    
        @GetMapping(value = "page")
        @ApiOperation(value = "system page接口")
        public Object page() {
            return systemService.page();
        }
    
        @GetMapping(value = "exception")
        @ApiOperation(value = "自定义异常及返回测试接口")
        public Result<String> exception() {
            return Result.data(systemService.exception());
        }
    
        @PostMapping(value = "valid")
        @ApiOperation(value = "参数校验测试接口")
        public Result<SystemDTO> valid(@Valid @RequestBody SystemDTO systemDTO) {
            return Result.data(systemDTO);
        }
    
        @PostMapping(value = "nacos")
        @ApiOperation(value = "Nacos读取配置文件测试接口")
        public Result<String> nacos() {
            return Result.data(nacosMaxActiveType);
        }
    
        @GetMapping(value = "api/by/id")
        @ApiOperation(value = "Fegin Get调用测试接口")
        public Result<Object> feginById(@RequestParam("id") String id) {
            return Result.data(systemService.list());
        }
    
        @PostMapping(value = "api/by/dto")
        @ApiOperation(value = "Fegin Post调用测试接口")
        public Result<Object> feginByDto(@Valid @RequestBody SystemDTO systemDTO) {
            return Result.data(systemDTO);
        }
    }
    
    

    3、参照gitegg-service-system工程,在gitegg-service-base工程下,引入gitegg-service-system-api依赖,新建BaseController.java、GitEggBaseApplication.java、bootstrap.yml作为服务调用方:
    pom.xml:

        <dependencies>
            <!-- gitegg-service-system 的fegin公共调用方法 -->
            <dependency>
                <groupId>com.gitegg.cloud</groupId>
                <artifactId>gitegg-service-system-api</artifactId>
                <version>${project.parent.version}</version>
            </dependency>
        </dependencies>
    

    BaseController.java:

    package com.gitegg.service.base.controller;
    
    import com.gitegg.platform.boot.common.base.Result;
    import com.gitegg.service.system.api.dto.ApiSystemDTO;
    import com.gitegg.service.system.api.feign.ISystemFeign;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    import lombok.RequiredArgsConstructor;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    import org.springframework.web.bind.annotation.*;
    
    import javax.validation.Valid;
    
    @RestController
    @RequestMapping(value = "base")
    @RequiredArgsConstructor(onConstructor_ = @Autowired)
    @Api(tags = "gitegg-base")
    @RefreshScope
    public class BaseController {
    
        private final ISystemFeign systemFeign;
    
        @GetMapping(value = "api/by/id")
        @ApiOperation(value = "Fegin Get调用测试接口")
        public Result<Object> feginById(@RequestParam("id") Long id) {
            return Result.data(systemFeign.querySystemById(id));
        }
    
        @PostMapping(value = "api/by/dto")
        @ApiOperation(value = "Fegin Post调用测试接口")
        public Result<Object> feginByDto(@Valid @RequestBody ApiSystemDTO systemDTO) {
            return Result.data(systemFeign.querySystemByDto(systemDTO));
        }
    
    }
    
    

    GitEggBaseApplication.java:

    package com.gitegg.service.base;
    
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    import org.springframework.context.annotation.ComponentScan;
    
    /**
     * gitegg-base 启动类
     */
    @EnableDiscoveryClient
    @EnableFeignClients(basePackages = "com.gitegg")
    @ComponentScan(basePackages = "com.gitegg")
    @MapperScan("com.gitegg.*.*.mapper")
    @SpringBootApplication
    public class GitEggBaseApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(GitEggBaseApplication.class,args);
        }
    
    }
    
    

    bootstrap.yml:

    server:
      port: 8002
    spring:
      application:
        name: gitegg-service-base
      cloud:
        nacos:
          discovery:
            server-addr: 127.0.0.1:8848
          config:
            server-addr: 127.0.0.1:8848
            file-extension: yaml
            prefix: gitegg-service-system
            group: DEFAULT_GROUP
            enabled: true
    

    4、分别启动gitegg-service-base和gitegg-service-system项目,打开浏览器,访问http://127.0.0.1:8002/doc.html(这里gitegg-service-base的端口设置为8002,所以访问gitegg-service-base的服务进行测试),在页面左侧菜单分别点击Fegin Get调用测试接口和Fegin Post调用测试接口,可以查看微服务调用成功

    image.png
    image.png

    本文源码在https://gitee.com/wmz1930/GitEgg 的chapter-11分支。

    GitEgg-Cloud是一款基于SpringCloud整合搭建的企业级微服务应用开发框架,开源项目地址:

    Gitee: https://gitee.com/wmz1930/GitEgg
    GitHub: https://github.com/wmz1930/GitEgg

    欢迎感兴趣的小伙伴Star支持一下。

    相关文章

      网友评论

        本文标题:SpringCloud微服务实战——搭建企业级开发框架(十一):

        本文链接:https://www.haomeiwen.com/subject/rohrsktx.html