如题,本篇我们介绍下spring事件监听以及自定义事件。
事件是spring中非常重要的一种异步通知机制,在spring框架中就内置了容器事件,如ContextStartedEvent(启动) 、ContextStoppedEvent(停止)、ContextRefreshedEvent(刷新)、ContextClosedEvent(关闭),它们都继承自ApplicationEvent对象,我们编写的事件监听器类时需要实现ApplicationListener 接口,然后重写onApplicationEvent(event)方法即可。
注意 :ContextStartedEvent、ContextStoppedEvent 这两种事件监听器,笔者在实际中配置了后好像并不起作用,我们可以用ContextRefreshedEvent、ContextClosedEvent分别代替代替前面二者。
当然除了上面的几种,我们还可以自定义事件,以及自定义事件处理器。
SpringStartedListener.java
package com.tingcream.springWeb.spring.eventListener;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStartedEvent;
import org.springframework.stereotype.Component;
@Component
public class SpringStartedListener implements ApplicationListener{
@Override
public void onApplicationEvent(ContextStartedEvent event) {
System.out.println("============SpringStartedListener 执行=========== ");
}
}
SpringStoppedListener.java
package com.tingcream.springWeb.spring.eventListener;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStoppedEvent;
import org.springframework.stereotype.Component;
@Component
public class SpringStoppedListener implements ApplicationListener{
@Override
public void onApplicationEvent(ContextStoppedEvent event) {
System.out.println("============SpringStoppedListener 执行=========== ");
}
}
SpringRefreshedListener.java
package com.tingcream.springWeb.spring.eventListener;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import com.tingcream.springWeb.common.SpringContextHelper;
import com.tingcream.springWeb.spring.event.MyAppEvent;
@Component
public class SpringRefreshedListener implements ApplicationListener{
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
System.out.println("============SpringRefreshedListener 执行=========== ");
}
}
SpringClosedListener.java
package com.tingcream.springWeb.spring.eventListener;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.stereotype.Component;
@Component
public class SpringClosedListener implements ApplicationListener{
@Override
public void onApplicationEvent(ContextClosedEvent event) {
System.out.println("============SpringClosedListener 执行=========== ");
}
}
1、编写自定义事件类
MyAppEvent.java
package com.tingcream.springWeb.spring.event;
import org.springframework.context.ApplicationEvent;
/**
* 自定义事件对象
* @author jelly
*
*/
public class MyAppEvent extends ApplicationEvent{
private static final long serialVersionUID = 1L;
public MyAppEvent(Object source) {
super(source);
}
}
2、编写自定义事件监听器
MyAppEventListener.java
package com.tingcream.springWeb.spring.eventListener;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import com.tingcream.springWeb.spring.event.MyAppEvent;
/**
* 自定义事件MyAppEvent的监听器
* @author jelly
*
*/
@Component
public class MyAppEventListener implements ApplicationListener{
@Override
public void onApplicationEvent(MyAppEvent event) {
System.out.println("MyAppEventListener监听到MyAppEvent事件发生");
System.out.println("事件source:"+event.getSource());//时间源对象
System.out.println("事件timestamp:"+event.getTimestamp());
System.out.println("事件class:"+event.getClass());
}
}
3、在spring容器中触发自定义事件
这里笔者是在spring容器启动(刷新)时自动触发一次该事件,当然实际业务中应当是在完成某个操作或任务后,在适当的时机触发该事件,如消息推送、日志通知等场景。
SpringRefreshedListener.java
package com.tingcream.springWeb.spring.eventListener;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import com.tingcream.springWeb.common.SpringContextHelper;
import com.tingcream.springWeb.spring.event.MyAppEvent;
@Component
public class SpringRefreshedListener implements ApplicationListener{
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
System.out.println("============SpringRefreshedListener 执行=========== ");
SpringContextHelper.getApplicationContext().publishEvent(new MyAppEvent("这是一段事件消息"));
}
}
SpringContextHelper.java
package com.tingcream.springWeb.common;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* Spring 容器上下文辅助类
* @author jelly
*
*/
@Component
public class SpringContextHelper implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
SpringContextHelper.applicationContext = applicationContext;
}
/**
* 获取spring容器的 applicationContext 上下文对象
* @return
*/
public static ApplicationContext getApplicationContext(){
return applicationContext;
}
public static Object getBean(String name){
return applicationContext.getBean(name);
}
/**
* 从spring 上下文中获取bean
* @param name
* @param requiredClass
* @return
*/
public static T getBean(String name, Class requiredClass){
return applicationContext.getBean(name, requiredClass);
}
public static T getBean(Class requiredType){
return applicationContext.getBean(requiredType);
}
}
--------------------
注: 事件监听的处理除了采用XxxListener方式,还可以XxxHandler的方式,在handler中使用@EventListener标记方法为一个事件处理的方法即可。Listner和Handler只能选用其中一种方式,若两种方式在项目中都存在,在Listener方式生效,Handler方式无效。例如,上面的spring容器的4种内置事件监听器类可以写到一个handler类中。
SpringContextEventHandler.java
package com.tingcream.springWeb.spring.eventListener;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.ContextStartedEvent;
import org.springframework.context.event.ContextStoppedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import com.tingcream.springWeb.common.SpringContextHelper;
import com.tingcream.springWeb.spring.event.MyAppEvent;
@Component
public class SpringContextEventHandler {
@EventListener
public void stopped(ContextStoppedEvent event){
System.out.println("SpringContextEventHandler stopped执行");
}
@EventListener
public void started(ContextStartedEvent event){
System.out.println("SpringContextEventHandler started执行");
}
@EventListener
public void refreshed(ContextRefreshedEvent event){
System.out.println("SpringContextEventHandler refreshed执行");
SpringContextHelper.getApplicationContext().publishEvent(new MyAppEvent("这是一段事件消息"));
}
@EventListener
public void closed(ContextClosedEvent event){
System.out.println("SpringContextEventHandler closed执行");
}
}