在 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的配置
org.springframework.cloud spring-cloud-starter-feign
启动类添加注解:
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@EnableFeignClientspublic 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. */@RestControllerpublic 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=..)