Spring学习笔记-监听器
今天我们来聊一聊Spring的监听器,来了解Spring的监听器是如何使用的,以及使用原理,接下来从监听器的使用以及原理分析两部分来详细说明:
监听器实现
直接上代码,做一个简易的实现,我们需要几个类,首先是我们的配置类,监听器类以及测试类;
监听器类:
需要实现ApplicationListener这个接口,然后加入未实现的方法,写入我们的监听内容。
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;public class MyListener implements ApplicationListener<ApplicationEvent>{
public void onApplicationEvent(ApplicationEvent arg0) {
System.out.println("监听====="+arg0);
}
}
配置类:
将我们的监听器类加入到我们的bean容器当中。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ListenerConfig {
@Bean
public MyListener myListener(){return new MyListener();
}}
测试类:
通过容器的publishEvent方法,我们可以加入我们的自定义事件。
import org.junit.Test;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;import com.wjs.listener.ListenerConfig;
public class TestListener {
@Test
public void test(){
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(ListenerConfig.class);
annotationConfigApplicationContext.publishEvent(new ApplicationEvent("新建的事件-----") {
});
annotationConfigApplicationContext.close();
}}
测试的结果:
原理分析
从以上的测试结果我们发现监听器已经生效,监测到了容器的创建刷新事件、我们通过容器的publishEvent方法新加的自定义事件,以及我们容器关闭的事件,我们来分析下它的实现原理,断点跟进,
1、还是容器创建的时候,调用容器创建的refresh方法————>finishRefresh()方法,在这个方法里执行了我们发布最后事件的方法publishEvent(new ContextRefreshedEvent(this)),进行事件的发布。
2、publishEvent发布事件方法中主要做的一件事就是拿到我们的派发器(getApplicationEventMulticaster()),然后派发事件(multicastEvent)。
3、进入派发事件方法,首先for循环拿到所有的监听器,如果有excutor,则可以进行异步事件派发,否则,同步方式的话,直接执行listener方法,invokeListener(listener, event);也就到了我们的目标方法,invokeListener------doInvokeListener--onApplicationEvent,到此一个事件的监听过程就实现了。
上面其实还有一个问题没说明,那就是我们在什么时候将我们的所有监听类注册到了这个派发器中,我们一起来分析下,
首先我们还是来看下容器的refresh方法,他里面在结束初始化bean之前会去执行两个方法,分别是initApplicationEventMulticaster()和registerListeners(),根据注解不难理解到,一个是初始化这个派发器方法 ,一个是注册这个监听器方法,
initApplicationEventMulticaster
1、首选判断容器中是否包含这个“applicationEventMulticaster” bean,
2、如果包含,直接以getBean的形式直接取出这个派发器,
3、如果不包含,则创建一个SimpleApplicationEventMulticaster对象,并注册到beanFactory中,
4、这样我们在后面的操作中就能取到这个派发器了,
registerListeners
1、首先通过getBeanNameForType方法拿到所有的监听器,
2、然后循环遍历并注册到我们的派发器中,
3、最后我们的派发器中就有了我们创建的监听器了。
所以在后面执行finishRefresh方法的时候,我们的派发器就能够派发事件了。
补充说明下:
监听器也可以通过注解的方法进行实现,也就是 @EventListener 注解,属性中表示我们需要监听的事件,可以添加多个,具体原理可断点跟进源码了解。