seata openfeign 实现传播xid源码解析

2022-01-10 09:30:29 浏览数 (1)

依赖

com.alibaba.cloud:spring-cloud-starter-alibaba-seata:2021.1

源码

  • 自动配置
  1. 注册FEIGN对象包装器
  2. 注册BEAN后处理器,包装FeignClient
  3. 注册BEAN后处理器,包装FeignContext com.alibaba.cloud.seata.feign.SeataFeignClientAutoConfiguration
代码语言:javascript复制
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Client.class)
@AutoConfigureBefore(FeignAutoConfiguration.class)
public class SeataFeignClientAutoConfiguration {
...
@Configuration(proxyBeanMethods = false)
	protected static class FeignBeanPostProcessorConfiguration {
		// 处理FeignClient 对象
 		@Bean
		SeataBeanPostProcessor seataBeanPostProcessor(
				SeataFeignObjectWrapper seataFeignObjectWrapper) {
			return new SeataBeanPostProcessor(seataFeignObjectWrapper);
		}
		// 处理FeignContext 对象
		@Bean
		SeataContextBeanPostProcessor seataContextBeanPostProcessor(
				BeanFactory beanFactory) {
			return new SeataContextBeanPostProcessor(beanFactory);
		}
		// FeignClient 对象包装器
		@Bean
		SeataFeignObjectWrapper seataFeignObjectWrapper(BeanFactory beanFactory) {
			return new SeataFeignObjectWrapper(beanFactory);
		}
	}
...
}
  • 包装FeignClient 使用SeataFeignBlockingLoadBalancerClient包装FeignBlockingLoadBalancerClient 使用SeataFeignClient包装其他Client com.alibaba.cloud.seata.feign.SeataFeignObjectWrapper
代码语言:javascript复制
Object wrap(Object bean) {
	if (bean instanceof Client && !(bean instanceof SeataFeignClient)) {
		if (bean instanceof FeignBlockingLoadBalancerClient) {
			FeignBlockingLoadBalancerClient client = (FeignBlockingLoadBalancerClient) bean;
			return new SeataFeignBlockingLoadBalancerClient(client.getDelegate(),
					beanFactory.getBean(BlockingLoadBalancerClient.class),
					beanFactory.getBean(LoadBalancerProperties.class),
					beanFactory.getBean(LoadBalancerClientFactory.class),
					this);
		}
		return new SeataFeignClient(this.beanFactory, (Client) bean);
	}
	return bean;
}
  • 包装FeignContext 使用SeataFeignContext包装FeignContext com.alibaba.cloud.seata.feign.SeataContextBeanPostProcessor
代码语言:javascript复制
public Object postProcessBeforeInitialization(Object bean, String beanName)
			throws BeansException {
	if (bean instanceof FeignContext && !(bean instanceof SeataFeignContext)) {
		return new SeataFeignContext(getSeataFeignObjectWrapper(),
				(FeignContext) bean);
	}
	return bean;
}
  • SeataFeignClient 将XID写入header com.alibaba.cloud.seata.feign.SeataFeignClient
代码语言:javascript复制
private Request getModifyRequest(Request request) {
	String xid = RootContext.getXID();
	if (StringUtils.isEmpty(xid)) {
		return request;
	}
	Map<String, Collection<String>> headers = new HashMap<>(MAP_SIZE);
	headers.putAll(request.headers());
	List<String> seataXid = new ArrayList<>();
	seataXid.add(xid);
	headers.put(RootContext.KEY_XID, seataXid);
	return Request.create(request.method(), request.url(), headers, request.body(),
			request.charset());
}

0 人点赞