文章目录
- 简介
- 案例
- ApplicationListener简介
- Spring的事件
- Spring默认启动事件
- SpringBoot默认启动事件
- Spring环境下的实现事件发布监听的方法
简介
* 3、ApplicationListener:监听容器中发布的事件。事件驱动模型开发;
* public interface ApplicationListener<E extends ApplicationEvent>
* 监听 ApplicationEvent 及其下面的子事件;
*
* 步骤:
* 1)、写一个监听器(ApplicationListener实现类)来监听某个事件(ApplicationEvent及其子类)
* @EventListener;
* 原理:使用EventListenerMethodProcessor处理器来解析方法上的@EventListener;
*
* 2)、把监听器加入到容器;
* 3)、只要容器中有相关事件的发布,我们就能监听到这个事件;
* ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件;
* ContextClosedEvent:关闭容器会发布这个事件;
* 4)、发布一个事件:
* applicationContext.publishEvent();
案例
创建一个自定义事件监听器类。
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
//当容器中发布此事件以后,方法触发
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("收到事件:"+event);
}
}
测试类,并发布一个事件。
@Test
public void test(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
//发布事件;
applicationContext.publishEvent(new ApplicationEvent(new String("我发布的事件")) {
});
applicationContext.close();
}
输出结果
收到事件:org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@2db0f6b2: startup date [Sun Sep 15 16:28:36 CST 2019]; root of context hierarchy]
收到事件:com.demo.IOCTest$1[source=我发布的事件]
收到事件:org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@2db0f6b2: startup date [Sun Sep 15 16:28:36 CST 2019]; root of context hierarchy]
ApplicationListener简介
依赖于Spring框架,在Spring启动时调用。在普通Spring应用中一般监听ContextRefreshedEvent事件。
ApplicationContext事件机制是观察者设计模式的实现,通过ApplicationEvent类和ApplicationListener接口,可以实现ApplicationContext事件处理。
如果容器中有一个ApplicationListener Bean,每当ApplicationContext发布ApplicationEvent时,ApplicationListener Bean将自动被触发。这种事件机制都必须需要程序显示的触发。
其中spring有一些内置的事件,当完成某种操作时会发出某些事件动作。比如监听ContextRefreshedEvent事件,当所有的bean都初始化完成并被成功装载后会触发该事件,实现ApplicationListener<ContextRefreshedEvent>
接口可以收到监听动作,然后可以写自己的逻辑。
同样事件可以自定义、监听也可以自定义,完全根据自己的业务逻辑来处理。
需要注意的是,在普通Spring环境中,基于ApplicationListener的监听器的onApplicationEvent方法可能会被执行多次,所以需要添加以下判断:
public void onApplicationEvent(ContextRefreshedEvent event) {
//root application context 没有parent
if(event.getApplicationContext().getParent() == null){
}
}
Spring的事件
ApplicationEvent:事件本身 事件接口。
ApplicationListener:事件监听者 事件监听器接口,所有的监听器都实现该接口。
ApplicationEventPublisher:事件发布者 事件发布接口,ApplicationContext实现了该接口。
ApplicationEventMulticaster: Spring事件机制中的事件广播器,执行事件。
执行流程:
当一个事件源产生事件时,它通过事件发布器ApplicationEventPublisher发布事件,然后事件广播器ApplicationEventMulticaster会去事件注册表ApplicationContext中找到事件监听器ApplicationListnener,并且逐个执行监听器的onApplicationEvent方法,从而完成事件监听器的逻辑。
Spring默认启动事件
-
ContextRefreshedEvent:
ApplicationContext 被初始化或刷新时,该事件被发布。这也可以在 ConfigurableApplicationContext接口中使用 refresh() 方法来发生。此处的初始化是指:所有的Bean被成功装载,后处理Bean被检测并激活,所有Singleton Bean 被预实例化,ApplicationContext容器已就绪可用。 -
ContextStartedEvent:
当使用 ConfigurableApplicationContext (ApplicationContext子接口)接口中的 start() 方法启动 ApplicationContext 时,该事件被发布。你可以调查你的数据库,或者你可以在接受到这个事件后重启任何停止的应用程序。 -
ContextStoppedEvent:
当使用 ConfigurableApplicationContext 接口中的 stop() 停止 ApplicationContext 时,发布这个事件。你可以在接受到这个事件后做必要的清理的工作。 -
ContextClosedEvent:
当使用 ConfigurableApplicationContext 接口中的 close() 方法关闭 ApplicationContext 时,该事件被发布。一个已关闭的上下文到达生命周期末端;它不能被刷新或重启。 -
RequestHandledEvent:
这是一个 web-specific 事件,告诉所有 bean HTTP 请求已经被服务。只能应用于使用DispatcherServlet的Web应用。在使用Spring作为前端的MVC控制器时,当Spring处理用户请求结束后,系统会自动触发该事件。
SpringBoot默认启动事件
-
ApplicationStartingEvent:
SpringBoot启动开始的时候执行的事件 -
ApplicationEnvironmentPreparedEvent:
SpringBoot对应Enviroment已经准备完毕,但此时上下文context还没有创建。在该监听中获取到ConfigurableEnvironment后可以对配置信息做操作,例如:修改默认的配置信息,增加额外的配置信息等等。 -
ApplicationPreparedEvent:
SpringBoot上下文context创建完成,但此时Spring中的bean是没有完全加载完成的。在获取完上下文后,可以将上下文传递出去做一些额外的操作。值得注意的是:在该监听器中是无法获取自定义bean并进行操作的。 -
ApplicationReadyEvent:
SpringBoot加载完成时候执行的事件。 -
ApplicationFailedEvent:
SpringBoot启动异常时执行事件。
Spring环境下的实现事件发布监听的方法
自定义事件,继承自ApplicationEvent抽象类。
@Getter
@Setter
public class MyApplicationEvent extends ApplicationEvent {
private String msg;
public MyApplicationEvent(Object source, String msg) {
super(source);
this.msg = msg;
}
}
自定义监听事件的发布:
@Resource
private ApplicationContext applicationContext;
applicationContext.publishEvent(new MyApplicationEvent("测试事件", msg));
SpringBoot进行事件监听有四种方式:
1、写代码向ApplicationContext中添加监听器\
// 实现ApplicationListener接口
public class MyApplicationListener implements ApplicationListener<MyApplicationEvent> {
@Override
public void onApplicationEvent(MyApplicationEvent myApplicationEvent) {
System.out.println("监听到事件源:" + myApplicationEvent);
}
}
// 装载监听
@SpringBootApplication
public class MqProviderApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(MqProviderApplication.class);
app.addListeners(new MyApplicationListener());//加入自定义的监听类
app.run(args);
}
}
2、使用Component注解将监听器装载入Spring容器
@Component
public class MyApplicationListener implements ApplicationListener<MyApplicationEvent> {
@Override
public void onApplicationEvent(MyApplicationEvent myApplicationEvent) {
System.out.println("监听到事件源:" + myApplicationEvent);
}
}
3、在application.yml中配置监听器
public class MyApplicationListener implements ApplicationListener<MyApplicationEvent> {
@Override
public void onApplicationEvent(MyApplicationEvent myApplicationEvent) {
System.out.println("监听到事件源:" + myApplicationEvent);
}
}
context:
listener:
classes: com.provider.listener.MyApplicationListener
4、通过@EventListener注解实现事件监听
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class MyApplicationListener {
@EventListener(classes = MyApplicationEvent.class)
public void onApplicationEvent(MyApplicationEvent myApplicationEvent) {
System.out.println("监听到事件源:" + myApplicationEvent);
}
}