Spring Boot启动过程源码分析(二)事件监听器

本文详细解析了SpringBoot中的事件监听机制,包括如何添加监听器、支持的事件类型及监听器的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       在http://blog.youkuaiyun.com/zero__007/article/details/77265239中大致介绍了Spring Boot启动过程,在SpringApplication.initialize()方法中会调用为setListeners()方法为SpringApplication添加监听器,默认的监听器是配置文件中Key为org.springframework.context. ApplicationListener的value:
# Application Listeners  
org.springframework.context.ApplicationListener=\  
org.springframework.boot.ClearCachesApplicationListener,\  
org.springframework.boot.builder.ParentContextCloserApplicationListener,\  
org.springframework.boot.context.FileEncodingApplicationListener,\  
org.springframework.boot.context.config.AnsiOutputApplicationListener,\  
org.springframework.boot.context.config.ConfigFileApplicationListener,\  
org.springframework.boot.context.config.DelegatingApplicationListener,\  
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener,\  
org.springframework.boot.logging.ClasspathLoggingApplicationListener,\  
org.springframework.boot.logging.LoggingApplicationListener  
       然后加载上述的类并实例化后,设置在SpringApplication的listeners中。
       在过程代码中也可以为SpringApplication添加自定义事件监听器:
	public void addListeners(ApplicationListener<?>... listeners) {
		this.listeners.addAll(Arrays.asList(listeners));
	}
       spring boot支持的事件监听类型有如下四种:ApplicationStartedEvent、ApplicationEnvironmentPreparedEvent、ApplicationPreparedEvent、ApplicationFailedEvent。

       那么监听器是如何工作的呢?在SpringApplication.run()方法中:
	public ConfigurableApplicationContext run(String... args) {
		……
		SpringApplicationRunListeners listeners = getRunListeners(args);
		listeners.starting();
		try {
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(
					args);
			ConfigurableEnvironment environment = prepareEnvironment(listeners,
					applicationArguments);
			Banner printedBanner = printBanner(environment);
			context = createApplicationContext();
			analyzers = new FailureAnalyzers(context);
			prepareContext(context, environment, listeners, applicationArguments,
					printedBanner);
			refreshContext(context);
			afterRefresh(context, applicationArguments);
			listeners.finished(context, null);
            …….
	}
       来看getRunListeners():
	private SpringApplicationRunListeners getRunListeners(String[] args) {
		Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
		return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances(
				SpringApplicationRunListener.class, types, this, args));
	}
       这里的getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args),会在META-INF/spring.factories中找到:
# Run Listeners
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener
       不多解释,getSpringFactoriesInstances()返回了EventPublishingRunListener实例。EventPublishingRunListener的构造方法如下:
	public EventPublishingRunListener(SpringApplication application, String[] args) {
		this.application = application;
		this.args = args;
		this.initialMulticaster = new SimpleApplicationEventMulticaster();
		for (ApplicationListener<?> listener : application.getListeners()) {
			this.initialMulticaster.addApplicationListener(listener);
		}
	}
       构造方法中将SpringApplication中的监听器添加到了SimpleApplicationEventMulticaster的实例multicaster中。

       OK,接下来SpringApplication.run()方法中调用listeners.starting()方法,来看下:
	public void starting() {
		for (SpringApplicationRunListener listener : this.listeners) {
			listener.starting();
		}
	}
	@Override
	@SuppressWarnings("deprecation")
	public void starting() {
		this.initialMulticaster
				.multicastEvent(new ApplicationStartedEvent(this.application, this.args));
	}
       在EventPublishingRunListener.starting()方法中,先创建一个ApplicationStartedEvent事件,将this.application传递进去,因此使用ApplicationStartedEvent监听器时可以获取SpringApplication实例。
       SimpleApplicationEventMulticaster.multicastEvent():
	@Override
	public void multicastEvent(ApplicationEvent event) {
		multicastEvent(event, resolveDefaultEventType(event));
	}
	@Override
	public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
		ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
		for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
			Executor executor = getTaskExecutor();
			if (executor != null) {
				executor.execute(new Runnable() {
					@Override
					public void run() {
						invokeListener(listener, event);
					}
				});
			}
			else {
				invokeListener(listener, event);
			}
		}
	}
       getApplicationListeners()获取对应ApplicationEvent的listener,获取完指定事件对应监听器后,通过Executor执行一个子线程执行invokeListener(listener, event),该函数会调用监听器listener.onApplicationEvent(event)方法。
       在SpringApplication.run()方法执行中,依次调用了listeners.starting()、listeners.environmentPrepared(environment)、listeners.contextLoaded(context)分别对应了ApplicationStartedEvent、ApplicationEnvironmentPreparedEvent、ApplicationPreparedEvent事件。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值