温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

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

发布时间:2021-09-14 22:53:25 来源:亿速云 阅读:202 作者:chen 栏目:云计算

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

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI