先看一個demo,加入依賴
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
定義一個自定義事件,繼承ApplicationEvent類
/**
* 定義事件
*
*/
public class MyApplicationEvent extends ApplicationEvent {
private static final long serialVersionUID = 1L;
public MyApplicationEvent(Object source) {
super(source);
}
}
定義一個事件監(jiān)聽器MyApplicationListener實現(xiàn)ApplicationListener接口艇挨,
package com.zhihao.miao;
import org.springframework.context.ApplicationListener;
public class MyApplicationListener implements ApplicationListener<MyApplicationEvent> {
public void onApplicationEvent(MyApplicationEvent event) {
System.out.println("接收到事件:"+event.getClass());
}
}
主測試類:
package com.zhihao.miao;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(Application.class);
//配置事件監(jiān)聽器
application.addListeners(new MyApplicationListener());
ConfigurableApplicationContext context =application.run(args);
//發(fā)布事件
context.publishEvent(new MyApplicationEvent(new Object()));
context.close();
}
}
打印結(jié)果:
總結(jié):
springboot事件監(jiān)聽的流程:
- 自定義事件,一般是繼承ApplicationEvent抽象類垃环。
- 定義事件監(jiān)聽器军浆,一般是實現(xiàn)ApplicationListener接口坯门。
- 配置監(jiān)聽器微饥,啟動的時候,需要把監(jiān)聽器加入到spring容器中古戴。
- 發(fā)布事件欠橘。
其中第三步(將監(jiān)聽器納入到spring容器)除了上面的方法之外,
application.addListeners(new MyApplicationListener());
還有三種方法
第二種方式
直接在MyApplicationListener類上加上@Component注解现恼,納入spring容器管理
package com.zhihao.miao;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Component
public class MyApplicationListener implements ApplicationListener<MyApplicationEvent> {
public void onApplicationEvent(MyApplicationEvent event) {
System.out.println("接收到事件:"+event.getClass());
}
}
主類測試:
package com.zhihao.miao;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(Application.class);
ConfigurableApplicationContext context =application.run(args);
//發(fā)布事件
context.publishEvent(new MyApplicationEvent(new Object()));
context.close();
}
}
第三種方式
在配置文件中配置
context.listener.classes=com.zhihao.miao.MyApplicationListener
源碼分析:
進入DelegatingApplicationListener類中的onApplicationEvent方法肃续,getListeners是獲取當前項目中的所有事件監(jiān)聽器。
第四種方式
使用@EventListener注解
package com.zhihao.miao;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class MyEventHandle {
/**
* 參數(shù)任意(為Object)的時候所有事件都會監(jiān)聽到
* 所有述暂,該參數(shù)事件痹升,或者其子事件(子類)都可以接收到
*/
@EventListener
public void event(Object event){
System.out.println("MyEventHandle 接收到事件:" + event.getClass());
}
}
主類測試:
package com.zhihao.miao;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(Application.class);
ConfigurableApplicationContext context =application.run(args);
//發(fā)布事件
context.publishEvent(new MyApplicationEvent(new Object()));
context.close();
}
}
打印結(jié)果:
源碼分析:
進入@EventListener注解,文檔說明中處理@EventListener是依靠EventListenerMethodProcessorbean畦韭,然后進入EventListenerMethodProcessorbean中疼蛾,我們大概看一下流程,可以自己調(diào)試
總結(jié):
配置事件監(jiān)聽器的四種方法
- SpringApplication.addListeners 添加監(jiān)聽器
- 把監(jiān)聽器納入到spring容器中管理
- 使用context.listener.classes配置項配置(詳細內(nèi)容參照:DelegatingApplicationListener)
- 使用@EventListener注解艺配,在方法上面加入@EventListener注解察郁,且該類需要納入到spring容器中管理(詳細內(nèi)容參照:EventListenerMethodProcessor衍慎,EventListenerFactory)
spring及springboot已經(jīng)定義好的事件
spring的事件
springboot的事件
測試一下spring自帶的事件:
@Component
public class MyEventHandle {
/**
* 監(jiān)聽spring的事件(運用停止事件,Application.stop()方法時候監(jiān)聽到。
*
*/
@EventListener
public void eventStop(ContextStoppedEvent event){
System.out.println("應用停止事件==========:"+event.getClass());
}
}
主類測試:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class,args);
context.stop();
}
}
測試: