Feign使用fallbackFactory属性打印fallback异

房东的猫 提交于 2019-11-28 19:46:23
https://cloud.spring.io/spring-cloud-openfeign/reference/html/#spring-cloud-feign-hystrix

If one needs access to the cause that made the fallback trigger, one can use the 
fallbackFactory 

attribute inside @FeignClient.

@FeignClient(name = "microservice-simple-provider-user", fallbackFactory = 
FeignClientFallbackFactory.class)
public interface UserFeignClient {
	  @RequestMapping(value = "/simple/{id}", method = RequestMethod.GET)
	  public User findById(@PathVariable("id") Long id);
}

@Component
public class FeignClientFallbackFactory implements FallbackFactory<UserFeignClient> {
    private static final Logger logger = 
LoggerFactory.getLogger(FeignClientFallbackFactory.class);

    @Override
    public UserFeignClient create(Throwable arg0) {
    	FeignClientFallbackFactory.logger.info("fallback reason was:{}", 
arg0.getMessage());
        return new UserFeignClient() {
            @Override
            public User findById(Long id) {
                User user = new User();
                user.setId(-1L);
                return user;
            }
        };
    }
}


localhost:8010/movie/1

fallback和fallbackFactory是有一定的冲突的,你可以理解为fallbackFactory是fallback的一个增强版,

因为fallback只是复写方法

@Component
public class HystrixClientFallback implements UserFeignClient {

	@Override
	public User findById(Long id) {
		User user = new User();
		user.setId(0L);
		return user;
	}
    
}

没办法打印日志,而这个更强一点,他可以拦截异常这一块,

/**
 * Define a fallback factory for the specified Feign client interface. The fallback
 * factory must produce instances of fallback classes that implement the interface
 * annotated by {@link FeignClient}. The fallback factory must be a valid spring
 * bean.
 *
 * @see feign.hystrix.FallbackFactory for details.
 */
Class<?> fallbackFactory() default void.class;

为特定的Feign client定义一个fallback factory,必须提供一个fallback类的实例,

https://www.cnblogs.com/bjlhx/p/8909577.html

@FeignClient(name = "microservice-provider-user",  fallbackFactory = 
HystrixClientFallbackFactory.class)
public interface UserFeignClient {
    // @GetMapping("/sample/{id}")
    @RequestMapping(method = RequestMethod.GET, value = "/sample/{id}")
    public User findById(@PathVariable("id") Long id);
}

public interface UserFeignClientWithFactory extends UserFeignClient {

}

Component
public class HystrixClientFallbackFactory implements FallbackFactory<UserFeignClient> {
    private static final Logger logger = 
LoggerFactory.getLogger(HystrixClientFallbackFactory.class);

    @Override
    public UserFeignClient create(Throwable arg0) {
        HystrixClientFallbackFactory.logger.info("fallback reason was:{}", 
arg0.getMessage());
        return new UserFeignClientWithFactory() {
            @Override
            public User findById(Long id) {
                User user = new User();
                user.setId(-1L);
                return user;
            }
        };
    }
}

public interface FallbackFactory<T> {

  /**
   * Returns an instance of the fallback appropriate for the given cause
   *
   * @param cause corresponds to {@link com.netflix.hystrix.AbstractCommand#getExecutionException()}
   * often, but not always an instance of {@link FeignException}.
   */
  T create(Throwable cause);

  /** Returns a constant fallback after logging the cause to FINE level. */
  final class Default<T> implements FallbackFactory<T> {
    // jul to not add a dependency
    final Logger logger;
    final T constant;

    public Default(T constant) {
      this(constant, Logger.getLogger(Default.class.getName()));
    }

    Default(T constant, Logger logger) {
      this.constant = checkNotNull(constant, "fallback");
      this.logger = checkNotNull(logger, "logger");
    }

    @Override
    public T create(Throwable cause) {
      if (logger.isLoggable(Level.FINE)) {
        logger.log(Level.FINE, "fallback due to: " + cause.getMessage(), cause);
      }
      return constant;
    }

    @Override
    public String toString() {
      return constant.toString();
    }
  }
}

https://cloud.spring.io/spring-cloud-openfeign/reference/html/
#spring-cloud-feign-hystrix

There is a limitation with the implementation of fallbacks in Feign and how Hystrix fallbacks work. 

Fallbacks are currently not supported for methods that return com.netflix.hystrix.HystrixCommand 

and rx.Observable.

在目前的回退是不支持原生的HystrixCommand或者是rx.Observable
package com.learn.cloud.feign;

import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.learn.cloud.entity.User;

//@FeignClient(name = "microservice-simple-provider-user", fallback = HystrixClientFallback.class)
@FeignClient(name = "microservice-simple-provider-user", fallbackFactory = FeignClientFallbackFactory.class)
public interface UserFeignClient {
	  @RequestMapping(value = "/simple/{id}", method = RequestMethod.GET)
	  public User findById(@PathVariable("id") Long id);
}
package com.learn.cloud.feign;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.learn.cloud.entity.User;

import feign.hystrix.FallbackFactory;

@Component
public class FeignClientFallbackFactory implements FallbackFactory<UserFeignClient> {
    private static final Logger logger = LoggerFactory.getLogger(FeignClientFallbackFactory.class);

    @Override
    public UserFeignClient create(Throwable arg0) {
    	FeignClientFallbackFactory.logger.info("fallback reason was:{}", arg0.getMessage());
        return new UserFeignClient() {
            @Override
            public User findById(Long id) {
                User user = new User();
                user.setId(-1L);
                return user;
            }
        };
    }
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!