在spring Cloud Netflix棧中,各個微服務都是以HTTP接口的形式暴露自身服務的,因此在調用遠程服務時就必須使用HTTP客戶端。我們可以使用JDK原生的URLConnection
、Apache的Http Client
、Netty的異步HTTP Client, Spring的RestTemplate
。但是,用起來最方便、最優雅的還是要屬Feign了。
Feign簡介
Feign是一種聲明式、模板化的HTTP客戶端。在Spring Cloud中使用Feign, 我們可以做到使用HTTP請求遠程服務時能與調用本地方法一樣的編碼體驗,開發者完全感知不到這是遠程方法,更感知不到這是個HTTP請求
下面寫一個feign的實例:
pom.xml的配置
<!-- 添加feign 的依賴 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency>
啟動類添加注解:
package com.wenbronk.consumer.feign; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.netflix.feign.EnableFeignClients; //import org.springframework.cloud.netflix.eureka.EnableEurekaClient; /** * Created by root on 2017/5/20. */ @SpringBootApplication @EnableEurekaClient @EnableFeignClients public class MovieFeignApplication { public static void main(String[] args) { SpringApplication.run(MovieFeignApplication.class, args); } }
3, 編寫一個feignClient接口, 以實現遠程調用
package com.wenbronk.consumer.feign.feignclient; import com.wenbronk.consumer.feign.entity.UserEntity; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; /** * feign的接口 * Created by root on 2017/5/20. */ @FeignClient("microservice-provider-user") public interface UserFeignClient { /** * 不可以使用 getMapping, 或者postMapping注解 * * @param id * @return * @PathVariable 中 必須有value的值 */ @RequestMapping(value = "/simple/{id}", method = RequestMethod.GET) public UserEntity findById(@PathVariable("id") Long id); @RequestMapping(value = "/user", method = RequestMethod.POST) public UserEntity postUser(@RequestBody UserEntity userEntity); /** * 這兒不會管唄調用的用什么方法 @PostMapping("/user") public User postUser(@RequestBody User user) { return user; } */ @RequestMapping(value = "/user", method = RequestMethod.GET) public UserEntity getUser(UserEntity userEntity); /** * 如果被調用的方法是對象, 默認是post請求, 對方不可以是get請求 // 該請求不會成功 @GetMapping("/get-user") public User getUser(User user) { return user; } * @param userEntity * @return */ @RequestMapping(value = "/get-user", method = RequestMethod.GET) public UserEntity getUserGet(UserEntity userEntity); }
4, 在controller中進行實驗
package com.wenbronk.consumer.feign.controller; import com.wenbronk.consumer.feign.entity.UserEntity; import com.wenbronk.consumer.feign.feignclient.UserFeignClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; /** * Created by root on 2017/5/20. */ @RestController public class MovieController { @Autowired private UserFeignClient userFeignClient; @GetMapping("/findUserById/{id}") public UserEntity findUserById(@PathVariable Long id) { return userFeignClient.findById(id); } @PostMapping("/getUser") public UserEntity getUser(UserEntity user) { // return userFeignClient.postUser(user); return userFeignClient.getUser(user); // return userFeignClient.getUserGet(user); } }
調用的遠程服務為: http://www.cnblogs.com/wenbronk/p/6881573.html
中的user服務
使用feign遇到的坑:
1, feign接口中, GetMapping, PostMapping不支持, 必須使用RequestMapping
2, 使用RestFul請求時, @PathVariables("id"), 和變量同名也必須加 "id"
3, 接口中的參數是對象, 默認使用post方法, 不管是否指定 @RequestMapping(method=..)