十一、Spring之事件监听
spring之事件监听
applicationlistener
applicationlistener是spring事件机制的一部分,与抽象类applicationevent类配合来完成applicationcontext的事件机制。
如果容器中存在applicationlistener的bean,当applicationcontext调用publishevent方法时,对应的bean会被触发。这一过程是典型的观察者模式的实现。
源码:
@functionalinterface public interface applicationlistener<e extends applicationevent> extends eventlistener { /** * handle an application event. * @param event the event to respond to */ void onapplicationevent(e event); }
contextrefreshedevent事件的监听
以spring的内置事件contextrefreshedevent为例,当applicationcontext被初始化或刷新时,会触发contextrefreshedevent事件,下面我们就实现一个applicationlistener来监听此事件的发生。
@component // 需对该类进行bean的实例化 public class learnlistener implements applicationlistener<contextrefreshedevent> { @override public void onapplicationevent(contextrefreshedevent event) { // 打印容器中出事bean的数量 system.out.println("监听器获得容器中初始化bean数量:" + event.getapplicationcontext().getbeandefinitioncount()); } }
事件发布
在容器创建完成后,在finishrefresh()方法中发布了一个事件——contextrefreshedevent
我们来具体看一下这个事件是如何发布的
protected void publishevent(object event, @nullable resolvabletype eventtype) { assert.notnull(event, "event must not be null"); // decorate event as an applicationevent if necessary applicationevent applicationevent; if (event instanceof applicationevent) { applicationevent = (applicationevent) event; } else { applicationevent = new payloadapplicationevent<>(this, event); if (eventtype == null) { eventtype = ((payloadapplicationevent<?>) applicationevent).getresolvabletype(); } } // multicast right now if possible - or lazily once the multicaster is initialized if (this.earlyapplicationevents != null) { this.earlyapplicationevents.add(applicationevent); } else { //获取事件的派发器 getapplicationeventmulticaster().multicastevent(applicationevent, eventtype); } // publish event via parent context as well... if (this.parent != null) { if (this.parent instanceof abstractapplicationcontext) { ((abstractapplicationcontext) this.parent).publishevent(event, eventtype); } else { this.parent.publishevent(event); } } }
派发事件:getapplicationeventmulticaster().multicastevent(applicationevent, eventtype);
这里的执行invokelistener主要是来回调listener的接口方法
以上就是spring中事件发布的流程。
事件派发器
在事件发布的过程中,有一步是获取事件的派发器,那么事件派发器是在哪里创建的呢?
实际上在容器初始化时,执行了initapplicationeventmulticaster()这个方法,来为容器初始化事件派发器。
protected void initapplicationeventmulticaster() { configurablelistablebeanfactory beanfactory = getbeanfactory(); //先来判断容器中有没有applicationeventmulticaster if (beanfactory.containslocalbean(application_event_multicaster_bean_name)) { this.applicationeventmulticaster = beanfactory.getbean(application_event_multicaster_bean_name, applicationeventmulticaster.class); if (logger.istraceenabled()) { logger.trace("using applicationeventmulticaster [" + this.applicationeventmulticaster + "]"); } } else { //如果没有则创建一个派发器 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() + "]"); } } }
application_event_multicaster_bean_name:
public static final string application_event_multicaster_bean_name = "applicationeventmulticaster";
监听器从哪里来
refresh()方法中执行了registerlisteners()来给容器中注册监听器
protected void registerlisteners() { // register statically specified listeners first. for (applicationlistener<?> listener : getapplicationlisteners()) { getapplicationeventmulticaster().addapplicationlistener(listener); } // do not initialize factorybeans here: we need to leave all regular beans // uninitialized to let post-processors apply to them! //根据类型获取所有的监听器的bean名称 string[] listenerbeannames = getbeannamesfortype(applicationlistener.class, true, false); for (string listenerbeanname : listenerbeannames) { //将监听器加入到派发器当中 getapplicationeventmulticaster().addapplicationlistenerbean(listenerbeanname); } // publish early application events now that we finally have a multicaster... set<applicationevent> earlyeventstoprocess = this.earlyapplicationevents; this.earlyapplicationevents = null; if (earlyeventstoprocess != null) { for (applicationevent earlyevent : earlyeventstoprocess) { getapplicationeventmulticaster().multicastevent(earlyevent); } } }
@eventlistener
除了实现applicationlistener接口来完成事件监听以外,@eventlistener这个注解也同样可以监听事件的发生
只需要将@eventlistener标注在方法上面:
@eventlistener(classes = {applicationevent.class}) public void listen(applicationevent applicationevent){ system.out.println("监听到:"+applicationevent); }
上一篇: 服务状态控制
下一篇: 揭秘:清朝十二位皇帝分别是怎么去世的?