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中获?。ㄖ吧傻呐渲肂ean)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);}3)方法1.1,AbstractInterfaceConfig类#startConfigCenter()方法
void startConfigCenter() {if (configCenter == null) {ConfigManager.getInstance().getConfigCenter().ifPresent(cc -> this.configCenter = cc);}// 如果配置了ConfigCenterif (this.configCenter != null) {// 从其他位置获取配置中心的相关属性信息 , 比如配置中心地址// TODO there may have duplicate refreshthis.configCenter.refresh();// 属性更新后,从远程配置中心获取数据(应用配置,全局配置)prepareEnvironment();}// 从配置中心取到配置数据后,刷新所有的XxConfig中的属性ConfigManager.getInstance().refreshAll();}private void prepareEnvironment() {if (configCenter.isValid()) {if (!configCenter.checkOrUpdateInited()) {return;}// 动态配置中心,管理台上的配置中心DynamicConfiguration dynamicConfiguration = getDynamicConfiguration(configCenter.toUrl());// 如果是zookeeper,获取的就是/dubbo/config/dubbo/dubbo.properties节点中的内容String configContent = dynamicConfiguration.getProperties(configCenter.getConfigFile(), configCenter.getGroup());String appGroup = application != null ? application.getName() : null;String appConfigContent = null;if (StringUtils.isNotEmpty(appGroup)) {// 获取的就是/dubbo/config/dubbo-demo-consumer-application/dubbo.properties节点中的内容// 这里有bugappConfigContent = 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(...);}}}
推荐阅读
- 四 SpringBoot - 整合Mybatis,逆向工程,JPA
- 华为手环6怎么样_华为手环6功能详解
- logback.xml详解
- iptables使用详解
- 一篇文章带你掌握主流办公框架——SpringBoot
- RAID5 IO处理之条带读代码详解
- RAID5 IO处理之写请求代码详解
- RAID5 IO处理之重构代码详解
- RAID5 IO处理之replace代码详解
- Spring的同一个服务为什么会加载多次?