Feign远程调用

添加依赖

  1. <!-- SpringCloud Openfeign -->
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-starter-openfeign</artifactId>
  5. </dependency>
  6. <!-- SpringCloud Loadbalancer -->
  7. <dependency>
  8. <groupId>org.springframework.cloud</groupId>
  9. <artifactId>spring-cloud-starter-loadbalancer</artifactId>
  10. </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

更多配置

参考:http://c.biancheng.net/view/5362.html