其实我们在SPI源码阅读的时候,已经阅读过Dubbo中的IOC/APO源码部分了,接下来我们再详细的跟踪一下复习一遍。
IOC
ServiceConfig.java
public synchronized void export() {
// 检测所有的注册中心可用性,并进一步完善<dubbo:service/>的配置
checkAndUpdateSubConfigs();
// 若设置的export为false,则不进行服务暴露,直接结束
if (!shouldExport()) {
return;
}
// 若设置了delay属性,则进行延迟暴露
if (shouldDelay()) {
DELAY_EXPORT_EXECUTOR.schedule(this::doExport, getDelay(), TimeUnit.MILLISECONDS);
} else {
doExport();
}
}
public void checkAndUpdateSubConfigs() {
// 如果用户没有自定义配置,则使用默认的配置信息
completeCompoundConfigs();
// Config Center should always being started first.
startConfigCenter();
checkDefault();
checkProtocol();
checkApplication();
// if protocol is not injvm checkRegistry
// 若不是本地服务暴露,则检测所有注册中心的可用性
if (!isOnlyInJvm()) {
checkRegistry();
}
this.refresh();
checkMetadataReport();
if (StringUtils.isEmpty(interfaceName)) {
throw new IllegalStateException("<dubbo:service interface=\"\" /> interface not allow null!");
}
if (ref instanceof GenericService) {
interfaceClass = GenericService.class;
if (StringUtils.isEmpty(generic)) {
generic = Boolean.TRUE.toString();
}
} else {
try {
interfaceClass = Class.forName(interfaceName, true, Thread.currentThread()
.getContextClassLoader());
} catch (ClassNotFoundException e) {
throw new IllegalStateException(e.getMessage(), e);
}
checkInterfaceAndMethods(interfaceClass, methods);
checkRef();
generic = Boolean.FALSE.toString();
}
if (local != null) {
if ("true".equals(local)) {
local = interfaceName + "Local";
}
Class<?> localClass;
try {
localClass = ClassUtils.forNameWithThreadContextClassLoader(local);
} catch (ClassNotFoundException e) {
throw new IllegalStateException(e.getMessage(), e);
}
if (!interfaceClass.isAssignableFrom(localClass)) {
throw new IllegalStateException("The local implementation class " + localClass.getName() + " not implement interface " + interfaceName);
}
}
if (stub != null) {
if ("true".equals(stub)) {
stub = interfaceName + "Stub";
}
Class<?> stubClass;
try {
stubClass = ClassUtils.forNameWithThreadContextClassLoader(stub);
} catch (ClassNotFoundException e) {
throw new IllegalStateException(e.getMessage(), e);
}
if (!interfaceClass.isAssignableFrom(stubClass)) {
throw new IllegalStateException("The stub implementation class " + stubClass.getName() + " not implement interface " + interfaceName);
}
}
checkStubAndLocal(interfaceClass);
checkMock(interfaceClass);
}
AbstractInterfaceConfig.java
protected void checkRegistry() {
loadRegistriesFromBackwardConfig();
convertRegistryIdsToRegistries();
// 遍历所有注册中心,只要有一个不可用,则直接抛出异常
for (RegistryConfig registryConfig : registries) {
if (!registryConfig.isValid()) {
throw new IllegalStateException("No registry config found or it's not a valid config! " +
"The registry config is: " + registryConfig);
}
}
// 使用注册中心作为配置中心,如果有必要的话(没有定义配置中心)
useRegistryForConfigIfNecessary();
}
private void useRegistryForConfigIfNecessary() {
registries.stream().filter(RegistryConfig::isZookeeperProtocol).findFirst().ifPresent(rc -> {
// we use the loading status of DynamicConfiguration to decide whether ConfigCenter has been initiated.
Environment.getInstance().getDynamicConfiguration().orElseGet(() -> {
ConfigManager configManager = ConfigManager.getInstance();
ConfigCenterConfig cc = configManager.getConfigCenter().orElse(new ConfigCenterConfig());
// 使用注册中心初始化配置中心
cc.setProtocol(rc.getProtocol());
cc.setAddress(rc.getAddress());
cc.setHighestPriority(false);
setConfigCenter(cc);
// 开启配置中心
startConfigCenter();
return null;
});
});
}
void startConfigCenter() {
if (configCenter == null) {
ConfigManager.getInstance().getConfigCenter().ifPresent(cc -> this.configCenter = cc);
}
if (this.configCenter != null) {
// TODO there may have duplicate refresh
this.configCenter.refresh();
// 从配置中心读取动态配置数据,准备运行环境
prepareEnvironment();
}
ConfigManager.getInstance().refreshAll();
}
private void prepareEnvironment() {
if (configCenter.isValid()) {
if (!configCenter.checkOrUpdateInited()) {
return;
}
// 获取动态配置
DynamicConfiguration dynamicConfiguration = getDynamicConfiguration(configCenter.toUrl());
String configContent = dynamicConfiguration.getProperties(configCenter.getConfigFile(), configCenter.getGroup());
String appGroup = application != null ? application.getName() : null;
String appConfigContent = null;
if (StringUtils.isNotEmpty(appGroup)) {
appConfigContent = dynamicConfiguration.getProperties
(StringUtils.isNotEmpty(configCenter.getAppConfigFile()) ? configCenter.getAppConfigFile() : configCenter.getConfigFile(),
appGroup
);
}
try {
Environment.getInstance().setConfigCenterFirst(configCenter.isHighestPriority());
Environment.getInstance().updateExternalConfigurationMap(parseProperties(configContent));
Environment.getInstance().updateAppExternalConfigurationMap(parseProperties(appConfigContent));
} catch (IOException e) {
throw new IllegalStateException("Failed to parse configurations from Config Center.", e);
}
}
}
private DynamicConfiguration getDynamicConfiguration(URL url) {
// 获取动态配置工厂DynamicConfigurationFactory的名称为zookeeper的扩展类实例
DynamicConfigurationFactory factories = ExtensionLoader
.getExtensionLoader(DynamicConfigurationFactory.class)
.getExtension(url.getProtocol()); //
DynamicConfiguration configuration = factories.getDynamicConfiguration(url);
Environment.getInstance().setDynamicConfiguration(configuration);
return configuration;
}
ExtensionLoader.java
// 获取指定名称的扩展类实例
@SuppressWarnings("unchecked")
public T getExtension(String name) {
if (StringUtils.isEmpty(name)) {
throw new IllegalArgumentException("Extension name == null");
}
if ("true".equals(name)) {
return getDefaultExtension();
}
final Holder<Object> holder = getOrCreateHolder(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;
}
private T createExtension(String name) {
// getExtensionClasses() 返回当前SPI接口的所有直接扩展类,是个map
// 其key为扩展名,value为直接扩展类的class
Class<?> clazz = getExtensionClasses().get(name);
if (clazz == null) {
throw findException(name);
}
try {
// 从缓存中获取指定类对应的实例,若为null,则创建一个实例
T instance = (T) EXTENSION_INSTANCES.get(clazz);
if (instance == null) {
EXTENSION_INSTANCES.putIfAbsent(clazz, clazz.newInstance());
instance = (T) EXTENSION_INSTANCES.get(clazz);
}
// 调用instance实例的setter完成注入
injectExtension(instance);
// 获取当前SPI接口类型的所有wrapper类
Set<Class<?>> wrapperClasses = cachedWrapperClasses;
// 遍历所有wrapper,逐层对instance实例进行包装
if (CollectionUtils.isNotEmpty(wrapperClasses)) {
for (Class<?> wrapperClass : wrapperClasses) {
instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
}
}
// 返回的是包装过的instance
return instance;
} catch (Throwable t) {
throw new IllegalStateException("Extension instance (name: " + name + ", class: " +
type + ") couldn't be instantiated: " + t.getMessage(), t);
}
}
private T injectExtension(T instance) {
try {
if (objectFactory != null) {
// 遍历当前instance中的所有方法
for (Method method : instance.getClass().getMethods()) {
// 仅对setter方法进行处理
if (isSetter(method)) {
/**
* Check {@link DisableInject} to see if we need auto injection for this property
*/
// 若一个setter方法上有@DisableInject注解,则不进行注入
if (method.getAnnotation(DisableInject.class) != null) {
continue;
}
// 获取当前setter方法的参数类型
Class<?> pt = method.getParameterTypes()[0];
// 若setter方法的参数类型为基本数据类型,则不进行注入
if (ReflectUtils.isPrimitives(pt)) {
continue;
}
try {
// 获取setter方法的形参名称
String property = getSetterProperty(method);
// 获取要注入的实例,即setter的实参
Object object = objectFactory.getExtension(pt, property);
if (object != null) {
// 调用setter完成注入
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;
}
public <T> T getExtension(Class<T> type, String name) {
// 若当前type为SPI接口
if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
ExtensionLoader<T> loader = ExtensionLoader.getExtensionLoader(type);
// 若当前type的直接扩展类不空,则返回其adaptive实例
if (!loader.getSupportedExtensions().isEmpty()) {
return loader.getAdaptiveExtension();
}
}
return null;
}
ExtensionLoader.java
public <T> T getExtension(Class<T> type, String name) {
// 若当前type为SPI接口
if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
ExtensionLoader<T> loader = ExtensionLoader.getExtensionLoader(type);
// 若当前type的直接扩展类不空,则返回其adaptive实例
if (!loader.getSupportedExtensions().isEmpty()) {
return loader.getAdaptiveExtension();
}
}
return null;
}
public <T> T getExtension(Class<T> type, String name) {
//SPI should be get from SpiExtensionFactory
// 若当前type为SPI接口,则直接结束,因为Spring方式不处理SPI接口实例的创建
if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
return null;
}
// 遍历所有Spring容器,根据名称从中查找实例
for (ApplicationContext context : CONTEXTS) {
if (context.containsBean(name)) {
Object bean = context.getBean(name);
if (type.isInstance(bean)) {
return (T) bean;
}
}
}
logger.warn("No spring extension (bean) named:" + name + ", try to find an extension (bean) of type " + type.getName());
// 这个type不能是Object
if (Object.class == type) {
return null;
}
// 遍历所有Spring容器,根据类型从中查找实例
for (ApplicationContext context : CONTEXTS) {
try {
return context.getBean(type);
} catch (NoUniqueBeanDefinitionException multiBeanExe) {
logger.warn("Find more than 1 spring extensions (beans) of type " + type.getName() + ", will stop auto injection. Please make sure you have specified the concrete parameter type and there's only one extension of that type.");
} catch (NoSuchBeanDefinitionException noBeanExe) {
if (logger.isDebugEnabled()) {
logger.debug("Error when get spring extension(bean) for type:" + type.getName(), noBeanExe);
}
}
}
logger.warn("No spring extension (bean) named:" + name + ", type:" + type.getName() + " found, stop get bean.");
return null;
}
AOP
Dubbo 的 AOP 是对 SPI 扩展类进行增强的方式,而 Wrapper 机制就是对 SPI 扩展类的增强。不同 SPI 的不同 Wrapper,其增强的功能不同。这里引用一下我们之前在学习Dubbo中的四大扩展机制中的Wraper示例。它会生成一个Adaptive扩展类,它的格式是这样的。
package <SPI 接口所在包>;
public class SPI 接口名$Adpative implements SPI 接口 {
public adaptiveMethod (arg0, arg1, ...) {
// 注意,下面的判断仅对 URL 类型,或可以获取到 URL 类型值的参数进行判断
// 例如,dubbo 的 Invoker 类型中就包含有 URL 属性
if(arg1==null)
throw new IllegalArgumentException(异常信息);
if(arg1.getUrl()==null)
throw new IllegalArgumentException(异常信息);
URL url = arg1.getUrl();
// 其会根据@Adaptive 注解上声明的 Key 的顺序,从 URL 获取 Value,
// 作为实际扩展类。若有默认扩展类,则获取默认扩展类名;否则获取
// 指定扩展名名。
String extName = url.get 接口名() == null?默认扩展前辍名:url.get 接口名();
if(extName==null) throw new IllegalStateException(异常信息);
SPI 接口 extension = ExtensionLoader.getExtensionLoader(SPI 接口.class)
.getExtension(extName);
return extension. adaptiveMethod(arg0, arg1, ...);
}
public unAdaptiveMethod( arg0, arg1, ...) {
throw new UnsupportedOperationException(异常信息);
}
}
它会调用getExtensionLoader()创建并执行这个类,然后再去调用被包装的真正的业务方法。从而达到AOP思想的增强。