前言
要学习dubbo源码 必须要搞清楚dubbo的spi。它比Java的spi更加灵活。
dubbo扩展点相关的注解
@SPI
@SPI主要标示在接口上,标示这个接口是个扩展点,具体使用那个实现是通过配置去找到具体实现类。这个注解可以接受一个value,这个值和文件(spi获取具体现实类全路径名的文件)里面的key 对应。dubbo的这个文件格式是key:实现类。例如
filter=org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper
listener=org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper
mock=org.apache.dubbo.rpc.support.MockProtocol
dubbo 会从3个路径是读取这个文件,它的代码如下
private static final String SERVICES_DIRECTORY = "META-INF/services/";
private static final String DUBBO_DIRECTORY = "META-INF/dubbo/";
private static final String DUBBO_INTERNAL_DIRECTORY = DUBBO_DIRECTORY + "internal/";
private Map<String, Class<?>> loadExtensionClasses() {
cacheDefaultExtensionName();
Map<String, Class<?>> extensionClasses = new HashMap<>();
loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY, type.getName());
loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY, type.getName().replace("org.apache", "com.alibaba"));
loadDirectory(extensionClasses, DUBBO_DIRECTORY, type.getName());
loadDirectory(extensionClasses, DUBBO_DIRECTORY, type.getName().replace("org.apache", "com.alibaba"));
loadDirectory(extensionClasses, SERVICES_DIRECTORY, type.getName());
loadDirectory(extensionClasses, SERVICES_DIRECTORY, type.getName().replace("org.apache", "com.alibaba"));
return extensionClasses;
}
总结就是/META-INF/services /META-INF/dubbo /META-INF/dubbo/internal 3个路径
@Adaptive
当这个注解标注在方法上的时候,这个方法的入参一定是带有URL这个在dubbo定义的一个对象的。在扫描到这个扩展点的这个方法的注解的时候,会生成一个代理类,在这个方法里,会获取URL,他是和个接口名字一样的一个属性,(例如protocol接口的export方法有@adaptive注解它生成的代理类就会从url里面获取一个protocol属性的值)这个属性的值是来获取对应的扩展实现类的。如果异常就用获取默认的扩展实现类,它生成这个类的方式就是通过string字符串去拼接这个代理类然后在用编译器编译为class。它生成的类如下:例子是 Protocol的扩展Adaptive
package org.apache.dubbo.rpc;
import org.apache.dubbo.co