述
了解了监听器的工作原理之后,我们来看一下自定义的监听器如何实现
监听器的实现跟之前的系统初始化器的实现基本是一致的
第一种方式
创建监听器,实现 ApplicationListener
,泛型是些对应的感兴趣的事件,如下:1
2
3
4
5
6
7
8
9
10@Order(1)
@Slf4j
public class FirstListener implements ApplicationListener<ApplicationStartedEvent> {
@Override
public void onApplicationEvent(ApplicationStartedEvent event) {
log.info("监听到:{}", event.getClass().getName());
}
}
和系统初始化器一样,也需要在 spring.factories
中配置,如下:1
org.springframework.context.ApplicationListener=com.zhou.springboot.example.listener.FirstListener
第二种方式
1 | @Order(2) |
修改启动类,如下:1
2
3
4
5
6
7
8
9
10@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(App.class);
springApplication.addInitializers(new SecondInitializer());
springApplication.addListeners(new SecondListener());
springApplication.run(args);
}
}
第三种方式
1 | @Order(3) |
在 application 配置文件中配置1
2
3context:
listener:
classes: com.zhou.springboot.example.listener.ThirdListener
第四种方式
前面三种方式都是和系统初始化器的配置方法一样的,监听器还有一种实现方式如下:
1 | @Order(4) |
这里是实现 SmartApplicationListener
接口, 在 supportsEventType()
方法中,配置自己感兴趣的事件,然后下面的 onApplicationEvent()
是具体的处理方法
同样的,这个监听器也是需要加到配置中去的,上面三种方式随便哪一种都行, 比如加到 application
配置文件中去:1
2
3context:
listener:
classes: com.zhou.springboot.example.listener.ThirdListener,com.zhou.springboot.example.listener.FourthListener
运行测试
启动项目,日志如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 . ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.4.RELEASE)
2020-02-03 17:27:35.225 INFO 8832 --- [ main] c.z.s.e.initializers.ThirdInitializer : ThirdInitializer done...
2020-02-03 17:27:35.232 INFO 8832 --- [ main] c.z.s.e.initializers.FirstInitializer : FirstInitializer done...
2020-02-03 17:27:35.232 INFO 8832 --- [ main] c.z.s.e.initializers.SecondInitializer : SecondInitializer done...
2020-02-03 17:27:35.258 INFO 8832 --- [ main] com.zhou.springboot.example.App : Starting App on DESKTOP-B1V47DV with PID 8832 (D:\Demo\SpringBoot\spring-boot-example\build\classes\java\main started by Administrator in D:\Demo\SpringBoot\spring-boot-example)
2020-02-03 17:27:35.260 INFO 8832 --- [ main] com.zhou.springboot.example.App : No active profile set, falling back to default profiles: default
2020-02-03 17:27:35.368 INFO 8832 --- [ main] c.z.s.example.listener.FourthListener : 监听到:org.springframework.boot.context.event.ApplicationPreparedEvent
2020-02-03 17:27:37.582 INFO 8832 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2020-02-03 17:27:37.609 INFO 8832 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-02-03 17:27:37.610 INFO 8832 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.30]
2020-02-03 17:27:37.930 INFO 8832 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-02-03 17:27:37.930 INFO 8832 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2559 ms
2020-02-03 17:27:38.360 INFO 8832 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-02-03 17:27:38.771 INFO 8832 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2020-02-03 17:27:38.779 INFO 8832 --- [ main] com.zhou.springboot.example.App : Started App in 4.564 seconds (JVM running for 9.864)
2020-02-03 17:27:38.780 INFO 8832 --- [ main] c.z.s.example.listener.ThirdListener : 监听到:org.springframework.boot.context.event.ApplicationStartedEvent
2020-02-03 17:27:38.780 INFO 8832 --- [ main] c.z.s.example.listener.FourthListener : 监听到:org.springframework.boot.context.event.ApplicationStartedEvent
2020-02-03 17:27:38.781 INFO 8832 --- [ main] c.z.s.example.listener.FirstListener : 监听到:org.springframework.boot.context.event.ApplicationStartedEvent
2020-02-03 17:27:38.781 INFO 8832 --- [ main] c.z.s.example.listener.SecondListener : 监听到:org.springframework.boot.context.event.ApplicationStartedEvent
这里可以看到 FourthListener
执行了两次,因为我们上面配置了两种事件, 然后同样的 application
配置文件指定的要优先于其他方式,原理和系统初始化器一样
总结
自定义监听器的三种实现方式:
- 定义在 spring.factories 中,被 SpringFactoriesLoader 发现注册.
- 在 SpringApplication 初始化完毕之后手动添加
- 定义成环境变量,被 DelegatingApplicationListener 发现注册