SpringCloud(二):Feign-单独使用及对hystrix的支持配置

Feign

自定义配置时,@Configuration和@ComponentScan包不应重叠

  • 示例:

    • @FeignClient注解的放在com.mmzs.cloud.feign包下面

      1
      @FeignClient(name = "xxxx", url = "http://localhost:8761/", configuration = Configuration2.class)
    • @Configuration注解的放在com.mmzs.config包下面

      @FeignClient所在的接口中,不支持@GetMapping等组合注解

      1
      2
      3
      4
      5
      6
      //value此处的值一定要和指定的应用microservice-provider-user的controller中的映射路径一致
      @RequestMapping(method = RequestMethod.GET, value = "/user/{id}", consumes = "application/json")
      // 此处有两个坑:
      //- 1. 不支持@GetMapping等组合注解
      //- 2. @PathVariable得设置value
      public User findById(@PathVariable("id") Long id);

使用@PathVariable时,需要指定其value

1
public String findServiceName(@PathVariable("serviceName") String serviceName);

Feign暂不支持复杂对象作为一个参数

  • [ ] ==错误用法==

    1
    2
    3
    // 该请求不会成功,只要参数是复杂对象,即使指定了是GET方法,feign依然会以POST方法进行发送请求。可能是我没找到相应的注解或使用方法错误。
    @RequestMapping(method = RequestMethod.GET, value = "/feign-get-user")
    public User getUser(User user);
  • [x] ==正确用法==

    1
    2
    @RequestMapping(method = RequestMethod.GET, value = "/feign-get-user")
    public User getUser(@RequestParam("id") Long id, @RequestParam("username") String username, @RequestParam("age") String age);

feign对hystrix的支持

添加feign对hystrix的支持,全局配置

application.xml配置:

1
feign.hystrix.enabled = true

禁用单个FegionClient的Hystrix的支持

1
2
// Configuration1表示feign的自定义配置类
@FeignClient(name = "microservice-provider-user", configuration = Configuration1.class)
1
2
3
4
5
6
7
8
9
10
11
@Configuration
public class Configuration1 {

//禁用当前配置的hystrix,局部禁用
@Bean
@Scope("prototype")
public Feign.Builder feignBuilder() {
return Feign.builder();
}

}

fallback和fallbackFactory定义的类

  • fallback定义的类

    • 只重写了一个方法
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      @Component
      //这个类不一定要和UserFeignClient写在同一个类中,
      public class HystrixClientFallback implements UserFeignClient {

      @Override
      public User findById(Long id) {
      User user = new User();
      user.setId(1L);
      user.setUsername("我是HystrixClientFallback");
      return user;
      }
      }
  • fallbackFactory定义的类

    • 不只重写了方法,还能捕获异常
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      @Component
      public class HystrixClientFallbackFactory implements FallbackFactory<UserFeignClient> {

      private static Logger LOGGER = LoggerFactory.getLogger(HystrixClientFallbackFactory.class);

      @Override
      public UserFeignClient create(Throwable cause) {
      //打印日志
      HystrixClientFallbackFactory.LOGGER.info("fallback; reason was: " + cause.getMessage());

      return new UserFeignClient() {
      @Override
      public User findById(Long id) {
      User user = new User();
      user.setId(-1L);
      user.setUsername("我是HystrixClientFallbackFactory");

      return user;
      }
      };
      }

      }

==:== fallbackFactory相当于fallback的增强版,也就是说fallbackFactory的范围更广,到收集异常的边界处了。因此我们是可以利用fallbackFactory属性来打印fallback异常的。
-正确用法如下:

1
@FeignClient(name = "microservice-provider-user", /*fallback = HystrixClientFallback.class,*/ fallbackFactory = HystrixClientFallbackFactory.class)

fallback和fallbackFactory

如下这种方式的注解,fallback和fallbackFactory是会有冲突的,但不会报错,只是会让断路器执行fallback中重写的方法

1
@FeignClient(name = "microservice-provider-user", fallback = HystrixClientFallback.class, fallbackFactory = HystrixClientFallbackFactory.class)