ApplicationListener是Spring事件机制的一部分,与抽象类ApplicationEvent类配合来完成ApplicationContext的事件机制。
如果容器中存在ApplicationListener的Bean,当ApplicationContext调用publishEvent方法时,对应的Bean会被触发。这一过程是典型的观察者模式的实现。
// 使用applicationListener监听ContextRefreshedEvent事件
// 需对该监听类进行Bean的实例化
@Component
public class ContentListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
// 打印容器中出事Bean的数量
System.out.println("监听器获得容器中初始化Bean数量:" + event.getApplicationContext().getBeanDefinitionCount());
}
}
控制台输出:
监听器获得容器中初始化Bean数量:127
如果在实现ApplicationListener接口时不写入event 则会坚挺到所有事件
@Component
public class AllListener implements ApplicationListener {
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("监听到事件,"+event);
}
}
控制台输出:
监听到事件,org.springframework.boot.web.servlet.context.ServletWebServerInitializedEvent[source=org.springframework.boot.web.embedded.tomcat.TomcatWebServer@71a06021]
监听到事件,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 需要实现抽象类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 + '\'' +
'}';
}
}
// 监听
@Component
public class UserLoginListener implements ApplicationListener<UserLoginEvent> {
@Override
public void onApplicationEvent(UserLoginEvent event) {
System.out.println("用户登录事件触发");
System.out.println(event);
System.out.println("执行通知");
}
}
// 触发事件
@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 "登录成功";
}
}
调用http://localhost:8080/user/login 控制台输出
用户登录事件触发
UserLoginEvent{id='kim', userName='000010', phone='188****8778'}
执行通知
以上方式是通过实现ApplicationListener接口实现监听,同时spring还提供了@EventListener注解用于对事件进行监听 如下代码效果同实现ApplicationListener相同
@Component
public class ListenerConfiguration {
@EventListener
public void UserLoginListener(UserLoginEvent event){
System.out.println("用户登录事件触发,基于注解");
System.out.println(event);
System.out.println("执行通知,基于注解");
}
}