在创建自适应实例时,都会调用ExtensionLoader的injectExtension方法:
@SuppressWarnings("unchecked")
private T createAdaptiveExtension() {
try {
/**
* 传入自适应实例注入到ExtensionLoader
*/
return injectExtension((T) getAdaptiveExtensionClass().newInstance());
} catch (Exception e) {
throw new IllegalStateException("Can not create adaptive extension " + type + ", cause: " + e.getMessage(), e);
}
}
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())) {
Class<?> pt = method.getParameterTypes()[0];
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;
}
dubbo中的IOC实例是通过ExtensionFactory实现的,其实就是检测扩展实现类有没有通过set方法设置的属性,如果有,就通过ExtensionFactory加载而设置。
ExtensionFactory的类实现体系:
在构造ExtensionLoader对象时,有个对象extensionFactory是必须要创建的,可以看到它就是用自适应实例,而ExtensionFatocry的自适应实例便是AdaptiveExtensionFactory,通过下面它的源码,我们可以发现,它维护了其他非自适应扩展实例,其实也就两个SpiExtensionFactory和SpringExtensionFactory。尝试用这两个实例去加载,加载到便返回。
@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);
}
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;
}
}
ExtensionFatocry 可以理解为对象工厂,只不过这里的对应就是Dubbo中的扩展Extension,AdaptiveExtensionFactory可以理解为通用扩展实现获取的入口,至于具体的获取方式分为两种,如果一种是通过Dubbo 自己的SPI方式加载到的扩展,同时还支持复用Srping 的方式,可以看看这两种实现的代码便可知:
public class SpiExtensionFactory implements ExtensionFactory {
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().size() > 0) {
return loader.getAdaptiveExtension();
}
}
return null;
}
}
public class SpringExtensionFactory implements ExtensionFactory {
private static final Set<ApplicationContext> contexts = new ConcurrentHashSet<ApplicationContext>();
public static void addApplicationContext(ApplicationContext context) {
contexts.add(context);
}
public static void removeApplicationContext(ApplicationContext context) {
contexts.remove(context);
}
@SuppressWarnings("unchecked")
public <T> T getExtension(Class<T> type, String name) {
for (ApplicationContext context : contexts) {
if (context.containsBean(name)) {
Object bean = context.getBean(name);
if (type.isInstance(bean)) {
return (T) bean;
}
}
}
return null;
}
}