作为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;@Datapublic 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")@RefreshScopepublic 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")@RefreshScopepublic 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")@SpringBootApplicationpublic class GitEggBaseApplication {    public static void main(String[] args) {        SpringApplication.run(GitEggBaseApplication.class,args);    }}

bootstrap.yml:

server:  port: 8002spring:  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调用测试接口,能够查看微服务调用胜利

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