seata openfeign 实现传播xid源码解析

依赖

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

源码

  • 自动配置
  1. 注册FEIGN对象包装器
  2. 注册BEAN后处理器,包装FeignClient
  3. 注册BEAN后处理器,包装FeignContext
    com.alibaba.cloud.seata.feign.SeataFeignClientAutoConfiguration
@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
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
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
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());
}

posted on 2022-04-11 22:38  路过君  阅读(445)  评论(0编辑  收藏  举报

导航