相关阅读
简介
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()))
);
}
}
|