Feign远程调用
添加依赖
<!-- SpringCloud Openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- SpringCloud Loadbalancer -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
远程调用接口
@FeignClient(contextId = "feignUserService", value = FeignServiceConstant.API_SYSTEM_SERVICE, fallbackFactory = FeignUserFallBackFactory.class)
public interface FeignUserService {
/**
* 通过用户名查询用户信息
*
* @param username 用户名
* @param source 请求来源
* @return 结果
*/
@GetMapping("/user/info/{username}")
public R<LoginUser> getUserInfo(@PathVariable("username") String username, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 注册用户信息
*
* @param sysUser 用户信息
* @param source 请求来源
* @return 结果
*/
@PostMapping("/user/register")
public R<Boolean> registerUserInfo(@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}
@FeignClient注解
定义一个 Feign 的客户端,以接口形式存在,代码如下所示。
@FeignClient(value = "feign-client-user-service")
public interface UserRemoteClient {
@GetMapping("/user/hello")
String hello();
}
@FeignClient 注解。这个注解标识当前是一个 Feign 的客户端,value 属性是对应的接口服务名称,也就是你需要调用哪个服务中的接口
源码
其中@FeignClient注解的参数可以查看源码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface FeignClient {
@AliasFor("name")
String value() default "";
String contextId() default "";
@AliasFor("value")
String name() default "";
/** @deprecated */
@Deprecated
String qualifier() default "";
String[] qualifiers() default {};
String url() default "";
boolean decode404() default false;
Class<?>[] configuration() default {};
Class<?> fallback() default void.class;
Class<?> fallbackFactory() default void.class;
String path() default "";
boolean primary() default true;
}
我们可以配置的参数:
contextId:后面生成的变量名
value:注册的服务名,可以替换为name属性
fallbackFactory:调用失败时的处理方法
失败处理类
@Component
public class FeignUserFallBackFactory implements FallbackFactory<FeignUserService> {
private static final Logger log = LoggerFactory.getLogger(FeignUserFallBackFactory.class);
@Override
public FeignUserService create(Throwable throwable) {
log.error("用户服务调用失败:{}", throwable.getMessage());
return new FeignUserService() {
@Override
public R<LoginUser> getUserInfo(String username, String source) {
return R.fail("获取用户失败:" + throwable.getMessage());
}
@Override
public R<Boolean> registerUserInfo(SysUser sysUser, String source) {
return R.fail("注册用户失败:" + throwable.getMessage());
}
};
}
}
启动类添加注解
在启动类上加 @EnableFeignClients 注解,
如果你的 Feign 接口定义跟你的启动类不在同一个包名下,还需要制定扫描的包名 **@EnableFeignClients**``**(basePackages=“com.fangjia.api.client”)**
@SpringBootApplication
@EnableFeignClients(basePackages = "com.fangjia.api.client")
public class FeignServiceApplication {
public static void main(String[] args) {
SpringApplication.run(FeignServiceApplication.class);
}
}
日志配置
有时候我们遇到 Bug,比如接口调用失败、参数没收到等问题,或者想看看调用性能,就需要配置 Feign 的日志了,以此让 Feign 把请求信息输出来。
定义配置类
@Configuration
public class FeignConfiguration {
/**
* 日志级别
*
* @return
*/
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
配置类建好后,我们需要在 Feign Client 中的 @FeignClient 注解中指定使用的配置类,代码如下所示。
@FeignClient(value = "eureka-client-user-service", configuration = FeignConfiguration. class)
public interface UserRemoteClient {
// ...
}
在配置文件中执行 Client 的日志级别才能正常输出日志,格式是“logging.level.client 类地址=级别”。
logging.level.com.zukxu.feign_demo.remote.UserRemoteClient=DEBUG