了解专栏完整的内容,请点击跳转:
Spring Framework专栏导航页
作为一款优先的框架,怎么能少得了监听器呢?虽然说现基于web开发的项目很少用到监听器(大多使用消息队列),但是有些时候又需要用到。以及我们想监听Spring容器的初始化相关事件时候,就可以用到Spring自带的的监听器实现方式。
重要组件:事件多播器
两种监听器实现方式
接口方式
@Lazy
@Component
public class ContextRefreshedInterfaceListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
System.out.println("接口监听");
}
}
注解方式
@Lazy // 加了懒加载 这个Bean不会被创建 但是 里边用注解标记的监听事件会被通过后置处理器创建出来
@Component
public class ContextRefreshedAnnotationListener {
@EventListener(ContextRefreshedEvent.class)
public void onAppllicationEvent(ContextRefreshedEvent event) {
System.out.println("注解监听");
}
}
创建多播器
// refresh().initApplicationEventMulticaster();
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//判断容器中是没有有我们的applicationEventMulticaster 应用多播器组件
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
//直接显示的调用我们的getBean获取出来赋值给我们的applicationContext对象
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
//spring ioc显示的new 一个SimpleApplicationEventMulticaster对象保存在applicatoinContext对象中
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
//并且注入到容器中
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
注册接口方式监听器的后置处理器
// refresh().prepareBeanFactory(ConfigurableListableBeanFactory beanFactory);
......
// 用于处理实现了ApplicationListener接口的bean,bean初始化后将其添加到监听器集合中 来监听事件
// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
......
注册监听器BeanName
// 注册接口方式的监听器 其实只是注册监听器名字
// 防止懒加载监听器漏掉
// 事件发布时候 会再根据这里注册的名字 把懒加载的bean进行实例化 然后再发布事件
// refresh().registerListeners();
protected void registerListeners() {
// 获取容器中所有的监听器对象
// 这个时候正常流程是不会有监听器的
// Register statically specified listeners first.
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster()