Dubbo2.7详解( 七 )

1)ServiceConfig类#export()方法
public synchronized void export() {//读取配置并补全(最新最全的配置),方法1checkAndUpdateSubConfigs();// 检查服务是否需要导出if (!shouldExport()) {return;}// 检查是否需要延迟发布if (shouldDelay()) {DELAY_EXPORT_EXECUTOR.schedule(this::doExport, getDelay(), TimeUnit.MILLISECONDS);} else {// 导出服务,方法2doExport();}}2)方法1:ServiceConfig类#checkAndUpdateSubConfigs()方法
/** * 1. ServiceConfig中的某些属性如果是空的,那么就从ProviderConfig、ModuleConfig、ApplicationConfig中获取 * 2. 从配置中心获取配置,包括应用配置和全局配置 * 3. 从配置中心获取Provider配置 * 4. 从配置中心获取Protocol配置 * 5. 如果ApplicationConfig为空,则构造一个ApplicationConfig * 6. 从配置中心获取Registry配置 * 7. 更新ServiceConfig中的属性为优先级最高的配置 * 8. 更新MetadataReportConfig中的属性为优先级最高的配置 * 9. 检查当前服务是不是一个泛化服务 * 10.检查Stub和Local * 11.检查Mock */public void checkAndUpdateSubConfigs() {// ServiceConfig中的某些属性如果是空的,那么就从ProviderConfig、ModuleConfig、ApplicationConfig中获取(之前生成的配置Bean)completeCompoundConfigs();// 方法1.1// 从配置中心获取配置,包括应用配置和全局配置// 把获取到的配置放入到Environment中的externalConfigurationMap和appExternalConfigurationMap中// 并刷新所有的Config属性startConfigCenter();// 如果没有ProviderConfig对象,则创建一个checkDefault();// 如果没有单独的配置protocols,那么就从provider获取配置的协议,添加到的ServiceConfig中去// 假如程序员在配置文件中配了一个dubbo协议,配置中心的全局配置或应用配置中也配置了一个协议,那么就会被添加到ServiceConfig中checkProtocol();checkApplication();// if protocol is not injvm checkRegistry// 如果protocol不是只有injvm协议,表示服务调用不是只在本机jvm里面调用,那就需要用到注册中心// 如果protocol是injvm,表示本地调用if (!isOnlyInJvm()) {checkRegistry();}// 刷新ServiceConfig,方法1.2this.refresh();// 如果配了metadataReportConfig,那么就刷新配置checkMetadataReport();if (StringUtils.isEmpty(interfaceName)) {throw new IllegalStateException("<dubbo:service interface=\"\" /> interface not allow null!");}// 当前服务对应的实现类是一个GenericService,表示没有特定的接口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);}// 刷新MethodConfig,并判断MethodConfig中对应的方法在接口中是否存在checkInterfaceAndMethods(interfaceClass, methods);// 实现类是不是该接口类型checkRef();generic = Boolean.FALSE.toString();}// local和stub一样,不建议使用了if (local != null) {// 如果本地存根为true,则存根类为interfaceName + "Local"if (Boolean.TRUE.toString().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) {// 如果本地存根为true,则存根类为interfaceName + "Stub"if (Boolean.TRUE.toString().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);}}// 检查local和stubcheckStubAndLocal(interfaceClass);// 检查mockcheckMock(interfaceClass);}

经验总结扩展阅读