說到事件監聽,想到的確定是觀察者模式。可是這兒主要說下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整合的