本文共 5952 字,大约阅读时间需要 19 分钟。
SpringApplicationRunListeners
类和SpringApplicationRunListener
类是SpringBoot中新增的类。SpringApplication类 中使用它们来间接调用ApplicationListener
。
SpringApplicationRunListeners包含了多个SpringApplicationRunListener。
SpringApplicationRunListener接口规定了SpringBoot的生命周期,在各个生命周期广播相应的事件,调用实际的ApplicationListener类。
接口定义如下:
public interface SpringApplicationRunListener { //刚执行run方法时 void started(); //环境建立好时候 void environmentPrepared(ConfigurableEnvironment environment); //上下文建立好的时候 void contextPrepared(ConfigurableApplicationContext context); //上下文载入配置时候 void contextLoaded(ConfigurableApplicationContext context); //上下文刷新完成后,run方法执行完之前 void finished(ConfigurableApplicationContext context, Throwable exception);}
SpringApplication类实际使用的是SpringApplicationRunListeners类,它可以包含多个SpringApplicationRunListener实例,与SpringApplicationRunListener生命周期相同,调用每个周期的各个SpringApplicationRunListener。然后广播相应的事件到ApplicationListener
EventPublishingRunListener类 实现了SpringApplicationRunListener,它具有广播事件的功能。
构造函数
从下面代码可以看出,它使用了Spring广播器SimpleApplicationEventMulticasterpublic EventPublishingRunListener(SpringApplication application, String[] args) { this.application = application; this.args = args; //新建立广播器 this.multicaster = new SimpleApplicationEventMulticaster(); for (ApplicationListener listener : application.getListeners()) { this.multicaster.addApplicationListener(listener); } }
* 当上下文准备好时候,注册名为“applicationEventMulticaster”的bean*
@Override public void contextPrepared(ConfigurableApplicationContext context) { registerApplicationEventMulticaster(context); } private void registerApplicationEventMulticaster( ConfigurableApplicationContext context) { context.getBeanFactory().registerSingleton( AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.multicaster); if (this.multicaster instanceof BeanFactoryAware) { ((BeanFactoryAware) this.multicaster) .setBeanFactory(context.getBeanFactory()); } }
把SpringApplication对象中暂存的所有监听器交给相应的Context
在上下文载入后:@Override public void contextLoaded(ConfigurableApplicationContext context) { for (ApplicationListener listener : this.application.getListeners()) { if (listener instanceof ApplicationContextAware) { ((ApplicationContextAware) listener).setApplicationContext(context); } context.addApplicationListener(listener); } publishEvent(new ApplicationPreparedEvent(this.application, this.args, context)); }
拓展:SpringContext如何的到监听器???
当使用SpringApplication#createAndRefreshContext(..)中refresh(context)时, 在AbstractApplicationContext类 中,有如下方法:protected void initApplicationEventMulticaster() { ConfigurableListableBeanFactory beanFactory = this.getBeanFactory(); if(beanFactory.containsLocalBean("applicationEventMulticaster")) { this.applicationEventMulticaster = (ApplicationEventMulticaster)beanFactory.getBean("applicationEventMulticaster", ApplicationEventMulticaster.class); if(this.logger.isDebugEnabled()) { this.logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]"); } } else { this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster); if(this.logger.isDebugEnabled()) { this.logger.debug("Unable to locate ApplicationEventMulticaster with name \'applicationEventMulticaster\': using default [" + this.applicationEventMulticaster + "]"); } } }
可以看出,前面注册了名为“applicationEventMulticaster”的bean,所以SpringContext不会创建另外的广播器,而是使用我们在EventPublishingRunListener建立的。
从它的源码中可以看出
started()—>ApplicationStartedEvent事件类environmentPrepared(Environment e)—>ApplicationEnvironmentPreparedEvent事件类
contextPrepared(ApplicationContext c)–>在context中注册广播器bean
contextLoaded(ApplicationContext c)–>ApplicationPreparedEvent事件
finished(ApplicationContext context, Throwable t) –>ApplicationFailedEvent()和ApplicationReadyEvent()事件
SpringApplication类没有直接添加SpringApplicationRunListener的方法。查看源码可知, 可以在spring.factory中定义org.springframework.boot.SpringApplicationRunListener=xxx,就会被初始化(与在第一章中初始化函数中相同)。
自己实现的类必须含有以下构造函数,才能被Boot调用public MyRunListener(SpringApplication application, String[] args) { }
META-INF/spring.factory
org.springframework.boot.SpringApplicationRunListener=\com.jazz.other.MyRunListener
* 方法一:代码中添加*
使用SpringApplication#setListeners方法添加监听器SpringApplication#setListeners(..[])或者addListeners(..)使用泛型构造专门接收ApplicationStartedEvent事件的监听器
public class MyStartListner implements ApplicationListener{ @Override public void onApplicationEvent(ApplicationStartedEvent event) { System.out.println("我的程序启动啦!!!"); }}
主程序
public static void main(String[] args) { SpringApplication application = new SpringApplication(App.class); application.addListeners(new MyStartListner()); application.run(args); }
屏幕输出:
我的程序启动啦!!!
. _ _ _ /\ / ‘ _ ()_ _ _ _ \ \ \ \ ( ( )___ | ‘_ | ‘| | ‘ \/ _` | \ \ \ \ \/ _)| |)| | | | | || (| | ) ) ) ) ’ |_| .|| ||| |_, | / / / / =========||==============|__/=///_/ :: Spring Boot :: (v1.3.5.RELEASE)2016-05-26 21:25:23.998 INFO 5008 — [ main] App : Starting App > on Jiazhi-PC with PID 5008 (E:\IdeaProjects\test\target\classes started by Jiazhi in > > E:\IdeaProjects\test)
2016-05-26 21:25:24.000 INFO 5008 — [ …….//省略
方法二:文件中添加
根目录下建立 META-INF/spring.factory,添加自定义的监听器到org.springframework.context.ApplicationListener键转载地址:http://eihgi.baihongyu.com/