这篇文章主要介绍“如何在Dubbo拦截器中拿到Invoker的引用对象”,在日常操作中,相信很多人在如何在Dubbo拦截器中拿到Invoker的引用对象问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何在Dubbo拦截器中拿到Invoker的引用对象”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
本文基于Dubbo 2.7.8。
当我们自定义Dubbo拦截器的时,有时候想要拿到代理对象(这里的代理对象是指Spring容器中的实际对象,可能已经被Cglib或Jdk代理),这里提供一种简单可行的方案。目前2.7.5及以上版本可用
先来看一下Dubbo服务导出的调用链:
//导出所有服务
private void exportServices() {
configManager.getServices().forEach(sc -> {
// TODO, compatible with ServiceConfig.export()
ServiceConfig serviceConfig = (ServiceConfig) sc;
serviceConfig.setBootstrap(this);
if (exportAsync) {
ExecutorService executor = executorRepository.getServiceExporterExecutor();
Future<?> future = executor.submit(() -> {
sc.export();
exportedServices.add(sc);
});
asyncExportingFutures.add(future);
} else {
sc.export();
exportedServices.add(sc);
}
});
}
//单个服务导出
public synchronized void export()
//是否需要导出
if (!shouldExport()) {
return;
}
checkAndUpdateSubConfigs();
doExport();
exported();
}
protected synchronized void doExport() {
if (exported) {
return;
}
exported = true;
if (StringUtils.isEmpty(path)) {
path = interfaceName;
}
doExportUrls();
}
private void doExportUrls() {
//这里是重点
ServiceRepository repository = ApplicationModel.getServiceRepository();
ServiceDescriptor serviceDescriptor = repository.registerService(getInterfaceClass());
repository.registerProvider(
getUniqueServiceName(),
ref,
serviceDescriptor,
this,
serviceMetadata
);
}
//注册提供者
public void registerProvider(String serviceKey,
Object serviceInstance,
ServiceDescriptor serviceModel,
ServiceConfigBase<?> serviceConfig,
ServiceMetadata serviceMetadata) {
ProviderModel providerModel = new ProviderModel(serviceKey, serviceInstance, serviceModel, serviceConfig,
serviceMetadata);
//key为serviceKey
providers.putIfAbsent(serviceKey, providerModel);
providersWithoutGroup.putIfAbsent(keyWithoutGroup(serviceKey), providerModel);
}
可以看到在Dubbo服务导出的时候会向ServiceRepository注册服务信息,而我们在Filter中可以通过Invocation的getTargetServiceUniqueName拿到serviceKey。
结果显而易见:
直接通过以下方式就可以拿到代理对象:
ProviderModel providerModel = ApplicationModel.getServiceRepository().lookupExportedService(invocation.getTargetServiceUniqueName());
System.out.println(providerModel.getServiceInstance().getClass());
到此,关于“如何在Dubbo拦截器中拿到Invoker的引用对象”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注天达云网站,小编会继续努力为大家带来更多实用的文章!