欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

十一、Spring之事件监听

程序员文章站 2023-04-04 14:30:59
Spring之事件监听 ApplicationListener ApplicationListener是Spring事件机制的一部分,与抽象类ApplicationEvent类配合来完成ApplicationContext的事件机制。 如果容器中存在ApplicationListener的Bean, ......

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

十一、Spring之事件监听

我们来具体看一下这个事件是如何发布的

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

十一、Spring之事件监听

这里的执行invokelistener主要是来回调listener的接口方法

十一、Spring之事件监听

以上就是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);
}