通过ExtensionLoader的getExtension方法,传入短名称,这样就可以精确地找到短名称对的实现类 。
所以从这可以看出Dubbo的SPI机制解决了前面提到的无法获取指定实现类的问题 。
测试结果:
文章插图
dubbo的SPI机制除了解决了无法获取指定实现类的问题,还提供了很多额外的功能,这些功能在dubbo内部用的非常多,接下来就来详细讲讲 。
dubbo核心机制1、自适应机制自适应,自适应扩展类的含义是说,基于参数,在运行时动态选择到具体的目标类,然后执行 。
每个接口有且只能有一个自适应类,通过ExtensionLoader的getAdaptiveExtension方法就可以获取到这个类的对象,这个对象可以根据运行时具体的参数找到目标实现类对象,然后调用目标对象的方法 。
举个例子,假设上面的LoadBalance有个自适应对象,那么获取到这个自适应对象之后,如果在运行期间传入了random这个key,那么这个自适应对象就会找到random这个key对应的实现类,调用那个实现类的方法,如果动态传入了其它的key,就路由到其它的实现类 。
自适应类有两种方式产生,第一种就是自己指定,在接口的实现类上加@Adaptive注解,那么这个这个实现类就是自适应实现类 。
@Adaptivepublic class RandomLoadBalance implements LoadBalance{}
除了自己代码指定,还有一种就是dubbo会根据一些条件帮你动态生成一个自适应类,生成过程比较复杂,这里就不展开了 。自适应机制在Dubbo中用的非常多,而且很多都是自动生成的,如果你不知道Dubbo的自适应机制,你在读源码的时候可能都不知道为什么代码可以走到那里 。。
2、IOC和AOP一提到IOC和AOP,立马想到的都是Spring,但是IOC和AOP并不是Spring特有的概念,Dubbo也实现IOC和AOP的功能,但是是一个轻量级的 。
2.1、依赖注入
Dubbo依赖注入是通过setter注入的方式,注入的对象默认就是上面提到的自适应的对象,在Spring环境下可以注入Spring Bean 。
public class RoundRobinLoadBalance implements LoadBalance {private LoadBalance loadBalance;public void setLoadBalance(LoadBalance loadBalance) {this.loadBalance = loadBalance;}}
如上代码,RoundRobinLoadBalance中有一个setLoadBalance方法,参数LoadBalance,在创建RoundRobinLoadBalance的时候,在非Spring环境底下,Dubbo就会找到LoadBalance自适应对象然后通过反射注入 。这种方式在Dubbo中也很常见,比如如下的一个场景
文章插图
RegistryProtocol中会注入一个Protocol,其实这个注入的Protocol就是一个自适应对象 。
2.2、接口回调
Dubbo也提供了一些类似于Spring的一些接口的回调功能,比如说,如果你的类实现了Lifecycle接口,那么创建或者销毁的时候就会回调以下几个方法
文章插图
在dubbo3.x的某个版本之后,dubbo提供了更多接口回调,比如说ExtensionPostProcessor、ExtensionAccessorAware,命名跟Spring的非常相似,作用也差不多 。
2.3、自动包装
自动包装其实就是aop的功能实现,对目标对象进行代理,并且这个aop功能在默认情况下就是开启的 。
在Dubbo中SPI接口的实现中,有一种特殊的类,被称为Wrapper类,这个类的作用就是来实现AOP的 。
判断Wrapper类的唯一标准就是这个类中必须要有这么一个构造参数,这个构造方法的参数只有一个,并且参数类型就是接口的类型,如下代码:
public class RoundRobinLoadBalance implements LoadBalance {private final LoadBalance loadBalance;public RoundRobinLoadBalance(LoadBalance loadBalance) {this.loadBalance = loadBalance;}}
此时RoundRobinLoadBalance就是一个Wrapper类 。当通过random获取RandomLoadBalance目标对象时,那么默认情况下就会对RandomLoadBalance进行包装,真正获取到的其实是RoundRobinLoadBalance对象,RoundRobinLoadBalance内部引用的对象是RandomLoadBalance 。
测试一下
在配置文件中加入
roundrobin=com.sanyou.spi.demo.RoundRobinLoadBalance
测试结果
文章插图
从结果可以看出,虽然指定了random,但是实际获取到的是RoundRobinLoadBalance,而RoundRobinLoadBalance内部引用了RandomLoadBalance 。
推荐阅读
- 静态路由or动态路由,一个例子说明白!
- 贾玲|真被热巴说中了!曝贾玲秘密生子,范丞丞冲上热搜榜一
- 阿里p6是什么级别(p6级别工资标准)
- 闭口是什么意思(如何去闭口)
- 厂长为什么叫7酱(lpl解说鼓鼓多人运动)
- 裁剪视频用什么软件(电商视频剪辑用什么软件)
- 拜灶神要说什么 拜灶神要怎样说话
- 西装裤配什么鞋子(西装裤怎么搭配上衣)
- 谛听为什么不说出真相(谛听为啥听出来真假不说)
- 每个手指戴戒指的含义怎么说 每个手指戴戒指的含义