常言道,此处无声更胜有声。看似无关联,实际千丝万缕。事件驱动让你的代码充分解耦,让我们一起看看Spring提供的事件驱动吧❤️
是什么
- 监听容器中发布的事件,事件驱动模型开发
public interface ApplicationListener<E extends ApplicationEvent>意思是监听ApplicationEvent及其下面的子事件
示例
- 写一个监听器来监听某个事件(
ApplicationEvent及其下面的子事件) - 把监听器加入容器
- 只要容器中有相关事件的发布,我们就能监听到这个事件,例如
ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件
//接收事件方式
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent>{
//当容器中发布此事件之后,方法会被触发
@Override
public void onApplicationEvent(ApplicationEvent event){
System.out.println("收到事件:"+event);
}
}
//发送事件方式
applicationContext.publishEvent(new ApplicationEvent(new Stirng("我发布的事件..")))
原理解析
- 容器创建对象,
refresh() finishRefresh()容器刷新完成publishEvent(new ContextRefreshedEvent(this))- 事件发布流程:
- 获取事件的多播器(派发器),
getApplicationEventMulticaster() multicastEvent派发事件- 获取到所有的
ApplicationListenerfor(final ApplicationListener<?> listener:getApplicationListeners(event, type)) - 如果有
Executor可以支持使用Executor进行异步派发Executor executor = getTaskExecutor() - 否则,同步的方式直接执行
listener方法invokeListener(listener, event)
- 获取事件的多播器(派发器),
- 可以用来监听容器创建好之后执行一些操作,比如初始化数据,初始化缓存 等等。
- 除了采用实现接口的方式创建自己的监听器,还可以采用注解的方式
@Component
public class Test{
@EventListener(classes=ApplicationEvent.class)
public void test1(ApplicationEvent e){
System.out.println("收到事件:"+e);
}
}
自定义事件发布
- 自定义事件,继承
ApplicationContextEvent抽象类
public class MyApplicationEvent extends ApplicationEvent{
private static final long serialVersionUID = 1L;
public MyApplicationEvent(ApplicationContext source){
super(source)
}
}
- 写个实现了
ApplicationListener接口的监听器 监听我们自定义的事件(加在ioc容器中)
@Component
public class MyApplicationListener implements ApplicationListener<MyApplicationEvent>{
public void onApplicationEvent(MyApplicationEvent event){
System.out.println("收到事件"+event);
System.out.println("收到事件"+event.getTimestamp());
System.out.println("收到事件"+event.getSource());
}
}
- 发布事件
@SpringBootTest
@RunWith(SpringRunner.class)
public class Test {
@Autowired
private ApplicationContext applicationContext;
@Test
public void test1() {
applicationContext.publishEvent(new MyApplicationEvent(new Stirng("我发布的事件..")));
}
}