Open testc1 opened 1 year ago
还有一个问题,在使用了Agent插件时,已经设置在了request中,为什么还在再设置在restStrategyContext中,但道理两个都设置了,但是异步场景下,直接从RequestContextHolder.getRequestAttributes();中还是娶不到,只有从RestStrategyContext.getCurrentContext().getRequestAttributes();才能取到 @Override public Object create() { RequestAttributes request = RequestContextHolder.getRequestAttributes(); if (requestDecoratorEnabled) { if (null != request) { request = ServiceStrategyRequestDecoratorFactory.decorateRequestAttributes(request); } } return request; }
@SuppressWarnings("unchecked")
@Override
public void before(Object object) {
if (object instanceof RequestAttributes) {
RequestAttributes requestAttributes = (RequestAttributes) object;
RequestContextHolder.setRequestAttributes(requestAttributes);
RestStrategyContext.getCurrentContext().setRequestAttributes(requestAttributes);
}
}
第一个问题,如果用了同步,上下文会从RequestContextHolder去取,这是Spring Boot自带的,它会主动清理,如果用了异步,那必须用DiscoveryAgent,它里面有清理代码,所有,两种情况都不会造成泄露
第二个问题,Agent下,Spring Boot 自带的会发生取不到的情况,所以框架自己维护了一个threadlocal,保证能取到
①RequestAttributes requestAttributes = RestStrategyContext.getCurrentContext().getRequestAttributes(); ②public static RestStrategyContext getCurrentContext() { return THREAD_LOCAL.get(); } ③ public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) { @SuppressWarnings("unchecked") T result = (T)e.value; return result; } } return setInitialValue(); }
在调入到第三部的时候,会调用 private static final ThreadLocal
public ServletRequestAttributes getRestAttributes() { RequestAttributes requestAttributes = RestStrategyContext.getCurrentContext().getRequestAttributes(); if (requestAttributes == null) { requestAttributes = RequestContextHolder.getRequestAttributes(); }
return (ServletRequestAttributes) requestAttributes;
}
这里获取的时候,可以换成先从 RequestContextHolder.getRequestAttributes() 这里为空,再从RestStrategyContext.getCurrentContext().getRequestAttributes()里边取吗?这样有问题吗?能不能避免先从RestStrategyContext中取,同步调用下,给当前线程绑定RestStrategyContext而没清理的情况
同步情况下,RestStrategyContext.getCurrentContext().getRequestAttributes()返回的是null
public ServletRequestAttributes getRestAttributes() { // 异步场景下 会复制请求信息到RestStrategyContext RequestAttributes requestAttributes = RestStrategyContext.getCurrentContext().getRequestAttributes(); if (requestAttributes == null) { requestAttributes = RequestContextHolder.getRequestAttributes(); } return (ServletRequestAttributes) requestAttributes; }