dubbo插件机制

来源:互联网 发布:中国税务网络大学ios 编辑:程序博客网 时间:2024/05/16 11:20

可以通过在classpath的META-INF/dubbo/internal/、META-INF/dubbo/、META-INF/services/目录下放置文件来定义扩展点,文件名称为组件接口的类全名,文件内容为扩展名=实现类名的形式,例如:

Protocol的扩展点文件(文件名称com.alibaba.dubbo.rpc.Protocol)

框架通过ExtensionLoader负责加载/存储扩展点实例,每个组件接口有一个对应的ExtensionLoader实例负责加载该组件扩展点,有三种方式加载:

(1)名称加载扩展点

(2)加载激活扩展点

(3)加载自适应扩展点

名称加载扩展点

对应ExtensionLoader.getExtension方法,这是最直观的方式,在补始化时框架会读取classpath下所有扩展点文件形成多个键值对,存放在扩展点对应的ExtensionLoader中,比如要获取名称为dubbo的Protocol扩展点,那么就会返回一个DubboProtocol实例,但是框架还有种特殊的扩展点叫Wrapper扩展点,这类扩展点一般做一些适配和封装性的工作。当有Wrapper扩展点时,获取任何名称的扩展点都会返回Wrapper实例,Wrapper实例封装真实的扩展实现,当有多个Wrapper实现时,会Wrapper封装Wrapper,形成一个链式的结构,比如获取名称是dubbo的Protocol扩展点,通过ExtensionLoader.getExtension("dubbo")获取,ExtensionLoader会返回一个ProtocolListenerWrapper实例,ProtocolListenerWrapper实例持有一个ProtocolFilterWrapper实例,ProtocolListenerWrapper实例持有一个DubboProtocol实例,对象引用关系:
ProtocolListenerWrapper->ProtocolFilterWrapper->DubboProtocol.

加载激活扩展点

对应ExtensionLoader.getActivateExtension方法在应用进行dubbo调用时,dubbo框架会根据条件加载一些自动激活的扩展点,最典型就是Filter组件,dubbo接口调用时会激活应用配置和框架内置的Filter调用链。自动激活的扩展点一般通过两种形式定义:(1)通过Activate注解,框架启动时ExtensionLoader会加载所有带Activate注解的接口实现,并存放在一个Map中,key是扩展点实现的类名首字母小写,如果实现类的结尾是接口名称,截掉这个接口名称,比如MonitorFilter实现,处理之后key就是monitor。

在查找被激活的扩展点时,如果Activate注解设置了group和values属性,要根据这两个属性进行过滤,group属性有两个枚举值:provider consumer,设置了group="provider"则调用端会加载此扩展点,设置了group="consumer"则调用时消费端会加载此扩展点,当然还要有个前提条件,就是应用层没有禁用此扩展点,禁用的方式 就是在配置时扩展点名称前加个-号,比如设置了filter="-monitor",那么不会激活MonitorFilter这个扩展点。如果values属性设置了值,那么框架会检查此次调用所有信息的URL的parameterds中是否存在values中的key,如果有的话也激活该扩展点。

加载自适应扩展点

对应ExtensionLoader.getAdaptiveExtension方法,每一次dubbo接口调用都是框架中的多个不同的组件来合作完成的,这时候完成核心工作的组件也是通过ExtensionLoader来加载的,加载的扩展点由调用上下文决定,这种扩展点加载方式叫自适应加载。Dubbo框架cefepAdaptive注解来定义自适应扩展点,同一个扩展点接口的实现中最多只能有一个实现 类可以定义Adaptive注解,定义了Adaptive注解的扩展点就是被加载到的自适应扩展点Map中,如果所有实现都没有使用Adaptive注解,那么接口需要使用SPI注解,并且设置value属性,value属性值就是默认扩展点的名称 ,如果UR中未指定加载哪个扩展点则加载默认扩展点。同是需要扩展的方法 也打上Adaptive注解,自适应扩展点加载逻辑是:在URL中获取扩展点名称,这个名称一般放在URL的某个属性或者parameters的某个key中,假如URL中没有取到默认值 ,就使用SPI注解中指定的value属性。每个组件的自适应扩展点的加载都通过该接口的一个代理实现 来完成,框架为了消除重复代码,该代理类并没有对应的静态代码,代码是dubbo框架通过一个代码模板在运行时生成的,通过Compiler组件把生的代码编译并加载成代理类class。

转自:http://blog.csdn.net/tolihaifeng/article/details/60967621