Dubbo原始碼分析:Dubbo自己實現的IOC
阿新 • • 發佈:2018-11-01
在建立自適應例項時,都會呼叫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;
}
}