dubbo的可扩展机制SPI源码解析(二)

1、基本流程
2、AOP
3、IOC
4、AdaptiveExtension
5、ActivateExtension

getExtension(name)
getAdaptiveExtension(URL)
getAdaptiveExtension(URL,扩展点名称,group名称)

dubbo spi的使用:
    需要设置的地方:
    1)resource文件夹增加接口全路径名称的文件
    2)接口类增加@SPI注解。
    3)被代理的对象增加@Adaptive注解
    配置好spi后执行的时候,是根据配置文件的key找到一个代理对象(此代理对象是根据配置的实现类的实例实现的,被代理的方法实现逻辑是,根据com.alibaba.dubbo.common.URL参数,拿到文件key,根据key找)

ExtensionLoader  -- 扩展点加载器
    1、type ---- 接口
    2、objectFactory   ----> 实现类的对象  ---- Spring容器(type)
    
    方法
    1、getExtension(name)----
    2、createExtension(name)  ----> 创建对象
        1、name--->实现类的全路径名字
            加载文件,遍历扫描文件内容,找到实现类的名字,放到map中。
            扫描到的wrapper类名字都放到一个set中,供依赖注入后使用生成wrapper类实例            
        2、实例化(newInstance)-------carFilter
        3、依赖注入
            是通过set方法来设置属性的。
            找到类的方法和参数,根据属性和方法找到对象,然后通过反射设置属性值(method.invoke(instance,object))
            依赖注入后,会根据上一步的接口实例生成wrapper类的实例(传入了instance)。如果有多个wrapper的话,会把上一次生成的wrapper类实例当成一个实例传入,然后生成一个新的wrapper类实例,就像套娃一样。
        4、AOP
        5、return instance
    3、loadExtensionClasses()  --  return Map
    
    
    
1 三者的关系
    SpiExtensionFactory
        要使用这个来获取对象,必须在接口上使用@SPI注解。
        获取的过程:先找到加载器,loader.getAdaptiveExtension()获取接口的Adaptive类(是一个代理对象)。
            解决方法上必须使用@Adaptive注解,才能默认生成代理类。而且需要被代理的方法也必须有个com.alibaba.dubbo.common.URL(dubbo服务提供者的url)参数
            如果接口方法没有指定Adaptive类,dubbo会默认生成一个
                ExtensionLoader的代码:
                //生成java类的代码
                String code = this.createAdaptiveExtensionClassCode();
                ClassLoader classLoader = findClassLoader();
                Compiler compiler = (Compiler)getExtensionLoader(Compiler.class).getAdaptiveExtension();
                //编译成class类
                return compiler.compile(code, classLoader);

    SpinrgExtensionFactory
        是从ApplicationContext(Spring容器)中先根据名称去拿对象实例,如果没有找到再根据type去拿。
    AdaptiveExtensionFactory:用来判断是适用spi的factory还是spring的factory。
    具体再适用的时候,如果接口上制定了@SPI的注解,那就只能适用SpiExtensionFactory,否则,只要从一个factory中生成了对象实例就返回。
    
    
    group 只是一个表示,不仅仅有PROVIDER和CONSUMER,可以随便定义
@Activate(group={PROVIDER,CONSUMER})    
    服务端和消费端都可以使用
@Activate(group=CommonConstants.PROVIDER)
    只能服务端使用
@Activate(group=CommonConstants.PROVIDER,value="condition_param")
    服务端使用,而且必须满足value配合的条件时才可使用

    
    
    
    
    
    
    
    
    
    
    
    

未分类
匿名

发表评论

匿名网友