更新時(shí)間:2022-03-18 12:18:03 來源:動(dòng)力節(jié)點(diǎn) 瀏覽2235次
Dubbo支持多種配置:
XML配置:基于Spring的Schema和XML擴(kuò)展機(jī)制實(shí)現(xiàn)
屬性配置:加載ClassPath根目錄下的Dubbo.Properties
API配置:硬編碼方式配置(不推薦)
注意配置:通過注解配置(Dubbo-2.5.7及以上,不推薦)
對(duì)于Property的配置方式,可以通過環(huán)境變量指定, -d 啟動(dòng)參數(shù)dubbo.properties文件,加載文件的順序?yàn)椋?/p>
-D 啟動(dòng)參數(shù)
環(huán)境變量
類路徑根目錄
加載代碼如下:
public static final String DUBBO_PROPERTIES_KEY = "dubbo.properties.file" ;
public static final String DEFAULT_DUBBO_PROPERTIES = "dubbo.properties" ;
私有 靜態(tài) 易失性屬性屬性;
公共 靜態(tài)屬性 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配置的實(shí)現(xiàn)原理和源碼,其他方法不再贅述。
文章開頭已經(jīng)提到XML配置是基于Spring-based Schema和XML擴(kuò)展來實(shí)現(xiàn)的。通過這種機(jī)制,我們可以編寫自己的模式,并根據(jù)自定義的 SCHEMA 自定義標(biāo)簽配置 bean。
使用 XML 擴(kuò)展機(jī)制有幾個(gè)步驟:
定義架構(gòu)(編寫 .xsd 文件)
定義 Javabean
編寫 NamespaceHandler 和 BeandefinitionParser 完成 SCHEMA 分析
編寫 Spring.Handlers 和 Spring.Schemas 文件系列解析部分
XML 文件中的應(yīng)用程序配置
Dubbo-Config 模塊中的 Dubbo 配置相關(guān)代碼。
(1)定義模式
Schema的定義體現(xiàn)在.xsd文件中,該文件位于Dubbo-Config-Spring子模塊下:
至于XSD的數(shù)據(jù)類型,如何定義,不是本文的重點(diǎn)。
(2)定義Javabean
Dubbo-Config-API子模塊定義了JavaBean的所有配置項(xiàng),JavaBean中JavaBean的屬性,在Dubbo-Config-API子模塊中定義。
(3)SCHEMA分析
Dubbo 服務(wù)框架的 SCHEMA 由 DubbonamespaceHandler 和 DubbobeandefinitionParser 實(shí)現(xiàn)。
其中,DubboNamespaceHandler擴(kuò)展了 Spring 的 NamespaceHandler 支持,并通過重寫其 INIT() 方法注冊(cè)相應(yīng)的解析器:
公共 類DubboNamespaceHandler擴(kuò)展NamespaceHandlerSupport {
靜態(tài){Version.checkDuplicate
(DubboNamespaceHandler.class );
}
公共 無效初始化(){
registerBeanDefinitionParser( "應(yīng)用程序" , new DubboBeanDefinitionParser(ApplicationConfig.class , true ) );
registerBeanDefinitionParser( "module" , new DubboBeanDefinitionParser(ModuleConfig.class , true ) );
registerBeanDefinitionParser( "注冊(cè)表" , 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實(shí)現(xiàn)了 Spring 的 beandefinitionParser,通過覆蓋 parse() 方法將標(biāo)簽解析為對(duì)應(yīng)的 JavaBean:
公共 類DubboBeanDefinitionParser實(shí)現(xiàn)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 ){
對(duì)象值= 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)系列組件
上面我們已經(jīng)知道了解析實(shí)現(xiàn)類,那么Spring怎么知道DubbonamespaceHandler是解析Dubbo標(biāo)簽的呢?這是編寫spring.handlers文件的實(shí)現(xiàn)。
Spring.handlers 內(nèi)容如下:
http\: // code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler
然后 Spring的spring.schemas文件得知 Dubbo 標(biāo)簽的 Schema 為 Dubbo.xsd,并以此驗(yàn)證 XML 配置文件的格式。
Spring.schemas 文件內(nèi)容如下:
http\: // code.alibabatech.com/schema/dubbo/dubbo.xsd=META-INF/dubbo.xsd
文件位置如下:
(5)應(yīng)用配置
通過以上步驟,Dubbo服務(wù)框架完成了標(biāo)簽的功能,用戶可以在 Dubbo.xsd 中的應(yīng)用程序中配置 XML。
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問老師會(huì)電話與您溝通安排學(xué)習(xí)