Dubbo版本:org.apache.dubbo:dubbo-bom:3.2.5
SpringBoot:3.1.2
根据 https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/description/filter/ 文档,在使用拦截器时,无法获取 AopAspect 类中 ThreadLocal 数据,经过调试发现:
在 Controller 中 与在 Filter 中,两个 AopAspect.class
不是一个对象,两个 AopAspect.LISTS
不是同一个 ThreadLocal 对象,导致在 Filter 中无法获取到数据。
@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class AopAspect {
/**
* 当前请求的某个数据列表
*/
public static final ThreadLocal<List<?>> LISTS = new ThreadLocal<>();
}
@Slf4j
@Activate(group = CommonConstants.CONSUMER, order = -10000, onClass = {OBJECT_MAPPER_CLASS_NAME})
public class MyConsumerFilter implements Filter {
public static final String KEY = DataScope.class.getName() + "#Dubbo";
private final ObjectMapperCodec mapper;
public MyConsumerFilter(ApplicationModel applicationModel) {
this.mapper = applicationModel.getBeanFactory().getBean(ObjectMapperCodec.class);
}
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
log.info("消费者");
Result result;
try {
initContext(invocation);
result = invoker.invoke(invocation);
} finally {
invocation.getObjectAttachments().remove(KEY);
}
return result;
}
private void initContext(Invocation invocation) {
// 在 Controller 中,这个是有数据的,但是在 Filter 中无法获取数据
List<?> lists = AopAspect.LISTS.get();
if (lists == null || lists.isEmpty()) {
return;
}
String context = mapper.serialize(new MyContext(lists));
log.info("消费者:{}", context);
invocation.setObjectAttachment(KEY, context);
}
}
在 META-INF/dubbo/org.apache.dubbo.rpc.Filter
文本文件中增加
MyConsumerFilter=com.houkunlin.MyConsumerFilter