dubbo最核心的思想就是就是SPI服务发现,可以实现动态加载实现类。http://dubbo.apache.org/zh-cn/docs/dev/SPI.html 在dubbo的官方文档中用扩展点的介绍。我们可以看到,dubbo扩展点主要有四大特性
- 扩展点自动包装。
- 扩展点自动装配.
- 扩展点自适应.
- 扩展点自动激活
接下来我会以Dubbo的Protocol 接口为例来说明一下dubbo的四大特性。
@SPI("dubbo")
public interface Protocol {
int getDefaultPort();
@Adaptive
<T> Exporter<T> export(Invoker<T> invoker) throws RpcException;
@Adaptive
<T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;
void destroy();
}
我们首先看第一条,扩展点自动包装,自动包装扩展点的Wrapper类。ExtensionLoader在加载扩展点时,如果加载到的扩展点有拷贝构造函数,则判定为扩展点Wrapper类。以Protocol为例。我们可以看一下Protocol的继承关系。
我们可以看到,其中有两个是以Wrapper结尾,点进去看一下这两个类,我们可以看到,他们都是有一个构造函数,参数是Protocol,也就是拷贝构造函数。那么,当dubbo扫描到这两个类时,就会把他们当作Protocol的包装类。
接下来再看官方文档,下面有介绍:“Wrapper 类同样实现了扩展点接口,但是 Wrapper 不是扩展点的真正实现。它的用途主要是用于从 ExtensionLoader 返回扩展点时,包装在真正的扩展点实现外。即从 ExtensionLoader 中返回的实际上是 Wrapper 类的实例,Wrapper 持有了实际的扩展点实现类。”
也就是我们拿到的扩展点实例其实都是经过了Wrapper包装。
接下来我们可以再去源码看看他是怎么实现的。我们看一下Dubbo ExtensionLoader中的源码
private T createExtension(String name)