说明事件监听机制可以理解为观察者模式,有数据发布者(事件源)和数据接收者(监听者);在Java中,事件对象是继承java.util.EventObject对象和事件监听器的java.util.EventListener实例;EventObject对象不提供默认构造函数,需要对外传递source参数,用于记录和跟踪事件的来源;Spring事件Spring事件对象为ApplicationEvent,继承EventObject,源码如下:.timestamp=System.currentTimeMillis();}}Spring的事件监听器是ApplicationListener,它继承了EventListener。源码如下:publicinterfaceApplicationListenerextendsEventListener{voidonApplicationEvent(Evar1);}Spring事件监听有两种实现方式:面向接口编程,实现ApplicationListener接口;基于注解驱动,@EventListener(Spring自定义注解);示例:面向接口编程,实现ApplicationListener接口:自定义事件对象:publicclassMyApplicationEventtextendsApplicationEvent{publicMyApplicationEvent(Objectsource){super(source);}}自定义事件监听器:publicclassMyApplicationListenerimplementsApplicationListener{@OverridepublicvoidonApplicationEvent(MyApplicationEventevent){System.out.println("Receivedevent:"+event);}}启动服务并发布事件:publicclassApplicationEventBootstrap{publicstaticvoidmain(String[]args){AnnotationConfigApplicationContextfigContext=newApplication;//注册自定义事件监听器context.addApplicationListener(newMyApplicationListener());//启动上下文context.refresh();//发布事件,事件源为Contextcontext.publishEvent(newMyApplicationEvent(context));//结束上下文.close();}}运行结果:Eventreceived:com.xx.MyApplicationEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@cb0ed20,startedonSatMay1616:32:04CST2020]使用注解@EventListener实现Spring事件监听:@ComponentpublicclassMyApplicationListener2{@EventListener(MyApplicationEvent.class)publicvoidonEvent(MyApplicationEventevent){System.out.println("收到前夕nt:"+event);}}开始并发布事件:publicclassApplicationEventBootstrap{publicstaticvoidmain(String[]args){AnnotationConfigApplicationContextcontext=newAnnotationConfigApplicationContext();//注册自定义事件监听器context.register(MyApplicationListener2.class);//启动上下文context.refresh();//发布事件,事件源为Contextcontext.publishEvent(newMyApplicationEvent)(context));//Endcontext.close();}}运行结果:通过instance可以看出上面两个方法都可以正常发布和接收事件实现原理从上面的例子可以看出,context是可以发布事件的,底层如何发布,让我们继续看源码:.multicastEvent,Type);...}}通过源码可以看出事件应该是通过ApplicationEventMulticaster来释放的。我们继续看:publicclassSimpleApplicationEventMulticasterextendsAbstractApplicationEventMulticasterSpring事件是通过SimpleApplicationEventMulticaster发布的:getApplicationListeners(event,type)){Executorexecutor=getTaskExecutor();if(executor!=null){//异步executor.execute(()->invokeListener(listener,event));}else{invokeListener(listener,event));}}}可见,如果设置了Executor,则异步发送,否则同步;可以看出,通过resolveDefaultEventType(event)检查发布的事件类型,这就是为什么我们可以直接使用泛型来指定我们要接收的事件对象,比如上面的ApplicationListenerprivatevoiddoInvokeListener(ApplicationListenerlistener,ApplicationEventevent){try{listener.onApplicationEvent(事件);最后就是使用对应的ApplicationListener来接收处理,那么ApplicationListener是什么时候注册的呢?如何添加ApplicationListener?直接添加,使用content.addApplicationListener(上面的例子中使用的);将自定义的ApplicationListener注册为一个bean,Spring会在重新初始化bean后添加它。具体代码在ApplicationListenerDetector#postProcessAfterInitialization中。如果一个bean是一个ApplicationListener,它也是使用context.addApplicationListener添加的;使用注解@EventListener,Bean初始化后,会在EventListenerMethodProcessor中处理添加;第三种实现的源码如下(在EventListenerMethodProcessor中):privatevoidprocessBean(finalStringbeanName,finalClass>targetType){....//获取public并有@EventListener方法AnnotatedElementUtils.findMergedAnnotation(method,EventListener.class));...ApplicationListener>applicationListener=factory.createApplicationListener(beanName,targetType,methodToUse);//添加监听器context.addApplicationListener(applicationListener);}SpringBuild事件ContextRefreshedEvent:Spring应用上下文就绪事件;ContextStartedEvent:Spring应用上下文启动事件;ContextStopedEvent:Spring应用上下文停止事件;ContextClosedEvent:Spring应用上下文关闭事件;SpringBoot事件SpringBoot事件是在Spring事件封装的基础上将publicabstractclassSpringApplicationEventtextendsApplicationEvent事件对象改为SpringApplicationEvent,事件源为SpringApplication(Spring事件源为Context);底层发布事件仍然使用SimpleApplicationEventMulticaster对象,但需要说明的是,从SpringBoot1.4开始,SpringApplication和ApplicationContext都使用SimpleApplicationEventMulticaster实例,但两者属于不同的对象(1.0~1.3版本是同一个对象);事件回顾:publicclassEventBootstrap{publicstaticvoidmain(String[]args){newSpringApplicationBuilder(Object.class).listeners(event->{System.out.println("事件对象:"+event.getClass().getSimpleName()+",事件源:"+event.getSource().getClass().getSimpleName());}).web(WebApplicationType.NONE).run(args).close();}}运行结果:事件对象:ApplicationContextInitializedEvent,event来源:SpringApplication事件对象:ApplicationPreparedEvent,事件来源:SpringApplication事件对象:ContextRefreshedEvent、事件源:AnnotationConfigApplicationContext事件对象:ApplicationStartedEvent、事件源:SpringApplication事件对象:ApplicationReadyEvent、事件源:SpringApplication事件对象:ContextClosedEvent、事件源:AnnotationConfigApplicationContext从结果可以看出,事件对象类型和事件来源,以及事件发布顺序