ApplicationListener是Spring事件機(jī)制的一部分,與抽象類ApplicationEvent類配合來完成ApplicationContext的事件機(jī)制。
如果容器中存在ApplicationListener的Bean,當(dāng)ApplicationContext調(diào)用publishEvent方法時(shí),對(duì)應(yīng)的Bean會(huì)被觸發(fā)。這一過程是典型的觀察者模式的實(shí)現(xiàn)。
// 使用applicationListener監(jiān)聽ContextRefreshedEvent事件
// 需對(duì)該監(jiān)聽類進(jìn)行Bean的實(shí)例化
@Component
public class ContentListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
// 打印容器中出事Bean的數(shù)量
System.out.println("監(jiān)聽器獲得容器中初始化Bean數(shù)量:" + event.getApplicationContext().getBeanDefinitionCount());
}
}
控制臺(tái)輸出:
監(jiān)聽器獲得容器中初始化Bean數(shù)量:127
如果在實(shí)現(xiàn)ApplicationListener接口時(shí)不寫入event 則會(huì)堅(jiān)挺到所有事件
@Component
public class AllListener implements ApplicationListener {
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("監(jiān)聽到事件,"+event);
}
}
控制臺(tái)輸出:
監(jiān)聽到事件,org.springframework.boot.web.servlet.context.ServletWebServerInitializedEvent[source=org.springframework.boot.web.embedded.tomcat.TomcatWebServer@71a06021]
監(jiān)聽到事件,org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@3b96c42e, started on Sat Dec 11 17:48:29 CST 2021]
如果要自定義event 需要實(shí)現(xiàn)抽象類ApplicationEvent
// 自定義事件
public class UserLoginEvent extends ApplicationEvent {
private String id;
private String userName;
private String phone;
/**
* Create a new {@code ApplicationEvent}.
*
* @param source the object on which the event initially occurred or with
* which the event is associated (never {@code null})
*/
public UserLoginEvent(Object source) {
super(source);
}
public UserLoginEvent(Object source, String id, String userName, String phone) {
super(source);
this.id = id;
this.userName = userName;
this.phone = phone;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@Override
public String toString() {
return "UserLoginEvent{" +
"id='" + id + '\'' +
", userName='" + userName + '\'' +
", phone='" + phone + '\'' +
'}';
}
}
// 監(jiān)聽
@Component
public class UserLoginListener implements ApplicationListener<UserLoginEvent> {
@Override
public void onApplicationEvent(UserLoginEvent event) {
System.out.println("用戶登錄事件觸發(fā)");
System.out.println(event);
System.out.println("執(zhí)行通知");
}
}
// 觸發(fā)事件
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private ApplicationContext applicationContext;
@RequestMapping("/login")
public String login(){
String username = "kim";
String id = "000010";
String phone = "188****8778";
UserLoginEvent userLoginEvent = new UserLoginEvent("loginEvent",username,id,phone);
applicationContext.publishEvent(userLoginEvent);
return "登錄成功";
}
}
調(diào)用http://localhost:8080/user/login 控制臺(tái)輸出
用戶登錄事件觸發(fā)
UserLoginEvent{id='kim', userName='000010', phone='188****8778'}
執(zhí)行通知
以上方式是通過實(shí)現(xiàn)ApplicationListener接口實(shí)現(xiàn)監(jiān)聽,同時(shí)spring還提供了@EventListener注解用于對(duì)事件進(jìn)行監(jiān)聽 如下代碼效果同實(shí)現(xiàn)ApplicationListener相同
@Component
public class ListenerConfiguration {
@EventListener
public void UserLoginListener(UserLoginEvent event){
System.out.println("用戶登錄事件觸發(fā),基于注解");
System.out.println(event);
System.out.println("執(zhí)行通知,基于注解");
}
}