那天晚上和@FeignClient注解的深度交流 (2)

可以看到如果配置了contextId就会用contextId,如果没有配置就会去value然后是name最后是serviceId。默认都没有配置,当出现一个服务有多个Feign Client的时候就会报错了。

其次的作用是在注册FeignClient中,contextId会作为Client 别名的一部分,如果配置了qualifier优先用qualifier作为别名。

private void registerFeignClient(BeanDefinitionRegistry registry,       AnnotationMetadata annotationMetadata, Map<String, Object> attributes) {     String className = annotationMetadata.getClassName();     BeanDefinitionBuilder definition = BeanDefinitionBuilder         .genericBeanDefinition(FeignClientFactoryBean.class);     validate(attributes);     definition.addPropertyValue("url", getUrl(attributes));     definition.addPropertyValue("path", getPath(attributes));     String name = getName(attributes);     definition.addPropertyValue("name", name);     String contextId = getContextId(attributes);     definition.addPropertyValue("contextId", contextId);     definition.addPropertyValue("type", className);     definition.addPropertyValue("decode404", attributes.get("decode404"));     definition.addPropertyValue("fallback", attributes.get("fallback"));     definition.addPropertyValue("fallbackFactory", attributes.get("fallbackFactory"));     definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE); // 拼接别名     String alias = contextId + "FeignClient";     AbstractBeanDefinition beanDefinition = definition.getBeanDefinition();     boolean primary = (Boolean) attributes.get("primary"); // has a default, won't be                                 // null     beanDefinition.setPrimary(primary); // 配置了qualifier优先用qualifier     String qualifier = getQualifier(attributes);     if (StringUtils.hasText(qualifier)) {       alias = qualifier;     }     BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, className,         new String[] { alias });     BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);   } url

url用于配置指定服务的地址,相当于直接请求这个服务,不经过Ribbon的服务选择。像调试等场景可以使用。

使用示列

@FeignClient(name = "optimization-user", url = "http://localhost:8085") public interface UserRemoteClient { @GetMapping("/user/get") public User getUser(@RequestParam("id") int id); } decode404

当调用请求发生404错误时,decode404的值为true,那么会执行decoder解码,否则抛出异常。

解码也就是会返回固定的数据格式给你:

{"timestamp":"2020-01-05T09:18:13.154+0000","status":404,"error":"Not Found","message":"No message available","path":"/user/get11"}

抛异常的话就是异常信息了,如果配置了fallback那么就会执行回退逻辑:

那天晚上和@FeignClient注解的深度交流

configuration

configuration是配置Feign配置类,在配置类中可以自定义Feign的Encoder、Decoder、LogLevel、Contract等。

configuration定义

public class FeignConfiguration { @Bean public Logger.Level getLoggerLevel() { return Logger.Level.FULL; } @Bean public BasicAuthRequestInterceptor basicAuthRequestInterceptor() { return new BasicAuthRequestInterceptor("user", "password"); } @Bean public CustomRequestInterceptor customRequestInterceptor() { return new CustomRequestInterceptor(); } // Contract,feignDecoder,feignEncoder..... }

使用示列

@FeignClient(value = "optimization-user", configuration = FeignConfiguration.class) public interface UserRemoteClient { @GetMapping("/user/get") public User getUser(@RequestParam("id")int id); } fallback

定义容错的处理类,也就是回退逻辑,fallback的类必须实现Feign Client的接口,无法知道熔断的异常信息。

fallback定义

@Component public class UserRemoteClientFallback implements UserRemoteClient { @Override public User getUser(int id) { return new User(0, "默认fallback"); } }

使用示列

@FeignClient(value = "optimization-user", fallback = UserRemoteClientFallback.class) public interface UserRemoteClient { @GetMapping("/user/get") public User getUser(@RequestParam("id")int id); } fallbackFactory

也是容错的处理,可以知道熔断的异常信息。

fallbackFactory定义

@Component public class UserRemoteClientFallbackFactory implements FallbackFactory<UserRemoteClient> { private Logger logger = LoggerFactory.getLogger(UserRemoteClientFallbackFactory.class); @Override public UserRemoteClient create(Throwable cause) { return new UserRemoteClient() { @Override public User getUser(int id) { logger.error("UserRemoteClient.getUser异常", cause); return new User(0, "默认"); } }; } }

使用示列

@FeignClient(value = "optimization-user", fallbackFactory = UserRemoteClientFallbackFactory.class) public interface UserRemoteClient { @GetMapping("/user/get") public User getUser(@RequestParam("id")int id); } path

path定义当前FeignClient访问接口时的统一前缀,比如接口地址是/user/get, 如果你定义了前缀是user, 那么具体方法上的路径就只需要写/get 即可。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpdjzp.html