1.问题目标:调用context.publishEvent(),事件监听类里面的方法会执行
1.入口
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
context.publishEvent(new EnjoyEvent("事件名称"));
2.原因
因为context.publishEvent会调用SimpleApplicationEventMulticaster类的multicastEvent方法
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
invokeListener(listener, event);
}
3.初始化上下文提前做的事
1.初始化事件管理类:在beanFactory创建SimpleApplicationEventMulticaster
initApplicationEventMulticaster()
2.注册事件监听器,把实现了ApplicationListen接口的所有实现类添加到事件管理类的一个Set集合
registerListeners(),
this.defaultRetriever.applicationListenerBeans.add(listenerBeanName);
context.addApplicationListener(new EnjoyApplicationListener2());
this.defaultRetriever.applicationListeners.add(listener);
添加监听器类的两种方式:一种上下文添加监听类,一种监听类加注解@Compoment
this.defaultRetriever.applicationListeners.add(listener);
2.Spring定义的事件之调用源码
上下文更新事件(ContextRefreshedEvent),在调用ConfigurableApplicationContext接口中的refresh()方法时触发
上下文开始事件(ContextStartedEvent),当容器调用ConfigurableApplicationContext的start()方法时触发该事件
上下文停止事件(ContextStoppedEvent),当容器调用ConfigurableApplicationContext的stop()方法时触发该事件
上下文关闭事件(ContextClosedEvent),当ApplicationContext被关闭时触发该事件;容器被关闭时,其管理的所有单例Bean都被销毁
请求处理事件(RequestHandlerEvent),在web应用中,当一个http请求结束触发该事件
3.自定义事件、监听器、发布事件
1.自定义事件 继承ApplicationEvent类
public class EnjoyEvent extends ApplicationEvent {
private String name;
public EnjoyEvent(Object source) {
super(source);
this.name = name;
}
}
2.自定义监听器 1.实现ApplicationListener接口 2.类上加@Component注解或者手动添加context.addApplicationListener(new EnjoyApplicationListener2());
@Component
public class EnjoyApplicationListener implements ApplicationListener {
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof EnjoyEvent) {
System.out.println("== 监听到享学事件EnjoyEvent,do something");
}
}
}
3.发布事件
context.publishEvent(new EnjoyEvent("事件名称"));