Dubbo/Dubbox的服务消费(一)- 服务代理的创建

本文详细探讨了Dubbo消费者初始化过程,包括如何通过Spring配置创建服务代理bean,重点分析了FactoryBean的作用,以及在Dubbo中如何生成服务代理对象,涉及到的扩展点机制和ProxyFactory的实现。同时,提到了EchoService接口在服务检测中的应用。
摘要由CSDN通过智能技术生成

dubbo的consumer的初始过程

一个常见的consumer配置是这样的

<dubbo:reference id="dubboDemo" interface="com.company.dsp.adcenter.protocol.dubbo.DubboDemo"
                 protocol="dubbo"/>

这样spring会创建一个beanName为dubboDemo的bean,使用上是这样的

@Resource(name = "dubboDemo")
private DubboDemo dubboDemo;

那么问题来了why why why? dubbo是怎么创建这样的bean的?全程都没有要求我们使用bean标签,也没有要求使用Componment和Service注解,即使使用显示的方式声明一个Bean,那我们也没有相关的实现类啊。

既然我们已经拥有上面的配置项,拍脑袋一想,已知dubbo启动时会利用spring对自定义配置项的spring.handles文件加载对应的handler解析自定义节点,且上文书已经分析
dubbo:reference节点的配置项存储在com.alibaba.dubbo.config.spring.ReferenceBean 中,该类的uml图如下。
这里写图片描述
可见该类集成自com.alibaba.dubbo.config.ReferenceConfig 类,并实现了下面四个接口

org.springframework.beans.factory.FactoryBean
org.springframework.context.ApplicationContextAware
org.springframework.beans.factory.InitializingBean
org.springframework.beans.factory.DisposableBean

InitializingBean和ApplicationContextAware我们都很熟悉了,还没详细了解过FactoryBean,不过这里有一个道友的文章可以看看《FactoryBean的实现原理与作用》
其中提到了以下两句

OK,那么这个时候我们getBean(“personFactory”)得到的就是Person对象而不是PersonFactoryBean对象。具体原理参考上面在IOC的应用,我们通过bean = getObjectForBeanInstance(sharedInstance, name, beanName, null)这个方法,具体调用到了getObject方法,所以结果很明显。
通过上面的小案例的代码,我们可以看到如果一个类实现了FactoryBean接口,那么getBean得到的不是他本身了,而是它所产生的对象,如果我们希望得到它本身,只需要加上&符号即可。至于FactoryBean的实际应用,需要大家去发现理解,后面如果有机会会继续聊聊这个东西。

那把目光转向:com.alibaba.dubbo.config.spring.ReferenceBean,开启找寻getObject方法之旅

/**
    * ReferenceFactoryBean
    *
    * @author william.liangf
    * @export
    */
    public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean, ApplicationContextAware, InitializingBean, DisposableBean {
   
        //......
        public Object getObject() throws Exception {
        return get();
        }
        //......
    }

其中get()方法 继承自com.alibaba.dubbo.config.ReferenceConfig

 public synchronized T get() {
        if (destroyed){
            throw new IllegalStateException("Already destroyed!");
        }
        if (ref == null) {
            init();
        }
        return ref;
    }

可见get方法内部调用了一个init()方法

private void init() {
        if (initialized) {
            return;
        }
        initialized = true; //初始化标记,防止重复创建对象
        if (interfaceName == null || interfaceName.length() == 0) {
            throw new IllegalStateException("<dubbo:reference interface=\"\" /> interface not allow null!");
        }
        // 获取消费者全局配置,检查consumer是否有配置,如果该属性为null,则new一个ConsumerConfig对象
        // 方法内部调用appendProperties(consumer)方法,该方法内部会拼装一个 dubbo.tagName.属性名的key,在配置文件中查找值,如果有值则调用属性的setter方法,设置属性值。
        checkDefault();
        // 上边注释已经说明appendProperties方法用途
        appendProperties(this);
        if (getGeneric() == null && getConsumer() != null) { //判断是不是泛化调用
            setGeneric(getConsumer().getGeneric());
        }
        if (ProtocolUtils.isGeneric(getGeneric())) {
            interfaceClass = GenericService.class;
        } else {
            try {
                interfaceClass = Class.forName(interfaceName, true, Thread.currentThread()
                .getContextClassLoader());
            } catch (ClassNotFoundException e) {
                throw new IllegalStateException(e.getMessage(), e);
            }
            //继承自com.alibaba.dubbo.config.AbstractInterfaceConfig
            //检查接口类中是否存在指定的方法,如果dubbo:service->dubbo:method 没有配置的情况下,methods为null,该方法不会执行方法校验。
            //如果有相关的配置,该方法会检查name属性对应的方法是否存在,不存在会抛IllegalStateException异常。
            checkInterfaceAndMethods(interfaceClass, methods);
        }
        //用-Ddubbo.resolve.file指定映射文件路径,此配置优先级高于<dubbo:reference>中的配置,1.0.15及以上版本支持
        //......省略-Ddubbo.resolve.file的解析代码行......//
        //........省略进一步初始化相关配置的代码行 .......//
        //检查应用配置,如果没有配置会创建默认对象。其内部会调用appendProperties(AbstractConfig config) 填充属性。
        //检查失败会抛出IllegalStateException异常
        checkApplication();
        //
        c
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值