更新時間:2022-03-18 12:18:03 來源:動力節點 瀏覽1994次
Dubbo支持多種配置:
XML配置:基于Spring的Schema和XML擴展機制實現
屬性配置:加載ClassPath根目錄下的Dubbo.Properties
API配置:硬編碼方式配置(不推薦)
注意配置:通過注解配置(Dubbo-2.5.7及以上,不推薦)
對于Property的配置方式,可以通過環境變量指定, -d 啟動參數dubbo.properties文件,加載文件的順序為:
-D 啟動參數
環境變量
類路徑根目錄
加載代碼如下:
public static final String DUBBO_PROPERTIES_KEY = "dubbo.properties.file" ;
public static final String DEFAULT_DUBBO_PROPERTIES = "dubbo.properties" ;
私有 靜態 易失性屬性屬性;
公共 靜態屬性 getProperties() {
if (PROPERTIES == null ) {
同步(ConfigUtils.class ) {
if ( PROPERTIES == null ) {
字符串路徑= System.getProperty(Constants.DUBBO_PROPERTIES_KEY);
if (path == null || path.length() == 0 ) {
路徑= System.getenv(Constants.DUBBO_PROPERTIES_KEY);
if (path == null || path.length() == 0 ) {
路徑=常量.DEFAULT_DUBBO_PROPERTIES;
}
}
屬性= ConfigUtils.loadProperties(路徑,假,真);
}
}
}
返回屬性;
}
本文主要分析XML配置的實現原理和源碼,其他方法不再贅述。
文章開頭已經提到XML配置是基于Spring-based Schema和XML擴展來實現的。通過這種機制,我們可以編寫自己的模式,并根據自定義的 SCHEMA 自定義標簽配置 bean。
使用 XML 擴展機制有幾個步驟:
定義架構(編寫 .xsd 文件)
定義 Javabean
編寫 NamespaceHandler 和 BeandefinitionParser 完成 SCHEMA 分析
編寫 Spring.Handlers 和 Spring.Schemas 文件系列解析部分
XML 文件中的應用程序配置
Dubbo-Config 模塊中的 Dubbo 配置相關代碼。
(1)定義模式
Schema的定義體現在.xsd文件中,該文件位于Dubbo-Config-Spring子模塊下:
至于XSD的數據類型,如何定義,不是本文的重點。
(2)定義Javabean
Dubbo-Config-API子模塊定義了JavaBean的所有配置項,JavaBean中JavaBean的屬性,在Dubbo-Config-API子模塊中定義。
(3)SCHEMA分析
Dubbo 服務框架的 SCHEMA 由 DubbonamespaceHandler 和 DubbobeandefinitionParser 實現。
其中,DubboNamespaceHandler擴展了 Spring 的 NamespaceHandler 支持,并通過重寫其 INIT() 方法注冊相應的解析器:
公共 類DubboNamespaceHandler擴展NamespaceHandlerSupport {
靜態{Version.checkDuplicate
(DubboNamespaceHandler.class );
}
公共 無效初始化(){
registerBeanDefinitionParser( "應用程序" , new DubboBeanDefinitionParser(ApplicationConfig.class , true ) );
registerBeanDefinitionParser( "module" , new DubboBeanDefinitionParser(ModuleConfig.class , true ) );
registerBeanDefinitionParser( "注冊表" , new DubboBeanDefinitionParser(RegistryConfig.class , true ) );
registerBeanDefinitionParser( "monitor" , new DubboBeanDefinitionParser(MonitorConfig.class , true ) );
registerBeanDefinitionParser( "provider" , new DubboBeanDefinitionParser(ProviderConfig.class , true ) );
registerBeanDefinitionParser( "consumer" , new DubboBeanDefinitionParser(ConsumerConfig.class , true ) );
registerBeanDefinitionParser( "protocol" , new DubboBeanDefinitionParser(ProtocolConfig.class , true ) );
registerBeanDefinitionParser( "service" , new DubboBeanDefinitionParser(ServiceBean.class , true ) );
registerBeanDefinitionParser( "reference" , new DubboBeanDefinitionParser(ReferenceBean.class , false ) );
registerBeanDefinitionParser( "annotation" , new DubboBeanDefinitionParser(AnnotationBean.class , true ) );
}
}
但是DubboBeanDefinitionParser實現了 Spring 的 beandefinitionParser,通過覆蓋 parse() 方法將標簽解析為對應的 JavaBean:
公共 類DubboBeanDefinitionParser實現BeanDefinitionParser {
public BeanDefinition parse(Element element, ParserContext parserContext) {
return parse(element, parserContext, beanClass, required);
}
@SuppressWarnings( "unchecked" )
private static BeanDefinition parse(Element element,ParserContext parserContext,Class<?> beanClass, boolean required) {
RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClass(beanClass);
beanDefinition.setLazyInit( false );
// ...... 省略
if (ProtocolConfig.class .equals(beanClass)) {
for (String name : parserContext.getRegistry().getBeanDefinitionNames()) {
BeanDefinition 定義= parserContext.getRegistry().getBeanDefinition(name);
PropertyValue 屬性= definition.getPropertyValues().getPropertyValue("protocol" );
如果(屬性!= null ){
對象值= property.getValue();
if (value instanceof ProtocolConfig && id.equals(((ProtocolConfig) value).getName())) {
definition.getPropertyValues().addPropertyValue( "protocol", new RuntimeBeanReference(id));
}
}
}
} else if (ServiceBean.class .equals (beanClass)) {
String className = element.getAttribute("class" );
if (className != null && className.length() > 0 ) {
RootBeanDefinition classDefinition = new RootBeanDefinition();
classDefinition.setBeanClass(ReflectUtils.forName(className));
classDefinition.setLazyInit( false );
parseProperties(element.getChildNodes(), classDefinition);
beanDefinition.getPropertyValues().addPropertyValue( "ref", new BeanDefinitionHolder(classDefinition, id + "Impl" ));
}
} else if (ProviderConfig.class .equals (beanClass)) {
parseNested(element, parserContext, ServiceBean.class , true , "service", "provider" , id, beanDefinition);
} else if (ConsumerConfig.class .equals (beanClass)) {
parseNested(element, parserContext, ReferenceBean.class , false , "reference", "consumer" , id, beanDefinition);
}
// ...... 省略
return beanDefinition;
}
}
(4)系列組件
上面我們已經知道了解析實現類,那么Spring怎么知道DubbonamespaceHandler是解析Dubbo標簽的呢?這是編寫spring.handlers文件的實現。
Spring.handlers 內容如下:
http\: // code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler
然后 Spring的spring.schemas文件得知 Dubbo 標簽的 Schema 為 Dubbo.xsd,并以此驗證 XML 配置文件的格式。
Spring.schemas 文件內容如下:
http\: // code.alibabatech.com/schema/dubbo/dubbo.xsd=META-INF/dubbo.xsd
文件位置如下:
(5)應用配置
通過以上步驟,Dubbo服務框架完成了標簽的功能,用戶可以在 Dubbo.xsd 中的應用程序中配置 XML。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習