千家信息网

如何在Dubbo拦截器中拿到Invoker的引用对象

发表于:2025-01-31 作者:千家信息网编辑
千家信息网最后更新 2025年01月31日,这篇文章主要介绍"如何在Dubbo拦截器中拿到Invoker的引用对象",在日常操作中,相信很多人在如何在Dubbo拦截器中拿到Invoker的引用对象问题上存在疑惑,小编查阅了各式资料,整理出简单好
千家信息网最后更新 2025年01月31日如何在Dubbo拦截器中拿到Invoker的引用对象

这篇文章主要介绍"如何在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的引用对象"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

0