??作為Spring Cloud的子項(xiàng)目之一风皿,Spring Cloud OpenFeign以將OpenFeign集成到Spring Boot應(yīng)用中的方式,為微服務(wù)架構(gòu)下服務(wù)之間的調(diào)用提供了解決方案缠俺。首先,利用了OpenFeign的聲明式方式定義Web服務(wù)客戶端;其次還更進(jìn)一步,通過(guò)集成Ribbon或Eureka實(shí)現(xiàn)負(fù)載均衡的HTTP客戶端椿浓。
??OpenFeign 可以使消費(fèi)者將提供者提供的服務(wù)名偽裝為接口進(jìn)行消費(fèi),消費(fèi)者只需使用“Service 接口+ 注解”的方式闽晦。即可直接調(diào)用 Service 接口方法轰绵,而無(wú)需再使用 RestTemplate 了。其實(shí)原理還是使用RestTemplate尼荆,而通過(guò)Feign(偽裝)成我們熟悉的習(xí)慣。
??GitEgg框架除了新建Fegin服務(wù)之外唧垦,還定義實(shí)現(xiàn)了消費(fèi)者Fegin-api捅儒,在其他微服務(wù)調(diào)用的時(shí)候,只需要引入Fegin-api即可直接調(diào)用,不需要在自己重復(fù)開(kāi)發(fā)消費(fèi)者調(diào)用接口巧还。
1鞭莽、在GitEgg-Platform工程的子工程gitegg-platform-cloud中引入spring-cloud-starter-openfeign依賴,重新install GitEgg-Platform工程,然后GitEgg-Cloud項(xiàng)目需要重新在IDEA中執(zhí)行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 服務(wù)注冊(cè)發(fā)現(xiàn)-->
<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 微服務(wù)調(diào)用解決方案-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
</project>
??我們從系統(tǒng)架構(gòu)設(shè)計(jì)方面考慮澎怒,GitEgg-Cloud下的gitegg-service作為業(yè)務(wù)邏輯處理模塊,gitegg-service-api作為微服務(wù)統(tǒng)一對(duì)外提供接口的模塊阶牍,這里在測(cè)試的時(shí)候需要用到兩個(gè)微服務(wù)之間的調(diào)用喷面,我們這里在gitegg-service下gitegg-service-base里面新建測(cè)試代碼,和gitegg-service-system之間相互調(diào)用走孽。注意惧辈,這里需要說(shuō)明,gitegg-service-api并不是繼承g(shù)itegg-service做業(yè)務(wù)擴(kuò)展磕瓷,而是對(duì)外提供接口的抽象盒齿,比如現(xiàn)在有A、B困食、C三個(gè)系統(tǒng)A边翁、B都需要調(diào)用C的同一個(gè)方法,如果按照業(yè)務(wù)邏輯來(lái)羅列代碼的話硕盹,那么就需要在A和B中寫相同的調(diào)用方法來(lái)調(diào)用C符匾,這里我們抽出來(lái)一個(gè)api模塊,專門存放調(diào)用微服務(wù)C的調(diào)用方法莱睁,在使用時(shí)待讳,A和B只需要引入C的jar包即可直接使用調(diào)用方法。
2仰剿、在gitegg-service-system-api工程中创淡,引入SpringBoot,SpringCloud南吮,Swagger2的依賴琳彩,新建ISystemFeign.java和ApiSystemDTO.java,作為OpenFeign調(diào)用微服務(wù)的公共方法:
<?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自定義及擴(kuò)展 -->
<dependency>
<groupId>com.gitegg.platform</groupId>
<artifactId>gitegg-platform-boot</artifactId>
</dependency>
<!-- gitegg Spring Cloud自定義及擴(kuò)展 -->
<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測(cè)試Get
*
* @param id
* @return
*/
@GetMapping("/system/api/by/id")
Result<Object> querySystemById(@RequestParam("id") Long id);
/**
* OpenFeign測(cè)試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 = "名稱長(zhǎng)度必須在3-20之間")
private String name;
}
2部凑、在gitegg-service-system工程中露乏,修改SystemController.java,添加需要被微服務(wù)調(diào)用的方法:
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 = "自定義異常及返回測(cè)試接口")
public Result<String> exception() {
return Result.data(systemService.exception());
}
@PostMapping(value = "valid")
@ApiOperation(value = "參數(shù)校驗(yàn)測(cè)試接口")
public Result<SystemDTO> valid(@Valid @RequestBody SystemDTO systemDTO) {
return Result.data(systemDTO);
}
@PostMapping(value = "nacos")
@ApiOperation(value = "Nacos讀取配置文件測(cè)試接口")
public Result<String> nacos() {
return Result.data(nacosMaxActiveType);
}
@GetMapping(value = "api/by/id")
@ApiOperation(value = "Fegin Get調(diào)用測(cè)試接口")
public Result<Object> feginById(@RequestParam("id") String id) {
return Result.data(systemService.list());
}
@PostMapping(value = "api/by/dto")
@ApiOperation(value = "Fegin Post調(diào)用測(cè)試接口")
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作為服務(wù)調(diào)用方:
pom.xml:
<dependencies>
<!-- gitegg-service-system 的fegin公共調(diào)用方法 -->
<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調(diào)用測(cè)試接口")
public Result<Object> feginById(@RequestParam("id") Long id) {
return Result.data(systemFeign.querySystemById(id));
}
@PostMapping(value = "api/by/dto")
@ApiOperation(value = "Fegin Post調(diào)用測(cè)試接口")
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 啟動(dòng)類
*/
@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驹止、分別啟動(dòng)gitegg-service-base和gitegg-service-system項(xiàng)目,打開(kāi)瀏覽器观蜗,訪問(wèn)http://127.0.0.1:8002/doc.html(這里gitegg-service-base的端口設(shè)置為8002臊恋,所以訪問(wèn)gitegg-service-base的服務(wù)進(jìn)行測(cè)試),在頁(yè)面左側(cè)菜單分別點(diǎn)擊Fegin Get調(diào)用測(cè)試接口和Fegin Post調(diào)用測(cè)試接口墓捻,可以查看微服務(wù)調(diào)用成功
本文源碼在https://gitee.com/wmz1930/GitEgg 的chapter-11分支抖仅。
GitEgg-Cloud是一款基于SpringCloud整合搭建的企業(yè)級(jí)微服務(wù)應(yīng)用開(kāi)發(fā)框架,開(kāi)源項(xiàng)目地址:
Gitee: https://gitee.com/wmz1930/GitEgg
GitHub: https://github.com/wmz1930/GitEgg
歡迎感興趣的小伙伴Star支持一下砖第。