Spring監聽器---ApplicationListener

說到事件監聽,想到的確定是觀察者模式。可是這兒主要說下spring中的監聽是怎麼樣的流程。spring

這就不得不說到spring容器的refresh方法,容器啓動過程當中,listener相關的主要是這個三個方法:initApplicationEventMulticaster方法初始化事件多播器,後續的事件發佈都是由多播器來發布的;registerListeners註冊監聽器到前面初始化好的多播器上面去;併發

finishRefresh容器啓動完成最後刷新,發佈ContextRefreshedEvent事件。

 

 

1.初始化多播器:獲取bean工廠對象ConfigurableListableBeanFactory,判斷容器中是否有applicationEventMulticaster多播器,若是沒有則建立一個一個簡單事件多播器SimpleApplicationEventMulticaster並註冊到容器中,後續使用app

 

 

 

2.註冊監聽器到多播器上併發布早期事件:首先獲取容器中已有的監聽器(成品對象),註冊到多播器;而後獲取bean定義中的監聽器,也就是咱們本身定義的監聽器;一樣也註冊到多播器上去;最後若是有早期事件就去發佈早期事件,multicastEvent方法ide

 

 

發佈事件:multicastEvent方法----->invokeListener方法---->doInvokeListener方法調用監聽器的onApplicationEvent測試

 

3.執行finishRefresh方法發佈ContextRefreshedEvent事件,標誌的容器已經啓動完成。spa

 

 

監聽器的流程完了,咱們如今來看下使用code

首先實現一個本身的監聽器對象

package com.nijunyang.spring.listener;

        import org.springframework.context.ApplicationEvent;
        import org.springframework.context.ApplicationListener;
        import org.springframework.stereotype.Component;

/**
 * Description:
 * Created by nijunyang on 2020/2/20 21:53
 */
@Component
public class MyListener implements ApplicationListener<ApplicationEvent> {
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        System.out.println("收到事件:" + event.toString());
    }
}

 

新建一個本身的事件:blog

package com.nijunyang.spring.listener;

import org.springframework.context.ApplicationEvent;

/**
 * Description:
 * Created by nijunyang on 2020/2/20 22:05
 */
public class MyApplicationEvent extends ApplicationEvent {
    /**
     * Create a new ApplicationEvent.
     *
     * @param source the object on which the event initially occurred (never {@code null})
     */
    public MyApplicationEvent(Object source) {
        super(source);
    }
}

配置類:指定要掃描的包事件

package com.nijunyang.spring;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * @author: create by nijunyang
 * @date:2019/10/6
 */
@Configuration
@ComponentScan(basePackages = "com.nijunyang.spring.*")
public class MainConfig {
}

測試代碼:在容器建立完以後發佈本身的事件。

package com.nijunyang.spring;

import com.nijunyang.spring.listener.MyApplicationEvent;
import com.nijunyang.spring.model.Student;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Application {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
        context.publishEvent(new MyApplicationEvent("想漲工資"));
    }

}

執行代碼會發現咱們的監聽器會監聽到兩個事件,由於咱們監聽器監聽的事件是ApplicationEvent,上面說到容器啓動的時候,最後會執行finishRefresh方法發佈ContextRefreshedEvent事件,容器啓動完成以後,咱們本身手動發佈了一個咱們本身的事件,所以會監聽到兩個事件。

 

 

 修改咱們的監聽器,只監聽咱們本身的事件:

package com.nijunyang.spring.listener;

import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

/**
 * Description:
 * Created by nijunyang on 2020/2/20 21:53
 */
@Component
public class MyListener implements ApplicationListener<MyApplicationEvent> {
    @Override
    public void onApplicationEvent(MyApplicationEvent event) {
        System.out.println("收到事件:" + event.toString());
    }
}

 

 再次執行代碼,發現如今就只能監聽咱們本身的事件了

 

 

經過spring的監聽器,咱們不只能夠實現本身相關的業務,還能夠經過這個機制將咱們本身的組件和spring進行整合,好比阿里的nacos就是經過ApplicationListener與spring整合的

相關文章
相關標籤/搜索