相关阅读
简介
Dubbo中使用的ApplicationListener如下:
DubboConfigApplicationListener,实现了ApplicationListener<DubboConfigInitEvent>;DubboDeployApplicationListener,实现了ApplicationListener<ApplicationContextEvent>;AwaitingNonWebApplicationListener,实现了SmartApplicationListener;DubboConfigBeanDefinitionConflictApplicationListener,实现了ApplicationListener<ContextRefreshedEvent>;
引入时机
RootBeanDefinition注册时机
DubboConfigApplicationListener和DubboDeployApplicationListener的RootBeanDefinition注册时机在DubboBeanUtils.registerCommonBeans方法中,调用流程如下:
DubboAutoConfiguration ->由EnableDubboConfig引入DubboConfigConfigurationRegistrar ->DubboConfigConfigurationRegistrar.registerBeanDefinitions ->DubboSpringInitializer.initialize ->DubboSpringInitializer.initContext ->DubboBeanUtils.registerCommonBeans;
DubboAutoConfiguration会被ConfigurationClassPostProcessor处理,解析其相关的RootBeanDefinition,调用流程如下:
AbstractApplicationContext.refresh ->invokeBeanFactoryPostProcessors ->PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors ->- … ->
ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry ->ConfigurationClassPostProcessor.processConfigBeanDefinitions ->ConfigurationClassBeanDefinitionReader.loadBeanDefinitions;
ConfigurationClassBeanDefinitionReader.loadBeanDefinitions方法中会执行DubboAutoConfiguration.importBeanDefinitionRegistrars的registerBeanDefinitions来注册RootBeanDefinition; DubboAutoConfiguration.importBeanDefinitionRegistrars如下:
EnableConfigurationPropertiesRegistrar,由EnableConfigurationProperties引入;DubboConfigConfigurationRegistrar,由EnableDubboConfig引入;
AwaitingNonWebApplicationListener和DubboConfigBeanDefinitionConflictApplicationListener是在DubboListenerAutoConfiguration中以BeanMethod形式定义,同DubboAutoConfiguration一样,DubboListenerAutoConfiguration也会被ConfigurationClassPostProcessor处理,最终由ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod方法将DubboListenerAutoConfiguration中所有的BeanMethod注册为RootBeanDefinition;
Bean实例化时机
DubboConfigApplicationListener
DubboConfigApplicationListener实现了ApplicationListener<DubboConfigInitEvent>,其关心的事件为DubboConfigInitEvent;DubboConfigApplicationListener是在DubboConfigInitEvent事件处理过程中被实例化,DubboConfigInitEvent事件是在ReferenceAnnotationBeanPostProcessor.postProcessBeanFactory中发布,所以DubboConfigApplicationListener的实例化主要涉及三个流程:
- 引入
ReferenceAnnotationBeanPostProcessor; - 发布
DubboConfigInitEvent; - 处理
DubboConfigInitEvent;
引入ReferenceAnnotationBeanPostProcessor
在PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法中,会执行容器中所有BeanFactoryPostProcessor的处理,执行顺序大致如下:
- 实现了
PriorityOrdered的BeanDefinitionRegistryPostProcessor; - 实现了
Ordered的BeanDefinitionRegistryPostProcessor; - 剩下的
BeanDefinitionRegistryPostProcessor; - 实现了
PriorityOrdered的BeanFactoryPostProcessor; - 实现了
Ordered的BeanFactoryPostProcessor; - 剩下的
BeanFactoryPostProcessor;
注意:BeanFactoryPostProcessor的获取途径有两种:代码直接添加和配置(代码配置或者文件配置),这里分析的执行顺序没有考虑这两种途径的区别;
ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor和PriorityOrdered,所以它会先执行其postProcessBeanDefinitionRegistry逻辑,从而引入了DubboAutoConfiguration自动配置类,由上文可知,DubboAutoConfiguration自动配置会调用到DubboBeanUtils.registerCommonBeans,该方法内会注册ReferenceAnnotationBeanPostProcessor的RootBeanDefinition; ReferenceAnnotationBeanPostProcessor实现了BeanFactoryPostProcessor和Ordered,故在第五步时,会引入ReferenceAnnotationBeanPostProcessor并执行其postProcessBeanFactory方法;
发布DubboConfigInitEvent
ReferenceAnnotationBeanPostProcessor.postProcessBeanFactory方法中会发布DubboConfigInitEvent事件,代码如下:
applicationContext.publishEvent(new DubboConfigInitEvent(applicationContext));
此时,AbstractApplicationContext中还不存在ApplicationEventMulticaster,所以还无法真正发布事件,便先缓存到earlyApplicationEvents中,等初始化ApplicationEventMulticaster后再发布事件; AbstractApplicationContext执行initApplicationEventMulticaster完成初始化ApplicationEventMulticaster后,便可以发布事件了,紧接着执行registerListeners,代码如下:
protected void registerListeners() {
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
处理DubboConfigInitEvent
ApplicationEvent由ApplicationEventMulticaster.multicastEvent,默认实现为SimpleApplicationEventMulticaster,其代码如下:
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor = getTaskExecutor();
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
获取支持指定事件的ApplicationListener过程中,如果已注册的BeanDefinition中存在匹配的ApplicationListener,那就将其实例化,核心代码如下:
private Collection<ApplicationListener<?>> retrieveApplicationListeners(
ResolvableType eventType, @Nullable Class<?> sourceType, @Nullable CachedListenerRetriever retriever) {
List<ApplicationListener<?>> allListeners = new ArrayList<>();
Set<ApplicationListener<?>> filteredListeners = (retriever != null ? new LinkedHashSet<>() : null);
Set<String> filteredListenerBeans = (retriever != null ? new LinkedHashSet<>() : null);
Set<ApplicationListener<?>> listeners;
Set<String> listenerBeans;
synchronized (this.defaultRetriever) {
listeners = new LinkedHashSet<>(this.defaultRetriever.applicationListeners);
listenerBeans = new LinkedHashSet<>(this.defaultRetriever.applicationListenerBeans);
}
for (ApplicationListener<?> listener : listeners) {
if (supportsEvent(listener, eventType, sourceType)) {
if (retriever != null) {
filteredListeners.add(listener);
}
allListeners.add(listener);
}
}
if (!listenerBeans.isEmpty()) {
ConfigurableBeanFactory beanFactory = getBeanFactory();
for (String listenerBeanName : listenerBeans) {
try {
if (supportsEvent(beanFactory, listenerBeanName, eventType)) {
ApplicationListener<?> listener =
beanFactory.getBean(listenerBeanName, ApplicationListener.class);
if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
if (retriever != null) {
if (beanFactory.isSingleton(listenerBeanName)) {
filteredListeners.add(listener);
}
else {
filteredListenerBeans.add(listenerBeanName);
}
}
allListeners.add(listener);
}
}
else {
Object listener = beanFactory.getSingleton(listenerBeanName);
if (retriever != null) {
filteredListeners.remove(listener);
}
allListeners.remove(listener);
}
}
catch (NoSuchBeanDefinitionException ex) {
}
}
}
AnnotationAwareOrderComparator.sort(allListeners);
if (retriever != null) {
if (filteredListenerBeans.isEmpty()) {
retriever.applicationListeners = new LinkedHashSet<>(allListeners);
retriever.applicationListenerBeans = filteredListenerBeans;
}
else {
retriever.applicationListeners = filteredListeners;
retriever.applicationListenerBeans = filteredListenerBeans;
}
}
return allListeners;
}
在查找支持DubboConfigInitEvent的ApplicationListener过程中,DubboConfigApplicationListener会被实例化;
DubboDeployApplicationListener
DubboDeployApplicationListener实现了ApplicationListener<ApplicationContextEvent>,其关心的事件为ContextRefreshedEvent和ContextClosedEvent; 其实例化时机是在AbstractApplicationContext.finishBeanFactoryInitialization,该方法会将容器中还未实例化的单例RootBeanDefinition预加载入容器中,即提前实例化;
AwaitingNonWebApplicationListener
AwaitingNonWebApplicationListener实现了SmartApplicationListener,其关心的事件为ApplicationReadyEvent和ContextClosedEvent; 在AbstractApplicationEventMulticaster.retrieveApplicationListeners方法中判断SmartApplicationListener实现类是否支持指定事件,需先将其实例化,再根据其supportsEventType方法做进一步判断; 所以AwaitingNonWebApplicationListener实例化是在发生在处理第一次事件时,本文背景下,即为处理DubboConfigInitEvent事件时;
DubboConfigBeanDefinitionConflictApplicationListener
DubboConfigBeanDefinitionConflictApplicationListener实现了ApplicationListener<ContextRefreshedEvent>,其关心的事件为ContextRefreshedEvent; 其实例化时机是在AbstractApplicationContext.finishBeanFactoryInitialization,该方法会将容器中还未实例化的单例RootBeanDefinition预加载入容器中,即提前实例化;
监听逻辑
DubboConfigApplicationListener
DubboConfigApplicationListener只关心DubboConfigInitEvent,用于初始化Dubbo相关配置Bean,代码如下:
public void onApplicationEvent(DubboConfigInitEvent event) {
if (nullSafeEquals(applicationContext, event.getSource())) {
if (initialized.compareAndSet(false, true)) {
initDubboConfigBeans();
}
}
}
initDubboConfigBeans方法将在下篇进行详细分析;
DubboDeployApplicationListener
DubboDeployApplicationListener关心ContextRefreshedEvent和ContextClosedEvent,代码如下:
public void onApplicationEvent(ApplicationContextEvent event) {
if (nullSafeEquals(applicationContext, event.getSource())) {
if (event instanceof ContextRefreshedEvent) {
onContextRefreshedEvent((ContextRefreshedEvent) event);
} else if (event instanceof ContextClosedEvent) {
onContextClosedEvent((ContextClosedEvent) event);
}
}
}
private void onContextRefreshedEvent(ContextRefreshedEvent event) {
ModuleDeployer deployer = moduleModel.getDeployer();
Assert.notNull(deployer, "Module deployer is null");
Future future = deployer.start();
if (!deployer.isBackground()) {
try {
future.get();
} catch (InterruptedException e) {
logger.warn("Interrupted while waiting for dubbo module start: " + e.getMessage());
} catch (Exception e) {
logger.warn("An error occurred while waiting for dubbo module start: " + e.getMessage(), e);
}
}
}
private void onContextClosedEvent(ContextClosedEvent event) {
try {
Object value = moduleModel.getAttribute(ModelConstants.KEEP_RUNNING_ON_SPRING_CLOSED);
boolean keepRunningOnClosed = Boolean.parseBoolean(String.valueOf(value));
if (!keepRunningOnClosed && !moduleModel.isDestroyed()) {
moduleModel.destroy();
}
} catch (Exception e) {
logger.error("An error occurred when stop dubbo module: " + e.getMessage(), e);
}
DubboSpringInitializer.remove(event.getApplicationContext());
}
AwaitingNonWebApplicationListener
AwaitingNonWebApplicationListener关心ApplicationReadyEvent和ContextClosedEvent,代码如下:
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ApplicationReadyEvent) {
onApplicationReadyEvent((ApplicationReadyEvent) event);
}
if (event instanceof ApplicationFailedEvent) {
awaitAndRelease(((ApplicationFailedEvent) event).getApplicationContext());
}
}
protected void onApplicationReadyEvent(ApplicationReadyEvent event) {
final ConfigurableApplicationContext applicationContext = event.getApplicationContext();
if (!isRootApplicationContext(applicationContext) || isWebApplication(applicationContext)) {
return;
}
if (applicationContextId.compareAndSet(UNDEFINED_ID, applicationContext.hashCode())) {
awaitAndRelease(event.getApplicationContext());
}
}
DubboConfigBeanDefinitionConflictApplicationListener
DubboConfigBeanDefinitionConflictApplicationListener只关心ContextRefreshedEvent,当系统启动成功后,会校验当前ApplicationConfig配置信息,代码如下:
public void onApplicationEvent(ContextRefreshedEvent event) {
ApplicationContext applicationContext = event.getApplicationContext();
BeanDefinitionRegistry registry = getBeanDefinitionRegistry(applicationContext);
resolveUniqueApplicationConfigBean(registry, applicationContext);
}
private void resolveUniqueApplicationConfigBean(BeanDefinitionRegistry registry, ListableBeanFactory beanFactory) {
String[] beansNames = beanNamesForTypeIncludingAncestors(beanFactory, ApplicationConfig.class);
if (beansNames.length < 2) {
return;
}
Environment environment = beanFactory.getBean(ENVIRONMENT_BEAN_NAME, Environment.class);
Stream.of(beansNames)
.filter(beansName -> isConfiguredApplicationConfigBeanName(environment, beansName))
.forEach(registry::removeBeanDefinition);
beansNames = beanNamesForTypeIncludingAncestors(beanFactory, ApplicationConfig.class);
if (beansNames.length > 1) {
throw new IllegalStateException(String.format("There are more than one instances of %s, whose bean definitions : %s",
ApplicationConfig.class.getSimpleName(),
Stream.of(beansNames)
.map(registry::getBeanDefinition)
.collect(Collectors.toList()))
);
}
}
|