当前位置: 移动技术网 > IT编程>开发语言>Java > 十一、Spring之事件监听

十一、Spring之事件监听

2019年11月10日  | 移动技术网IT编程  | 我要评论

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);
}

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网