Dubbo Wrapper 依赖注入机制分析
基于 2.7.0 版本 上一章:『Dubbo SPI源码分析』Wrapper 机制分析
创建测试 demo
package com. luban. dubbo_spi. api ;
@SPI
public interface Car {
public void getColor ( ) ;
public void getColorForUrl ( URL url) ;
}
package com. luban. dubbo_spi. impl ;
public class RedCar implements Car {
public void getColor ( ) {
System . out. println ( "red" ) ;
}
@Override
public void getColorForUrl ( URL url) {
}
}
package com. luban. dubbo_spi. impl ;
@Adaptive
public class AdaptiveCar implements Car {
@Override
public void getColor ( ) {
}
@Override
public void getColorForUrl ( URL url) {
System . out. println ( "123123" ) ;
}
}
然后在 resources 创建一个目录 META-INF.services 目录 并在 META-INF.services 目录中创建文件 com.luban.dubbo_spi.api.Car 一定要与接口同名
red = com.luban.dubbo_spi.impl.RedCar
com.luban.dubbo_spi.impl.AdaptiveCar
package com. luban. dubbo_spi. api ;
@SPI
public interface Driver {
public void getColorForUrl ( URL url) ;
}
package com. luban. dubbo_spi. impl
public class Trucker implements Driver {
private Car car;
public void setCar ( Car car) {
this . car = car;
}
@Override
public void getColorForUrl ( URL url) {
car. getColorForUrl ( url) ;
}
}
并在 META-INF.services 目录中创建文件 com.luban.dubbo_spi.api.Driver 一定要与接口同名
tru = com.luban.dubbo_spi.impl.Trucker
public class CarDemo {
public static void main ( String [ ] args) {
ExtensionLoader < Driver > extensionLoader =
ExtensionLoader . getExtensionLoader ( Driver . class ) ;
Driver driver = extensionLoader. getExtension ( "tru" ) ;
Map < String , String > map = new HashMap < > ( ) ;
map. put ( "car" , "black" ) ;
URL url = new URL ( "" , "" , 1 , map) ;
driver. getColorForUrl ( url) ;
}
}
首先通过 ExtensionLoader.getExtensionLoader() 获取 Driver.class 的加载器,加载器的流程可以参考 『Dubbo SPI源码分析』SPI 机制分析。获取到加载器以后,从加载器中,拿出扩展类
public class CarDemo {
public static void main ( String [ ] args) {
ExtensionLoader < Driver > extensionLoader =
ExtensionLoader . getExtensionLoader ( Driver . class ) ;
Driver driver = extensionLoader. getExtension ( "tru" ) ;
. . .
}
}
由于还没创建实体,所以同时需要执行 createExtension() 方法
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() 扫描目录的配置,获取所有配置的类,然后从中取出标识为 “tru” 的类,其中相关流程在 『Dubbo SPI源码分析』SPI 机制分析 分析过,就不再叙述。获取 com.luban.dubbo_spi.impl.Trucker 类后,执行依赖注入
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) ;
}
}
}
com.luban.dubbo_spi.impl.Trucker 的 ExtensionLoader 包含 AdaptiveExtensionFactory 的对象工厂,所以这次会尝试对创建后的实体判断是否需要执行依赖注入,主要是判断是否有公有的 set() 方法,然后取出属性名称,既 set[Name]() 中这个 Name 就是要注入的属性名称,case 这里是 “car”,然后入参就是代表对应的类,最后调用 AdaptiveExtensionFactory.getExtension() 获取实体类之后注入方法中
重点
依赖注入的类,一定要标注 @Adaptive 与 @SPI 被注入的类,要标注 @SPI ,同时如果要注入依赖的话,需要实现 set[Name]() ,其中 Name 是名称,而入参是实现类
public class ExtensionLoader < T > {
private final ExtensionFactory objectFactory;
. . .
private T injectExtension ( T instance) {
try {
if ( objectFactory != null ) {
for ( Method method : instance. getClass ( ) . getMethods ( ) ) {
if ( method. getName ( ) . startsWith ( "set" )
&& method. getParameterTypes ( ) . length == 1
&& Modifier . isPublic ( method. getModifiers ( ) ) ) {
if ( method. getAnnotation ( DisableInject . class ) != null ) {
continue ;
}
Class < ? > pt = method. getParameterTypes ( ) [ 0 ] ;
if ( ReflectUtils . isPrimitives ( pt) ) {
continue ;
}
try {
String property = method. getName ( ) . length ( ) > 3 ? method. getName ( ) . substring ( 3 , 4 ) . toLowerCase ( ) + method. getName ( ) . substring ( 4 ) : "" ;
Object object = objectFactory. getExtension ( pt, property) ;
if ( object != null ) {
method. invoke ( instance, object) ;
}
} catch ( Exception e) {
logger. error ( "fail to inject via method " + method. getName ( )
+ " of interface " + type. getName ( ) + ": " + e. getMessage ( ) , e) ;
}
}
}
}
} catch ( Exception e) {
logger. error ( e. getMessage ( ) , e) ;
}
return instance;
}
}
AdaptiveExtensionFactory 在执行的 getExtension() 方法时,会遍历所有在配置文件中,实现了 ExtensionFactory.class 接口的类,从而获取其中的实体,这里只有 1 个,就是 SpiExtensionFactory
@Adaptive
public class AdaptiveExtensionFactory implements ExtensionFactory {
private final List < ExtensionFactory > factories;
. . .
@Override
public < T > T getExtension ( Class < T > type, String name) {
for ( ExtensionFactory factory : factories) {
T extension = factory. getExtension ( type, name) ;
if ( extension != null ) {
return extension;
}
}
return null ;
}
}
执行 SpiExtensionFactory 的 getExtension() 方法时,会先判断入参的 type(即 com.luban.dubbo_spi.api.Car )是否为接口,同时标注了 @SPI 注解,如果有,则先获取 com.luban.dubbo_spi.api.Car 的 ExtensionLoader (过程参考 『Dubbo SPI源码分析』SPI 机制分析 ),通过 getSupportedExtensions() 扫描所有配置文件中实现了 com.luban.dubbo_spi.api.Car 接口的类,然后获取 Adaptive 扩展类
public class SpiExtensionFactory implements ExtensionFactory {
@Override
public < T > T getExtension ( Class < T > type, String name) {
if ( type. isInterface ( ) && type. isAnnotationPresent ( SPI . class ) ) {
ExtensionLoader < T > loader = ExtensionLoader . getExtensionLoader ( type) ;
if ( ! loader. getSupportedExtensions ( ) . isEmpty ( ) ) {
return loader. getAdaptiveExtension ( ) ;
}
}
return null ;
}
}
执行 ExtensionLoader 获取 Adaptive 扩展类时,先判断缓存 cachedAdaptiveInstance 是否有一个创建过的实体,如果有就返回,没有则创建
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;
}
}
执行 createAdaptiveExtension() 方法时,先获取 Adaptive 扩展类
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) ;
}
}
}
首先执行一次 getExtensionClasses() 扫描目录获取 com.luban.dubbo_spi.api.Car 的实现类(上面获取过一次,其实已经缓存了),返回缓存的 @Adaptive 扩展类
public class ExtensionLoader < T > {
. . .
private Class < ? > getAdaptiveExtensionClass ( ) {
getExtensionClasses ( ) ;
if ( cachedAdaptiveClass != null ) {
return cachedAdaptiveClass;
}
return cachedAdaptiveClass = createAdaptiveExtensionClass ( ) ;
}
}
获取到 com.luban.dubbo_spi.api.Car 的扩展类并创建实体,然后对该类也执行依赖注入,但是我们的 case 也没在对 com.luban.dubbo_spi.impl.AdaptiveCar 再进行注入,所以就直接返回
public class ExtensionLoader < T > {
. . .
@SuppressWarnings ( "unchecked" )
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) ;
}
}
}
当完成对 com.luban.dubbo_spi.impl.Trucker 注入以后,就可以使用 com.luban.dubbo_spi.impl.AdaptiveCar 这个属性
public class CarDemo {
public static void main ( String [ ] args) {
ExtensionLoader < Driver > extensionLoader =
ExtensionLoader . getExtensionLoader ( Driver . class ) ;
Driver driver = extensionLoader. getExtension ( "tru" ) ;
Map < String , String > map = new HashMap < > ( ) ;
map. put ( "car" , "black" ) ;
URL url = new URL ( "" , "" , 1 , map) ;
driver. getColorForUrl ( url) ;
}
}
总结