Dubbo spi
- ExtensionLoader
获取到对应的加载器
public staticExtensionLoader getExtensionLoader(Class type) { if (type == null) { throw new IllegalArgumentException("Extension type == null"); } if (!type.isInterface()) { throw new IllegalArgumentException("Extension type (" + type + ") is not an interface!"); } if (!withExtensionAnnotation(type)) { throw new IllegalArgumentException("Extension type (" + type + ") is not an extension, because it is NOT annotated with @" + SPI.class.getSimpleName() + "!"); } ExtensionLoader loader = (ExtensionLoader ) EXTENSION_LOADERS.get(type); if (loader == null) { EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader (type)); loader = (ExtensionLoader ) EXTENSION_LOADERS.get(type); } return loader; }
org.apache.dubbo.common.extension.ExtensionLoader#getExtension(java.lang.String, boolean)
public T getExtension(String name, boolean wrap) {
if (StringUtils.isEmpty(name)) {
throw new IllegalArgumentException("Extension name == null");
}
if ("true".equals(name)) {
return getDefaultExtension();
}
final Holder
org.apache.dubbo.common.extension.ExtensionLoader#createExtension
这个比较重要,核心逻辑
private T createExtension(String name, boolean wrap) {
Class> clazz = getExtensionClasses().get(name);
if (clazz == null || unacceptableExceptions.contains(name)) {
throw findException(name);
}
try {
T instance = (T) EXTENSION_INSTANCES.get(clazz);
if (instance == null) {
EXTENSION_INSTANCES.putIfAbsent(clazz, clazz.getDeclaredConstructor().newInstance());
instance = (T) EXTENSION_INSTANCES.get(clazz);
}
// 这个地方注入依赖
injectExtension(instance);
//默认true
if (wrap) {
List> wrapperClassesList = new ArrayList<>();
if (cachedWrapperClasses != null) {
wrapperClassesList.addAll(cachedWrapperClasses);
wrapperClassesList.sort(WrapperComparator.COMPARATOR);
Collections.reverse(wrapperClassesList);
}
if (CollectionUtils.isNotEmpty(wrapperClassesList)) {
for (Class> wrapperClass : wrapperClassesList) {
Wrapper wrapper = wrapperClass.getAnnotation(Wrapper.class);
if (wrapper == null
|| (ArrayUtils.contains(wrapper.matches(), name) && !ArrayUtils.contains(wrapper.mismatches(), name))) {
//反射的方式创建对象
//自动包装,类似于aop
instance = injectExtension((T)
wrapperClass.getConstructor(type).newInstance(instance));
}
}
}
}
initExtension(instance);
return instance;
} catch (Throwable t) {
throw new IllegalStateException("Extension instance (name: " + name + ", class: " +
type + ") couldn't be instantiated: " + t.getMessage(), t);
}
}
org.apache.dubbo.common.extension.ExtensionLoader#injectExtension
这个就是怎么注入的
private T injectExtension(T instance) {
if (objectFactory == null) {
return instance;
}
try {
//获取对应的set方法
for (Method method : instance.getClass().getMethods()) {
if (!isSetter(method)) {
continue;
}
if (method.getAnnotation(DisableInject.class) != null) {
continue;
}
Class> pt = method.getParameterTypes()[0];
if (ReflectUtils.isPrimitives(pt)) {
continue;
}
try {
String property = getSetterProperty(method);
// 从这个objectFactoy拿对象,这非常重要
Object object = objectFactory.getExtension(pt, property);
if (object != null) {
//反射初始化
method.invoke(instance, object);
}
} catch (Exception e) {
logger.error("Failed to inject via method " + method.getName()
+ " of interface " + type.getName() + ": " + e.getMessage(), e);
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return instance;
}
来我们继续,看这个
@SPI
public interface ExtensionFactory {
T getExtension(Class type, String name);
}
publicT getExtension(Class type, String name) { for (ExtensionFactory factory : factories) { //调用这个方法,debug发现这个有两个的实现 //一个是SpiExtensionFactory 对于SpiExtensionFactory就是根据传入Class获取自适应拓展类 // SpringExtensionFactory 获取对应的Spring Bean //所以dubbo这个注入即可以注入Spi,又可以注入Spring Bean T extension = factory.getExtension(type, name); if (extension != null) { return extension; } } return null; }



