dubbo系列之ServiceBean介紹(六)
前言
前面幾篇文章中,我們瞭解了spring是如何解析@Service,@Reference註解的,今天主要講的是服務暴露者的一個非常重要的類,ServiceBean
, 每個暴露出去的服務都會生成一個ServiceBean.
ServiceBean
該類的繼承實現關係如下
public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener<ContextRefreshedEvent> , BeanNameAware {
// 程式碼省略
}
繼承了ServiceConfig, 這個類特別重要,後面會重點講,因為服務暴露,SPI機制,都跟這個類有關係
InitializingBean , 主要是用到了他的afterPropertiesSet方法,在物件例項化完畢後,呼叫該方法,做一些值的初始化
DisposableBean , 主要用到他的destroy() 方法, 在spring容器showdown的時候呼叫。
ApplicationContextAware, 為了得到applicationContext
ApplicationListener , 添加了上下文重新整理監聽,用於暴露服務使用。
BeanNameAware , 用於設定Bean的名稱
setApplicationContext
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
//將applicationContext設定到SpringExtensionFactory中,用於後續從SpringExtensionFactory中獲取Bean
//SpringExtensionFactory是dubbo自定義的一個類
SpringExtensionFactory.addApplicationContext(applicationContext);
if (applicationContext != null) {
SPRING_CONTEXT = applicationContext;
try {
Method method = applicationContext.getClass().getMethod("addApplicationListener", new Class<?>[]{ApplicationListener.class}); //相容Spring2.0.1
//獲取方法addApplicationListener(ApplicationListener<?> listener),
// 之後將當前類(因為當前類監聽了ContextRefreshedEvent事件)加入spring的監聽器列表
method.invoke(applicationContext, new Object[]{this});
supportedApplicationListener = true;
} catch (Throwable t) {
if (applicationContext instanceof AbstractApplicationContext) {
try {
Method method = AbstractApplicationContext.class.getDeclaredMethod("addListener", new Class<?>[]{ApplicationListener.class}); // 相容Spring2.0.1
if (!method.isAccessible()) {
method.setAccessible(true);
}
method.invoke(applicationContext, new Object[]{this});
supportedApplicationListener = true;
} catch (Throwable t2) {
}
}
}
}
}
SpringExtensionFactory的作用在於dubbo的SPI機制中的依賴注入,當有擴充套件類需要注入其他bean的時候,可能會從SpringExtensionFactory這個類中通過applicationContext獲取Bean物件。
onApplicationEvent
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
// 服務沒有延遲載入 && 服務沒有釋出 && 服務沒有下線過 。 滿足這三個條件,則進行服務暴露
if (isDelay() && !isExported() && !isUnexported()) {
if (logger.isInfoEnabled()) {
logger.info("The service ready on spring started. service: " + getInterface());
}
// 暴露服務介面
export();
}
}
private boolean isDelay() {
// 獲取延遲載入的設定 , 延遲註冊服務時間(毫秒)- ,設為-1時,表示延遲到Spring容器初始化完成時暴露服務
Integer delay = getDelay();
ProviderConfig provider = getProvider();
if (delay == null && provider != null) {
delay = provider.getDelay();
}
// 加了上下文重新整理監聽,並且沒有設定延遲載入,
return supportedApplicationListener && (delay == null || delay == -1);
}
上面的export方法比較重要,用作於服務暴露, 後面會單獨開一篇講。
afterPropertiesSet
dubbo在Spring例項化bean(initializeBean)的時候會對實現了InitializingBean的類進行回撥,回撥方法就是此方法
@Override
@SuppressWarnings({"unchecked", "deprecation"})
public void afterPropertiesSet() throws Exception {
//
if (getProvider() == null) {
Map<String, ProviderConfig> providerConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProviderConfig.class, false, false);
if (providerConfigMap != null && providerConfigMap.size() > 0) {
Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class, false, false);
if ((protocolConfigMap == null || protocolConfigMap.size() == 0)
&& providerConfigMap.size() > 1) { // backward compatibility
List<ProviderConfig> providerConfigs = new ArrayList<ProviderConfig>();
for (ProviderConfig config : providerConfigMap.values()) {
if (config.isDefault() != null && config.isDefault().booleanValue()) {
providerConfigs.add(config);
}
}
if (!providerConfigs.isEmpty()) {
setProviders(providerConfigs);
}
} else {
ProviderConfig providerConfig = null;
for (ProviderConfig config : providerConfigMap.values()) {
if (config.isDefault() == null || config.isDefault().booleanValue()) {
if (providerConfig != null) {
throw new IllegalStateException("Duplicate provider configs: " + providerConfig + " and " + config);
}
providerConfig = config;
}
}
if (providerConfig != null) {
setProvider(providerConfig);
}
}
}
}
//如果當前ServiceBan的application為空,則為該Service設定application
if (getApplication() == null
&& (getProvider() == null || getProvider().getApplication() == null)) {
Map<String, ApplicationConfig> applicationConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ApplicationConfig.class, false, false);
if (applicationConfigMap != null && applicationConfigMap.size() > 0) {
ApplicationConfig applicationConfig = null;
for (ApplicationConfig config : applicationConfigMap.values()) {
if (config.isDefault() == null || config.isDefault().booleanValue()) {
if (applicationConfig != null) {
throw new IllegalStateException("Duplicate application configs: " + applicationConfig + " and " + config);
}
applicationConfig = config;
}
}
if (applicationConfig != null) {
setApplication(applicationConfig);
}
}
}
//如果當前ServiceBan的module為空,則為該Service設定module
if (getModule() == null
&& (getProvider() == null || getProvider().getModule() == null)) {
Map<String, ModuleConfig> moduleConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ModuleConfig.class, false, false);
if (moduleConfigMap != null && moduleConfigMap.size() > 0) {
ModuleConfig moduleConfig = null;
for (ModuleConfig config : moduleConfigMap.values()) {
if (config.isDefault() == null || config.isDefault().booleanValue()) {
if (moduleConfig != null) {
throw new IllegalStateException("Duplicate module configs: " + moduleConfig + " and " + config);
}
moduleConfig = config;
}
}
if (moduleConfig != null) {
setModule(moduleConfig);
}
}
}
//如果當前ServiceBan的Registries為空,則為該Service設定Registries
if ((getRegistries() == null || getRegistries().isEmpty())
&& (getProvider() == null || getProvider().getRegistries() == null || getProvider().getRegistries().isEmpty())
&& (getApplication() == null || getApplication().getRegistries() == null || getApplication().getRegistries().isEmpty())) {
Map<String, RegistryConfig> registryConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RegistryConfig.class, false, false);
if (registryConfigMap != null && registryConfigMap.size() > 0) {
List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>();
for (RegistryConfig config : registryConfigMap.values()) {
if (config.isDefault() == null || config.isDefault().booleanValue()) {
registryConfigs.add(config);
}
}
if (registryConfigs != null && !registryConfigs.isEmpty()) {
super.setRegistries(registryConfigs);
}
}
}
//如果當前ServiceBan的Monitor為空,則為該Service設定Monitor
if (getMonitor() == null
&& (getProvider() == null || getProvider().getMonitor() == null)
&& (getApplication() == null || getApplication().getMonitor() == null)) {
Map<String, MonitorConfig> monitorConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, MonitorConfig.class, false, false);
if (monitorConfigMap != null && monitorConfigMap.size() > 0) {
MonitorConfig monitorConfig = null;
for (MonitorConfig config : monitorConfigMap.values()) {
if (config.isDefault() == null || config.isDefault().booleanValue()) {
if (monitorConfig != null) {
throw new IllegalStateException("Duplicate monitor configs: " + monitorConfig + " and " + config);
}
monitorConfig = config;
}
}
if (monitorConfig != null) {
setMonitor(monitorConfig);
}
}
}
//如果當前ServiceBan的Protocol為空,則為該Service設定Protocol
if ((getProtocols() == null || getProtocols().isEmpty())
&& (getProvider() == null || getProvider().getProtocols() == null || getProvider().getProtocols().isEmpty())) {
Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class, false, false);
if (protocolConfigMap != null && protocolConfigMap.size() > 0) {
List<ProtocolConfig> protocolConfigs = new ArrayList<ProtocolConfig>();
for (ProtocolConfig config : protocolConfigMap.values()) {
if (config.isDefault() == null || config.isDefault().booleanValue()) {
protocolConfigs.add(config);
}
}
if (protocolConfigs != null && !protocolConfigs.isEmpty()) {
super.setProtocols(protocolConfigs);
}
}
}
// 設定服務名稱
if (getPath() == null || getPath().length() == 0) {
if (beanName != null && beanName.length() > 0
&& getInterface() != null && getInterface().length() > 0
&& beanName.startsWith(getInterface())) {
setPath(beanName);
}
}
if (!isDelay()) {
export();
}
}
檢查ServiceBean的某個屬性(這裡的屬性包含如下6個)是否為空,如果為空,從applicationContext獲取相應型別的bean,如果獲取到了,則進行相應的設定。
- ProviderConfig provider:有沒有配置dubbo:provider
- ApplicationConfig application:有沒有配置dubbo:application
- ModuleConfig module:有沒有配置dubbo:module
- MonitorConfig monitor:有沒有配置dubbo:monitor
- String path:服務名稱
以上就是Service即將暴露之前做的準備。