在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=..)