Dubbo組態檔流程決議(二)
- 通過AnnotatedBeanDefinitionReader來決議Multiple/Single型別上的EnableDubboConfigBindings的值(是一個@EnableDubboConfigBinding陣列)
- 讀取組態檔中Dubbo的所有配置項,根據@EnableDubboConfigBinding系結注解的prefix前綴,匹配配置項的key, 然后將單個配置項,或者一組配置項轉換成一個個type型別Class的BeanDefinition的Bean, 注入IOC容器;
- 然后每個XxConfig的Bean會生成對應一個DubboConfigBindingBeanPostProcessor的Bean注入IOC容器
DubboConfigBindingBeanPostProcessor后置處理器
DubboConfigBindingBeanPostProcessor是一個BeanPostProcessor, 利用Spring機制的前后置處理機制,所有Bean的生成,都會經過前后置處理;也就是每個BeanPostProcessor都會參與所有Bean的處理加工;
postProcessBeforeInitialization
Bean初始化的前置處理邏輯;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 每個XxConfig對應一個BeanPostProcessor,所以每個DubboConfigBindingBeanPostProcessor只處理對應的beanName
if (this.beanName.equals(beanName) && bean instanceof AbstractConfig) {
AbstractConfig dubboConfig = (AbstractConfig) bean;
// 從properties檔案中獲取值,并設定到dubboConfig物件中
bind(prefix, dubboConfig);
// 設定dubboConfig物件的name屬性,設定為beanName
customize(beanName, dubboConfig);
}
return bean;
}
//涉及到了Spring的DataBinding;
private void bind(String prefix, AbstractConfig dubboConfig) {
dubboConfigBinder.bind(prefix, dubboConfig);
if (log.isInfoEnabled()) {
log.info("The properties of bean [name : " + beanName + "] have been binding by prefix of " +
"configuration properties : " + prefix);
}
}
- Dubbo的每種配置都會生成相關的代表XXXDubboConfig的Bean Definition 和配套的BeanPostProcessor,Bean在經過創建之后, 會經過屬性處理, 然后經過postProcessBeforeInitialization這個階段,
- if (this.beanName.equals(beanName) && bean instanceof AbstractConfig)
- 判斷Bean的型別是是否為AbstractConfig(org.apache.dubbo.config)這個類是Dubbo的配置類,
- 判斷當前種類配置Bean的名稱是否和當前BeanPostProcessor的beanName屬性是否相等,
- 相等則會將Propertis檔案中的配置項的值和配置Bean的屬性進行系結,賦值;
- 執行完@EnableDubboConfig注解的后, 只是往容器中注入了代表各種XXXDubboConfig配置類的BeanDefinition的實體, 這些DubboConfig的屬性復制則是通過BeanPostProcessor來完成;
postProcessAfterInitialization
執行完Bean的初始化后的后置處理邏輯;
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof AbstractConfig) {
// 添加別名,id屬性的值為別名
String id = ((AbstractConfig) bean).getId();
if (beanDefinitionRegistry != null && beanDefinitionRegistry instanceof DefaultListableBeanFactory) {
DefaultListableBeanFactory factory = (DefaultListableBeanFactory) beanDefinitionRegistry;
if (!StringUtils.isBlank(id) && !factory.hasAlias(beanName, id)) {
beanDefinitionRegistry.registerAlias(beanName, id);
}
}
}
return bean;
}
目的: 添加別名
- 判斷Bean是否為AbstractConfig型別,即是否為Dubbo配置Bean;
- 判斷當前實體的beanDefinitionRegistry 容器是否為空;
- 判斷Bean的id是否為空, 以及bean的別名是否已經存在;(id是別名)
- id不為空, 且beanName不為空,則將beanName為Bean的名稱, id為bean的別名保存起來;
- 判斷bean的別名是否已經存在
目的: 判斷別名是否存在;
//1. 獲取別名容器的迭代器;
//2. 判斷容器中是否還有別名項,沒有回傳false
//3. 判斷遍歷的別名值 是否 和 傳入的別名相等, 相等退出回圈;
//4. 在別名相等的情況, 判斷bean的名稱是否和別名相等, 相等則Bean的別名項已經存在
public boolean hasAlias(String name, String alias) {
Iterator var3 = this.aliasMap.entrySet().iterator();
Entry entry;
String registeredName;
do {
if (!var3.hasNext()) {
return false;
}
entry = (Entry)var3.next();
registeredName = (String)entry.getValue();
} while(!registeredName.equals(name));
String registeredAlias = (String)entry.getKey();
return registeredAlias.equals(alias) || this.hasAlias(registeredAlias, alias);
}
afterPropertiesSet()
這個方法是Bean生命周期中的屬性填充后的一個后置屬性設定階段, 而在這個階段中,會創建一個DefaultDubboConfigBinder物件,
- 當某個AbstractConfig型別的Bean,在經過DubboConfigBindingBeanPostProcessor處理時,此時Bean物件中的屬性是沒有值的,會利用DefaultDubboConfigBinder進行賦值,
- 底層就是利用Spring中的DataBinder技術,結合properties檔案對對應的屬性進行賦值
- 前置處理階段中,會呼叫這個系結器系結資料;
對于一個AbstractConfig型別(針對的其實是子類,比如ApplicationConfig、RegistryConfig)的Bean,每個類都有一些屬性,而properties檔案是一個key-value對,所以實際上DataBinder就是將屬性名和properties檔案中的key進行匹配,如果匹配成功,則把value賦值給屬性,
dubbo.application.name=dubbo-demo-provider1-application
dubbo.application.logger=log4
最終Dubbo的ApplicationConfig配置Bean的name屬性值為"dubbo-demo-provider1-application", logger為 “log4”
dubbo.protocols.p1.name=dubbo
dubbo.protocols.p1.port=20880
dubbo.protocols.p1.host=0.0.0.0
dubbo.protocols.p2.name=http
dubbo.protocols.p2.port=20990
dubbo.protocols.p2.host=127.0.0.1
對應的配置類是 ProtocolConfig, 上述配置會生成兩個實體,一個beanName為p1, name為“dubbo”,“port”為20880, host為“0.0.0.0”, multiple為true;(意味會有一個或者多個ProtocolConfig配置Bean);一個beanName為p2, name為“http”,“port”為20990, host為“127.0.0.1”, multiple為true;
組態檔決議流程
- 通過AnnotatedBeanDefinitionReader來決議Multiple/Single型別上的EnableDubboConfigBindings的值(是一個@EnableDubboConfigBinding陣列)
- 讀取組態檔中Dubbo的所有配置項,根據@EnableDubboConfigBinding系結注解的prefix前綴,匹配配置項的key, 然后將單個配置項,或者一組配置項轉換成一個個type型別Class的BeanDefinition的Bean, 注入IOC容器;
- 然后每個XxConfig的Bean會生成對應一個DubboConfigBindingBeanPostProcessor的Bean注入IOC容器
- 通過BeanPostProcessor的前置處理,底層使用DataBinding技術,完成屬性的賦值;
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/437989.html
標籤:其他
