Feign是一個聲明式的Web Service客戶端,它簡化了Web服務客戶端的編寫操做,相對於Ribbon+RestTemplate的方式,開發者只需經過簡單的接口和註解來調用HTTP API。它支持Spring MVC註解和JAX-RS註解,還支持可插拔式的編碼器和解碼器。整合了Eureka,Ribbon和Hystrix,具備可插拔、基於註解、負載均衡、服務熔斷等一系列便捷功能。html
<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> <parent> <groupId>com.cf</groupId> <artifactId>sc-parent</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>sc-consumer-feign</artifactId> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> </dependencies> </project>
package feign; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication @EnableFeignClients public class FeignApplication { public static void main(String[] args) { SpringApplication.run(FeignApplication.class, args); } }
package feign.inter; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; @FeignClient("sc-provider") public interface BookService { @GetMapping("/book/list") public String getBookList(); }
package feign.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import feign.inter.BookService; @RequestMapping("/feign") @RestController public class FeignController { @Autowired private BookService bookService; @GetMapping("/getBookList") public String getBookList(){ return bookService.getBookList(); } }
server: port: 8084 spring: application: name: sc-consumer-feign eureka: client: registerWithEureka: false serviceUrl: defaultZone: http://localhost:8080/eureka/
Feign基於Ribbon實現,也具備Ribbon負載均衡的特性,能夠將調用的提供者服務換成sc-provider-random(請參照SpringCloud學習筆記(2):使用Ribbon負載均衡)來測試。java
上面例子沒有涉及到參數的傳遞,接下來測試下如何使用Feign構造帶參數的請求,首先對提供者和消費者作以下更改:web
//提供者Controller添加了兩個參數,並打印到控制檯。 @RequestMapping("/book") @RestController public class BookController { @GetMapping("/list") public String getBookList(String param1, Integer param2){ System.out.println(param1 + ":" + param2); return "[\"Java入門到放棄\",\"C++入門到放棄\",\"Python入門到放棄\",\"C入門到放棄\"]"; } } //消費者Feign接口和Controller添加參數 @FeignClient("sc-provider") public interface BookService { @GetMapping("/book/list") public String getBookList(String param1, Integer param2); } @RequestMapping("/feign") @RestController public class FeignController { @Autowired private BookService bookService; @GetMapping("/getBookList") public String getBookList(){ return bookService.getBookList("Java", 520); } }
依次啓動註冊中心sc-eureka、提供者sc-provider、消費者sc-consumer-feign,啓動消費者sc-consumer-feign時會啓動失敗: <font color="red">java.lang.IllegalStateException: Method has too many Body parameters: public abstract java.lang.String feign.inter.BookService.getBookList(java.lang.String,java.lang.Integer)</font>spring
更改Feign接口,爲參數添加@RequestParam註解:apache
@FeignClient("sc-provider") public interface BookService { @GetMapping("/book/list") public String getBookList(@RequestParam("param1") String param1, @RequestParam("param2") Integer param2); }
將參數封裝到Map裏,更改消費者Feign接口和Controller:app
@FeignClient("sc-provider") public interface BookService { @GetMapping("/book/list") public String getBookList(@RequestParam Map<String, Object> paramMap); } @RequestMapping("/feign") @RestController public class FeignController { @Autowired private BookService bookService; @GetMapping("/getBookList") public String getBookList(){ Map<String,Object> paramMap = new HashMap<String, Object>(); paramMap.put("param1", "Java"); paramMap.put("param2", 520); return bookService.getBookList(paramMap); } }
在參數較多的狀況下,該方式能夠簡化Feign接口的編寫。負載均衡
OpenFeign的@QueryMap註解支持將自定義類型用於GET參數映射,因爲@QueryMap和Spring不兼容,Spring Cloud OpenFeign提供了一個等價的@SpringQueryMap註解,能夠用於自定義類型和Map類型的參數映射。下面將使用自定義類型Params做爲參數,使用@SpringQueryMap註解來處理自定義類型的參數映射。dom
public class Params { private String param1; private Integer param2; public String getParam1() { return param1; } public void setParam1(String param1) { this.param1 = param1; } public Integer getParam2() { return param2; } public void setParam2(Integer param2) { this.param2 = param2; } @Override public String toString() { return "Params [param1=" + param1 + ", param2=" + param2 + "]"; } public Params(String param1, Integer param2) { this.param1 = param1; this.param2 = param2; } public Params() {} }
//提供者 @RequestMapping("/book") @RestController public class BookController { @GetMapping("/list") public String getBookList(Params params){ System.out.println(params.toString()); return "[\"Java入門到放棄\",\"C++入門到放棄\",\"Python入門到放棄\",\"C入門到放棄\"]"; } } //消費者 @FeignClient("sc-provider") public interface BookService { @GetMapping("/book/list") public String getBookList(@SpringQueryMap Params params); } @RequestMapping("/feign") @RestController public class FeignController { @Autowired private BookService bookService; @GetMapping("/getBookList") public String getBookList(){ Params params = new Params("Java", 520); return bookService.getBookList(params); } }
Params [param1=Java, param2=520]
原文出處:https://www.cnblogs.com/seve/p/11512249.htmlmaven