Dubbo SPI 机制分析
创建测试 demo
package com. luban. dubbo_spi. api ;
@SPI
public interface Car {
public void getColor ( ) ;
}
package com. luban. dubbo_spi. impl ;
public class RedCar implements Car {
public void getColor ( ) {
System . out. println ( "red" ) ;
}
}
然后在 resources 创建一个目录 META-INF.services 目录 并在 META-INF.services 目录中创建文件 com.luban.dubbo_spi.api.Car 一定要与接口同名
red = com.luban.dubbo_spi.impl.RedCar
public class CarDemo {
public static void main ( String [ ] args) {
ExtensionLoader < Car > extensionLoader =
ExtensionLoader . getExtensionLoader ( Car . class ) ;
Car redCar = extensionLoader. getExtension ( "red" ) ;
redCar. getColor ( ) ;
}
}
首先通过 ExtensionLoader.getExtensionLoader() 获取加载器
public class CarDemo {
public static void main ( String [ ] args) {
ExtensionLoader < Car > extensionLoader =
ExtensionLoader . getExtensionLoader ( Car . class ) ;
. . .
}
}
调用 ExtensionLoader.getExtensionLoader() 时,会先判断接口是有 @SPI 标注,然后通过传入 type(即 Car.class ),通过 EXTENSION_LOADERS 属性缓存获取 ExtensionLoader ,没有则新建一个
public class ExtensionLoader < T > {
private static final ConcurrentMap < Class < ? > , ExtensionLoader < ? > > EXTENSION_LOADERS = new ConcurrentHashMap < Class < ? > , ExtensionLoader < ? > > ( ) ;
. . .
public static < T > ExtensionLoader < T > getExtensionLoader ( Class < T > type) {
if ( type == null ) {
throw new IllegalArgumentException ( "Extension type == null" ) ;
}
if ( ! type. isInterface ( ) ) {
throw new IllegalArgumentException ( "Extension type(" + type + ") is not interface!" ) ;
}
if ( ! withExtensionAnnotation ( type) ) {
throw new IllegalArgumentException ( "Extension type(" + type +
") is not extension, because WITHOUT @" + SPI . class . getSimpleName ( ) + " Annotation!" ) ;
}
ExtensionLoader < T > loader = ( ExtensionLoader < T > ) EXTENSION_LOADERS . get ( type) ;
if ( loader == null ) {
EXTENSION_LOADERS . putIfAbsent ( type, new ExtensionLoader < T > ( type) ) ;
loader = ( ExtensionLoader < T > ) EXTENSION_LOADERS . get ( type) ;
}
return loader;
}
}
因为 ExtensionLoader 的构造是私有的,先把 type 赋值到 type 属性,同事创建一个 objectFactory 工厂,由于第一次创建。所以得通过 ExtensionLoader.getExtensionLoader 创建 ExtensionFactory.class 类,陷入一次循环中,
public class ExtensionLoader < T > {
private final Class < ? > type;
private final ExtensionFactory objectFactory;
. . .
private ExtensionLoader ( Class < ? > type) {
this . type = type;
objectFactory = ( type == ExtensionFactory . class ? null : ExtensionLoader . getExtensionLoader ( ExtensionFactory . class ) . getAdaptiveExtension ( ) ) ;
}
}
再次进入到 getExtensionLoader() 方法,只不过这次创建的是 ExtensionFactory.class
public class ExtensionLoader < T > {
private static final ConcurrentMap < Class < ? > , ExtensionLoader < ? > > EXTENSION_LOADERS = new ConcurrentHashMap < Class < ? > , ExtensionLoader < ? > > ( ) ;
. . .
public static < T > ExtensionLoader < T > getExtensionLoader ( Class < T > type) {
. . .
ExtensionLoader < T > loader = ( ExtensionLoader < T > ) EXTENSION_LOADERS . get ( type) ;
if ( loader == null ) {
EXTENSION_LOADERS . putIfAbsent ( type, new ExtensionLoader < T > ( type) ) ;
loader = ( ExtensionLoader < T > ) EXTENSION_LOADERS . get ( type) ;
}
return loader;
}
}
调用 ExtensionLoader() 方法时,这次的 objectFactory 为空,然后返回 ExtensionFactory 的 ExtensionLoader 对象,同时 EXTENSION_LOADERS 属性包含一个 ExtensionFactory.class 的 key-value 对
public class ExtensionLoader < T > {
private final Class < ? > type;
private final ExtensionFactory objectFactory;
. . .
private ExtensionLoader ( Class < ? > type) {
this . type = type;
objectFactory = ( type == ExtensionFactory . class ? null : ExtensionLoader . getExtensionLoader ( ExtensionFactory . class ) . getAdaptiveExtension ( ) ) ;
}
}
回到 Car.class 的 ExtensionLoader 构建,这次得调用 ExtensionFactory.class 的 ExtensionLoader 执行 getAdaptiveExtension() 方法
public class ExtensionLoader < T > {
private final Class < ? > type;
private final ExtensionFactory objectFactory;
. . .
private ExtensionLoader ( Class < ? > type) {
this . type = type;
objectFactory = ( type == ExtensionFactory . class ? null : ExtensionLoader . getExtensionLoader ( ExtensionFactory . class ) . getAdaptiveExtension ( ) ) ;
}
}
首先判断从 cachedAdaptiveInstance 属性中获取自适应的代理对象,如果没有,则执行 createAdaptiveExtension() 方法来创建
public class ExtensionLoader < T > {
private final Holder < Object > cachedAdaptiveInstance = new Holder < Object > ( ) ;
private volatile Throwable createAdaptiveInstanceError;
. . .
public T getAdaptiveExtension ( ) {
Object instance = cachedAdaptiveInstance. get ( ) ;
if ( instance == null ) {
if ( createAdaptiveInstanceError == null ) {
synchronized ( cachedAdaptiveInstance) {
instance = cachedAdaptiveInstance. get ( ) ;
if ( instance == null ) {
try {
instance = createAdaptiveExtension ( ) ;
cachedAdaptiveInstance. set ( instance) ;
} catch ( Throwable t) {
createAdaptiveInstanceError = t;
throw new IllegalStateException ( "fail to create adaptive instance: " + t. toString ( ) , t) ;
}
}
}
} else {
throw new IllegalStateException ( "fail to create adaptive instance: " + createAdaptiveInstanceError. toString ( ) , createAdaptiveInstanceError) ;
}
}
return ( T ) instance;
}
}
ExtensionFactory.class 的 ExtensionLoader 调用 getAdaptiveExtensionClass() 方法创建代理对象,然后返回
public class ExtensionLoader < T > {
. . .
private T createAdaptiveExtension ( ) {
try {
return injectExtension ( ( T ) getAdaptiveExtensionClass ( ) . newInstance ( ) ) ;
} catch ( Exception e) {
throw new IllegalStateException ( "Can not create adaptive extension " + type + ", cause: " + e. getMessage ( ) , e) ;
}
}
}
getAdaptiveExtensionClass() 方法再调用 getExtensionClasses() 获取自适应代理对象,如果一个实现标注了 @Adaptive 注解就直接返回该 class
public class ExtensionLoader < T > {
. . .
private Class < ? > getAdaptiveExtensionClass ( ) {
getExtensionClasses ( ) ;
if ( cachedAdaptiveClass != null ) {
return cachedAdaptiveClass;
}
return cachedAdaptiveClass = createAdaptiveExtensionClass ( ) ;
}
}
getExtensionClasses() 方法会从 cachedClasses 属性获取实现类,如果没有,就得去文件目录加载,即执行 loadExtensionClasses() 方法,然后存入 cachedClasses 返回
public class ExtensionLoader < T > {
private final Holder < Map < String , Class < ? > > > cachedClasses = new Holder < Map < String , Class < ? > > > ( ) ;
. . .
private Map < String , Class < ? > > getExtensionClasses ( ) {
Map < String , Class < ? > > classes = cachedClasses. get ( ) ;
if ( classes == null ) {
synchronized ( cachedClasses) {
classes = cachedClasses. get ( ) ;
if ( classes == null ) {
classes = loadExtensionClasses ( ) ;
cachedClasses. set ( classes) ;
}
}
}
return classes;
}
}
执行 loadExtensionClasses() 方法时,如果 @SPI 指定了 value,会校验只能有 1 个值,同时先缓存起来,然后通过各个目录去加载与 ExtensionFactory.class 相关联的实现(和我们最初定义 Car.class 实现一样的)
重点
加载的目录只会在这些地方,同时越往后,优先级越高
META-INF/dubbo/ META-INF/dubbo/internal/ META-INF/services/
public class ExtensionLoader < T > {
private String cachedDefaultName;
private final Class < ? > type;
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 ( ) {
final SPI defaultAnnotation = type. getAnnotation ( SPI . class ) ;
if ( defaultAnnotation != null ) {
String value = defaultAnnotation. value ( ) ;
if ( ( value = value. trim ( ) ) . length ( ) > 0 ) {
String [ ] names = NAME_SEPARATOR . split ( value) ;
if ( names. length > 1 ) {
throw new IllegalStateException ( "more than 1 default extension name on extension " + type. getName ( )
+ ": " + Arrays . toString ( names) ) ;
}
if ( names. length == 1 ) {
cachedDefaultName = names[ 0 ] ;
}
}
}
Map < String , Class < ? > > extensionClasses = new HashMap < String , Class < ? > > ( ) ;
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;
}
}
执行 loadDirectory() 时,会先拼接资源定位符 URL,然后加载对应资源文件
public class ExtensionLoader < T > {
. . .
private void loadDirectory ( Map < String , Class < ? > > extensionClasses, String dir, String type) {
String fileName = dir + type;
try {
Enumeration < java. net. URL> urls;
ClassLoader classLoader = findClassLoader ( ) ;
if ( classLoader != null ) {
urls = classLoader. getResources ( fileName) ;
} else {
urls = ClassLoader . getSystemResources ( fileName) ;
}
if ( urls != null ) {
while ( urls. hasMoreElements ( ) ) {
java. net. URL resourceURL = urls. nextElement ( ) ;
loadResource ( extensionClasses, classLoader, resourceURL) ;
}
}
} catch ( Throwable t) {
logger. error ( "Exception when load extension class(interface: " +
type + ", description file: " + fileName + ")." , t) ;
}
}
}
第一次执行 loadResource() 时,主要是获取 org.apache.dubbo.common.extension.ExtensionFactory 文件下的内容,遍历每一行类,进行加载
org.apache.dubbo.common.extension.ExtensionFactory 内容
adaptive=org.apache.dubbo.common.extension.factory.AdaptiveExtensionFactory
spi=org.apache.dubbo.common.extension.factory.SpiExtensionFactory
public class ExtensionLoader < T > {
. . .
private void loadResource ( Map < String , Class < ? > > extensionClasses, ClassLoader classLoader, java. net. URL resourceURL) {
try {
BufferedReader reader = new BufferedReader ( new InputStreamReader ( resourceURL. openStream ( ) , "utf-8" ) ) ;
try {
String line;
while ( ( line = reader. readLine ( ) ) != null ) {
final int ci = line. indexOf ( '#' ) ;
if ( ci >= 0 ) {
line = line. substring ( 0 , ci) ;
}
line = line. trim ( ) ;
if ( line. length ( ) > 0 ) {
try {
String name = null ;
int i = line. indexOf ( '=' ) ;
if ( i > 0 ) {
name = line. substring ( 0 , i) . trim ( ) ;
line = line. substring ( i + 1 ) . trim ( ) ;
}
if ( line. length ( ) > 0 ) {
loadClass ( extensionClasses, resourceURL, Class . forName ( line, true , classLoader) , name) ;
}
} catch ( Throwable t) {
IllegalStateException e = new IllegalStateException ( "Failed to load extension class(interface: " + type + ", class line: " + line + ") in " + resourceURL + ", cause: " + t. getMessage ( ) , t) ;
exceptions. put ( line, e) ;
}
}
}
} finally {
reader. close ( ) ;
}
} catch ( Throwable t) {
logger. error ( "Exception when load extension class(interface: " +
type + ", class file: " + resourceURL + ") in " + resourceURL, t) ;
}
}
}
在加载 org.apache.dubbo.common.extension.ExtensionFactory 第一行内容时,标注的 org.apache.dubbo.common.extension.factory.AdaptiveExtensionFactory 是指定了 @Adaptive ,所以会先存入到 cachedAdaptiveClass 属性。然后再遍历第二行,org.apache.dubbo.common.extension.factory.SpiExtensionFactory 就是个实现类,存到 cachedNames 属性中(其中 key 为 class,value 为 name,这不管标注了多少个 name,都只存一次),同时存入 extensionClasses 中(其中 key 为 name, value 为 class)
重点
在文件中写的类,必须实现了文件名的接口 同一个类,可以指定多个别名 对于每个接口 @Adaptive 只能指定一个实现类
public class ExtensionLoader < T > {
private final Class < ? > type;
private volatile Class < ? > cachedAdaptiveClass = null ;
. . .
private void loadClass ( Map < String , Class < ? > > extensionClasses, java. net. URL resourceURL, Class < ? > clazz, String name) throws NoSuchMethodException {
if ( ! type. isAssignableFrom ( clazz) ) {
throw new IllegalStateException ( "Error when load extension class(interface: " +
type + ", class line: " + clazz. getName ( ) + "), class "
+ clazz. getName ( ) + "is not subtype of interface." ) ;
}
if ( clazz. isAnnotationPresent ( Adaptive . class ) ) {
if ( cachedAdaptiveClass == null ) {
cachedAdaptiveClass = clazz;
} else if ( ! cachedAdaptiveClass. equals ( clazz) ) {
throw new IllegalStateException ( "More than 1 adaptive class found: "
+ cachedAdaptiveClass. getClass ( ) . getName ( )
+ ", " + clazz. getClass ( ) . getName ( ) ) ;
}
} else if ( isWrapperClass ( clazz) ) {
Set < Class < ? > > wrappers = cachedWrapperClasses;
if ( wrappers == null ) {
cachedWrapperClasses = new ConcurrentHashSet < Class < ? > > ( ) ;
wrappers = cachedWrapperClasses;
}
wrappers. add ( clazz) ;
} else {
clazz. getConstructor ( ) ;
if ( StringUtils . isEmpty ( name) ) {
name = findAnnotationName ( clazz) ;
if ( name. length ( ) == 0 ) {
throw new IllegalStateException ( "No such extension name for the class " + clazz. getName ( ) + " in the config " + resourceURL) ;
}
}
String [ ] names = NAME_SEPARATOR . split ( name) ;
if ( names != null && names. length > 0 ) {
Activate activate = clazz. getAnnotation ( Activate . class ) ;
if ( activate != null ) {
cachedActivates. put ( names[ 0 ] , activate) ;
} else {
com. alibaba. dubbo. common. extension. Activate oldActivate = clazz. getAnnotation ( com. alibaba. dubbo. common. extension. Activate. class ) ;
if ( oldActivate != null ) {
cachedActivates. put ( names[ 0 ] , oldActivate) ;
}
}
for ( String n : names) {
if ( ! cachedNames. containsKey ( clazz) ) {
cachedNames. put ( clazz, n) ;
}
Class < ? > c = extensionClasses. get ( n) ;
if ( c == null ) {
extensionClasses. put ( n, clazz) ;
} else if ( c != clazz) {
throw new IllegalStateException ( "Duplicate extension " + type. getName ( ) + " name " + n + " on " + c. getName ( ) + " and " + clazz. getName ( ) ) ;
}
}
}
}
}
}
由于 ExtensionFactory 接口下的 AdaptiveExtensionFactory 实现了 @Adaptive 注解,所以在 Car.class 的 createAdaptiveExtension() 时,返回的是 AdaptiveExtensionFactory 进行实例化,这时候再次获取 ExtensionFactory.class 的 ExtensionLoader ,并把之前存入到 cachedClasses 属性的 org.apache.dubbo.common.extension.factory.SpiExtensionFactory 元素,存入 factories 属性,并返回 AdaptiveExtensionFactory 这个实例
@Adaptive
public class AdaptiveExtensionFactory implements ExtensionFactory {
private final List < ExtensionFactory > factories;
. . .
public AdaptiveExtensionFactory ( ) {
ExtensionLoader < ExtensionFactory > loader = ExtensionLoader . getExtensionLoader ( ExtensionFactory . class ) ;
List < ExtensionFactory > list = new ArrayList < ExtensionFactory > ( ) ;
for ( String name : loader. getSupportedExtensions ( ) ) {
list. add ( loader. getExtension ( name) ) ;
}
factories = Collections . unmodifiableList ( list) ;
}
}
这时候就回到 Car.class 的 ExtensionLoader ,并赋值 objectFactory 为 AdaptiveExtensionFactory
public class ExtensionLoader < T > {
private final Class < ? > type;
private final ExtensionFactory objectFactory;
. . .
private ExtensionLoader ( Class < ? > type) {
this . type = type;
objectFactory = ( type == ExtensionFactory . class ? null : ExtensionLoader . getExtensionLoader ( ExtensionFactory . class ) . getAdaptiveExtension ( ) ) ;
}
}
得到 Car.class 的 ExtensionLoader 之后,执行 getExtension() 获取扩展类
public class CarDemo {
public static void main ( String [ ] args) {
. . .
Car redCar = extensionLoader. getExtension ( "red" ) ;
}
}
执行 getExtension() 时,先判断 cachedInstances 属性是否已经有过创建的实例,没有的话,就执行 createExtension() 方法
重点
当执行 getExtension() 时,可以放入参数为 true,只是获取的是默认扩展类
public class ExtensionLoader < T > {
private final ConcurrentMap < String , Holder < Object > > cachedInstances = new ConcurrentHashMap < String , Holder < Object > > ( ) ;
. . .
public T getExtension ( String name) {
if ( StringUtils . isEmpty ( name) ) {
throw new IllegalArgumentException ( "Extension name == null" ) ;
}
if ( "true" . equals ( name) ) {
return getDefaultExtension ( ) ;
}
Holder < Object > holder = cachedInstances. get ( name) ;
if ( holder == null ) {
cachedInstances. putIfAbsent ( name, new Holder < Object > ( ) ) ;
holder = cachedInstances. get ( name) ;
}
Object instance = holder. get ( ) ;
if ( instance == null ) {
synchronized ( holder) {
instance = holder. get ( ) ;
if ( instance == null ) {
instance = createExtension ( name) ;
holder. set ( instance) ;
}
}
}
return ( T ) instance;
}
}
再次执行 getExtensionClasses() 扫描目录获取所有实现了 Car.class 接口的类,然后找到指定 name=red 的类,并且实例化对象,存入 EXTENSION_INSTANCES 属性中,并返回。最后就可以执行接口的方法了
public class ExtensionLoader < T > {
private static final ConcurrentMap < Class < ? > , Object > EXTENSION_INSTANCES = new ConcurrentHashMap < Class < ? > , Object > ( ) ;
. . .
private T createExtension ( String name) {
Class < ? > clazz = getExtensionClasses ( ) . get ( name) ;
if ( clazz == null ) {
throw findException ( name) ;
}
try {
T instance = ( T ) EXTENSION_INSTANCES . get ( clazz) ;
if ( instance == null ) {
EXTENSION_INSTANCES . putIfAbsent ( clazz, clazz. newInstance ( ) ) ;
instance = ( T ) EXTENSION_INSTANCES . get ( clazz) ;
}
injectExtension ( instance) ;
Set < Class < ? > > wrapperClasses = cachedWrapperClasses;
if ( CollectionUtils . isNotEmpty ( wrapperClasses) ) {
for ( Class < ? > wrapperClass : wrapperClasses) {
instance = injectExtension ( ( T ) wrapperClass. getConstructor ( type) . newInstance ( instance) ) ;
}
}
return instance;
} catch ( Throwable t) {
throw new IllegalStateException ( "Extension instance(name: " + name + ", class: " +
type + ") could not be instantiated: " + t. getMessage ( ) , t) ;
}
}
}
总结