SpringCloud入门实战(5)-Feign使用
Feign是一种声明式、模板化的HTTP客户端。在Spring Cloud中使用Feign,可以做到调用远程服务,就像调用本地方法一样的,开发者完全感知不到这是在调用远程方法,更感知不到在访问HTTP请求。本文主要介绍Feign的基本使用,文中使用到的软件版本:Spring Boot 2.2.5.RELEASE、Spring Cloud Hoxton.SR3、Java 1.8.0_191。
1、特点
a、Feign可帮助我们更加便捷,优雅的调用HTTP API。
b、在SpringCloud中,使用Feign非常简单——创建一个接口,并在接口上添加一些注解,代码就完成了。
c、Feign支持多种注解,例如Feign自带的注解或者JAX-RS注解等。
d、SpringCloud对Feign进行了增强,使Feign支持了SpringMVC注解,并整合了Ribbon,从而让Feign的使用更加方便。
2、原理
3、常用参数设置
feign.hystrix.enabled=false feign的调用过程中是否启用hystrix,默认false
feign.httpclient.enabled=ture 是否使用httpclient来调用接口,默认true;要使用httpclient还需要引入feign-httpclient依赖
feign.okhttp.enabled=false 是否使用okhttp来调用接口,默认false;要使用okhttp需把改属性设为true,还需要引入feign-httpclient依赖
4、使用
4.1、客户端引入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
4.2、客户端启动类增加@EnableFeignClients
package com.abc.scdemo.client;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class ClientApplication {
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
}
4.3、服务端 Controller
package com.abc.scdemo.server.controller; import com.abc.scdemo.server.entity.CallResult; import com.abc.scdemo.server.entity.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/user") public class UserController { private Logger logger = LoggerFactory.getLogger(UserController.class); @RequestMapping("/addUser") public CallResult<User> addUser(@RequestBody User user) { logger.info(user.toString()); //TODO: insert to db user.setId(1000L); user.setName("server-" + user.getName()); CallResult<User> result = new CallResult<>(); result.setResult(user); return result; } @RequestMapping("/getUser") public CallResult<User> getUser(long id) { logger.info(id + ""); // try { // Thread.sleep(1000 * 10); // } catch (InterruptedException e) { // e.printStackTrace(); // } //TODO: select from db User user = new User(); user.setId(id); user.setName("server-马云"); user.setAddress("杭州"); CallResult<User> result = new CallResult<User>(); result.setResult(user); return result; } @RequestMapping("/getUser2") public CallResult<User> getUser2(long id) { return null; } }
4.4、客户端定义Feign接口
package com.abc.scdemo.client.feign; import com.abc.scdemo.client.entity.CallResult; import com.abc.scdemo.client.entity.User; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; //scdemo-server为服务名称 @FeignClient(name = "scdemo-server") public interface IUserFeign { @PostMapping("/user/addUser") CallResult<User> addUser(@RequestBody User user); @PostMapping("/user/getUser") CallResult<User> getUser(@RequestParam("id") long id); }
4.5、客户端调用
@RequestMapping("/getUser") public CallResult<User> getUser(long id) { logger.info(id + ""); CallResult<User> result = null; try { result = userFeign.getUser(id); } catch (Exception e) { result = new CallResult<User>(-1, "发生异常"); e.printStackTrace(); } return result; }
4.5、与Hystrix结合使用
4.5.1、配置启用Hystrix
feign:
hystrix:
enabled: true
4.5.2、定义降级实现类
package com.abc.scdemo.client.feign.fallback; import com.abc.scdemo.client.entity.CallResult; import com.abc.scdemo.client.entity.User; import com.abc.scdemo.client.feign.IUserFeign; import org.springframework.stereotype.Component; @Component public class UserFallBack implements IUserFeign { @Override public CallResult<User> addUser(User user) { return new CallResult<>(1, "增加用户服务暂不可用!"); } @Override public CallResult<User> getUser(long id) { return new CallResult<>(1, "获取用户服务暂不可用!"); } }
4.5.3、Feign接口中指定降级实现类
package com.abc.scdemo.client.feign; import com.abc.scdemo.client.entity.CallResult; import com.abc.scdemo.client.entity.User; import com.abc.scdemo.client.feign.fallback.UserFallBack; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; //scdemo-server为服务名称 @FeignClient(name = "scdemo-server", fallback = UserFallBack.class) public interface IUserFeign { @PostMapping("/user/addUser") CallResult<User> addUser(@RequestBody User user); @PostMapping("/user/getUser") CallResult<User> getUser(@RequestParam("id") long id); }
当scdemo-server服务不存在或调用超时,都会返回降级实现类中的结果。