ContextRefreshedEvent事件使用注意事项(Spring)
0 概述
ContextRefreshedEvent 事件会在Spring容器初始化完成会触发该事件。我们在实际工作也可以能会监听该事件去做一些事情,但是有时候使用不当也会带来一些问题。
1 防止重复触发
主要因为对于web应用会出现父子容器,这样就会触发两次,那么如何避免呢?下面给出一种简单的解决方案。
@Component public class TestTask implements ApplicationListener<ContextRefreshedEvent> { private volatile AtomicBoolean isInit=new AtomicBoolean(false); @Override public void onApplicationEvent(ContextRefreshedEvent event) { //防止重复触发 if(!isInit.compareAndSet(false,true)) { return; } start(); } private void start() { //开启任务 System.out.println("****-------------------init---------------******"); } }
2 监听事件顺序问题
Spring 提供了一个SmartApplicationListener类,可以支持listener之间的触发顺序,普通的ApplicationListener优先级最低(最后触发)。
@Component public class LastTask implements SmartApplicationListener { private volatile AtomicBoolean isInit = new AtomicBoolean(false); @Override public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) { return eventType == ContextRefreshedEvent.class; } @Override public boolean supportsSourceType(Class<?> sourceType) { return true; } @Override public void onApplicationEvent(ApplicationEvent event) { if (!isInit.compareAndSet(false, true)) { return; } start(); } private void start() { //开启任务 System.out.println("LastTask-------------------init------------ "); } //值越小,就先触发 @Override public int getOrder() { return 2; } }
https://github.com/godmaybelieve