dubbo 直连解决方案

1 篇文章 0 订阅

要做什么

看dubbo官网后发现有dubbo直连这种方式,简化了我们开发环境的流程,不再需要启动注册中心。于是想要应用到自己项目中去。
但是各类网站看了很多dubbo直连的案例,基本都和官网一致,一个一个service 指定 url,这样的方式不太符合我们自己项目,我想要的是所有的service 使用 dubbo://127.0.0.1:20880 url

dubbo版本:2.7.8

源码过程分析

这里先创建的一个又Spring 管理的Controller, 其中只有一个属性且被Reference 注解标识,然后我们看一下这个实力注入流程:
一、 扫描到Controller 类进行实例化
二、 populate 属性注入
在这一步 扫描到Reference注解标识的属性,开始生成代理对象

org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor#doGetInjectedBean
// 进行一系列解析,不过多赘述,这步之前已经解析完注解
调用referenceBean.get()

执行 org.apache.dubbo.config.ReferenceConfig#init
org.apache.dubbo.config.ReferenceConfig#checkAndUpdateSubConfigs
org.apache.dubbo.config.ReferenceConfigBase#resolveFile  // 这个地方解析了dubbo文件 中配置的url

org.apache.dubbo.config.ReferenceConfig#postProcessConfig // 这里是一个可扩展点,如何扩展往下面看
//方法源码
private void postProcessConfig() {
        List<ConfigPostProcessor> configPostProcessors = ExtensionLoader.getExtensionLoader(ConfigPostProcessor.class)
                .getActivateExtension(URL.valueOf("configPostProcessor://"), (String[]) null);
        configPostProcessors.forEach(component -> component.postProcessReferConfig(this));
} 

ConfigPostProcessor 接口点进去发现是一个spi扩展接口
虽然官网没写这个接口如何扩展,我们可以仿造其他的spi扩展 以及自己debug

首先 实现ConfigPostProcessor 接口可以设置ReferenceConfig 的属性,后面会将其属性加入到一个map,之后利用map创建代理类(也在init方法中, 创建赋值给ref,前面的referenceBean.get() 返回的就是ref)

最开始的想法:
利用filter,每次调用前 切换invoker中的url,不太好设置
利用spring 的扩展,bpp 等方法,判断其中的不是reference的属性,进行修改

实际coding

基于ConfigPostProcessor 接口进行spi扩展

@Activate(group = {CommonConstants.CONSUMER})
public class DubboRedirectConfigPostProcessor implements ConfigPostProcessor {

    public static final String DUBBO_URL = "dubbo://127.0.0.1:20880";

    /**
     * org.apache.dubbo.config.ReferenceConfig#postProcessConfig() 调用
     * @param referenceConfig
     */
    public void postProcessReferConfig(ReferenceConfig referenceConfig) {
    	// referenceConfig 在这是 org.apache.dubbo.config.spring.ReferenceBean
        referenceConfig.setUrl(DUBBO_URL);
    }
}

在META-INF.dubbo下创建com.alibaba.dubbo.config.ConfigPostProcessor 的文件,
写入你的全路径实现类dubboDirect=com.config.DubboDirectConfigPostProcessor

如果你上述步骤没有问题,
configPostProcessors 就成功加入了你的实现类, 可以再postProcessReferConfig 方法中实现更多的扩展

其他配置就和官网介绍一的一样了,服务提供方 在application.properties
dubbo.registry.check=false
dubbo.registry.address=N/A

只在dev生效

DubboRedirectConfigPostProcessor 实现EnvironmentAware 接口,判断getActiveProfiles 环境 是否需要执行postProcessReferConfig 方法就可以了,

在dubbo中 有这样的org.apache.dubbo.config.spring.extension.SpringExtensionFactory,其中包含了spring 的上下文对象,源码中在实例化后,解析方法,解析到setEnvironment 标准命名的方法后,从上下文对象中获取 Environment 对象作为参数, 执行此方法

org.apache.dubbo.common.extension.ExtensionLoader#getExtension(java.lang.String, boolean)
org.apache.dubbo.common.extension.ExtensionLoader#createExtension


 try {
                    String property = getSetterProperty(method);
                    // 从spring上下文 获取到Environment 
                    Object object = objectFactory.getExtension(pt, property);
                    if (object != null) {
                    	// 执行set方法
                        method.invoke(instance, object);
                    }
                } catch (Exception e) {
                    logger.error("Failed to inject via method " + method.getName()
                            + " of interface " + type.getName() + ": " + e.getMessage(), e);
                }

git地址

https://github.com/zhaokun-12/dubbo-direct-demo.git

二次完善

这样的写法,每增加一个消费服务都需要将以上的内容重新copy一遍,比较烦人,于是决定单独抽出一个依赖包,在实现的过程中发现抽出的依赖包中的resources文件没有读取到,于是debug变天,发现源码中的确是有扫描所有的依赖包是否包含spi的扩展文件,仔细查看发现包没有成功被加载进来,书写错误导致浪费了大量的时间

org.apache.dubbo.common.extension.ExtensionLoader#loadExtensionClasses
org.apache.dubbo.common.extension.ExtensionLoader#loadDirectory(java.util.Map<java.lang.String,java.lang.Class<?>>, java.lang.String, java.lang.String, boolean, boolean, java.lang.String...)
if (urls != null) {
//urls.hasMoreElements() 实际去读文件资源
                while (urls.hasMoreElements()) {
                    java.net.URL resourceURL = urls.nextElement();
                    loadResource(extensionClasses, classLoader, resourceURL, overridden, excludedPackages);
                }
            }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值