作为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分支。