扩展类,有3种类型
1、类含有 @Adaptive 注解,那么这个类是 cachedAdaptiveClass
2、类是包装类(含有构造函数&构造函数参数只有一个&参数类型是目标类,如Protocol),那么这个类是 cachedWrapperClasses
3、普通扩展类型
org.apache.dubbo.common.extension.ExtensionLoader#getExtensionLoader
1、一种扩展类型,有且只能有一个类含有 @Adaptive 注解
private void cacheAdaptiveClass(Class<?> clazz) {
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());
}
}
2、一种扩展类型,可以有多个类含有Wrapper类
private void cacheWrapperClass(Class<?> clazz) {
if (cachedWrapperClasses == null) {
cachedWrapperClasses = new ConcurrentHashSet<>();
}
cachedWrapperClasses.add(clazz);
}
3、加载扩展类的过程
private void loadClass(Map<String, Class<?>> extensionClasses, java.net.URL resourceURL, Class<?> clazz, String name) throws NoSuchMethodException {
/*
resourceURL 为所在的配置文件
如:line == "hessian=org.apache.dubbo.rpc.protocol.hessian.HessianProtocol"
name="hessian"
clazz="org.apache.dubbo.rpc.protocol.hessian.HessianProtocol"
如:line == "http=org.apache.dubbo.rpc.protocol.http.HttpProtocol"
name="http"
clazz="org.apache.dubbo.rpc.protocol.http.HttpProtocol"
*/
if (!type.isAssignableFrom(clazz)) {
throw new IllegalStateException("Error occurred when loading extension class (interface: " +
type + ", class line: " + clazz.getName() + "), class "
+ clazz.getName() + " is not subtype of interface.");
}
/*
1、类含有 @Adaptive 注解,那么这个类是 cachedAdaptiveClass
2、类是包装类(含有构造函数&构造函数参数只有一个&参数类型是目标类,如Protocol),那么这个类是 cachedWrapperClasses
3、是扩展类
*/
if (clazz.isAnnotationPresent(Adaptive.class)) { // 适配过的类
cacheAdaptiveClass(clazz);
} else if (isWrapperClass(clazz)) { // 被包装过的类
cacheWrapperClass(clazz);
} else {
clazz.getConstructor();
if (StringUtils.isEmpty(name)) {
/*
1、通过@Extension注解获取名称
2、使用类的短名,去除后缀
*/
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 (ArrayUtils.isNotEmpty(names)) {
cacheActivateClass(clazz, names[0]); // 获取类上的 @Activate 注解
for (String n : names) {
cacheName(clazz, n);
/*
类放入 extensionClasses
extensionClasses = {
"hessian" : "org.apache.dubbo.rpc.protocol.hessian.HessianProtocol"
"http" : "org.apache.dubbo.rpc.protocol.http.HttpProtocol"
}
*/
saveInExtensionClass(extensionClasses, clazz, n);
}
}
}
}
4、创建扩展的过程
private T createExtension(String name) {
/*
extensionClasses = {
"hessian" : "org.apache.dubbo.rpc.protocol.hessian.HessianProtocol"
"http" : "org.apache.dubbo.rpc.protocol.http.HttpProtocol"
}
clazz === "org.apache.dubbo.rpc.protocol.hessian.HessianProtocol"
clazz === "org.apache.dubbo.rpc.protocol.http.HttpProtocol"
*/
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);
}
/*
通过setter注入属性到扩展
*/
injectExtension(instance);
/*
获取包装类(含有构造函数&构造函数参数只有一个&参数类型是目标类,如Protocol),对扩展进行包装
*/
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 + ") couldn't be instantiated: " + t.getMessage(), t);
}
}