我正在尝试创建一个在失败时具有回退方法的Feign客户端。
通过以下示例,我创建了一个简单的 Feign 客户端:
@Component
@FeignClient(value = "authenticationClient", fallback = AuthenticationClientFallback.class)
public interface AuthenticationClient
{
@RequestMapping(method = RequestMethod.GET, value = "/auth/userinfo")
UserInfoResource getUserInfo(@RequestHeader("Authorization") String token);
@RequestMapping(method = RequestMethod.GET, value = "/auth/token")
TokenResource getToken(@RequestHeader("Authorization") String basicAuth);
}
AuthenticaionClientFallback 类如下:
@Component
public class AuthenticationClientFallback implements AuthenticationClient
{
public static final String NO_TOKEN = "No Token";
@Override
public UserInfoResource getUserInfo(String token)
{
return null;
}
@Override
public TokenResource getToken(String basicAuth)
{
return new TokenResource(NO_TOKEN);
}
}
当我将客户端与@Autowire注释一起使用时,会触发回退。但是我需要创建自己的假客户端实例,以便我可以动态设置 URL。
身份验证客户端的初始化:
public AuthenticationClient getAuthenticationClient()
{
return HystrixFeign.builder().contract(new SpringMvcContract())
.encoder(new JacksonEncoder())
.decoder(new JacksonDecoder())
.client(new OkHttpClient())
.logger(new Slf4jLogger(AuthenticationClient.class))
.logLevel(Logger.Level.FULL).target(AuthenticationClient.class, getTargetURL());
}
现在我的回退方法永远不会被调用,只是抛出一个 FeignException,并带有返回 401 状态代码的消息。
PS 我已经在 .yml 文件中设置了feign.hystrix.enabled=true
,并在应用程序级别@EnableCircuitBreaker。
我认为您已经混合了 2 种假客户端初始化方法; 声明式和手动初始化。您需要坚持一种方法。
如果您使用的是声明性初始化; 您可以将@FeignClient注释与回退一起使用,如下所示;
@FeignClient(value = "authenticationClient", url = "${feign.url}", fallback = AuthenticationClientFallback.class)
public interface AuthenticationClient
您可以像这样在组件中自动连接假装客户端。
@Autowired
AuthenticationClient client;
如果您使用带有某些自定义的假装客户端的手动初始化;那么您不必在 AuthenticationClient 类上使用@FeignClient注释。您可以创建自定义的假装客户端,如下所示;
@Autowired
AuthenticationClientFallback fallbackClient;
public AuthenticationClient getAuthenticationClient()
{
return HystrixFeign.builder().contract(new SpringMvcContract())
.encoder(new JacksonEncoder())
.decoder(new JacksonDecoder())
.client(new OkHttpClient())
.logger(new Slf4jLogger(AuthenticationClient.class))
.logLevel(Logger.Level.FULL).target(AuthenticationClient.class, getTargetURL(), fallbackClient);
}
请注意,fallbackClient 对象在 .target(( 中作为参数传递。
有关更多详细信息,请参阅 Spring Cloud 假装文档