Spring Boot系列: 点击查看Spring Boot系列文章
顾名思义,监听器就是用来监听某些事件,当事件发生某些情况的时候,我们就采取对应的行动。
下面是找的一个比较详细的解释
监听器,字面上的理解就是监听观察某个事件(程序)的发生情况,当被监听的事件真的发生了的时候,事件发生者(事件源) 就会给注册该事件的监听者(监听器)发送消息,告诉监听者某些信息,同时监听者也可以获得一份事件对象,根据这个对象可以获得相关属性和执行相关操作。
监听器涉及以下三个对象:
(1)事件:用户对组件的一个操作,或者说程序执行某个方法,称之为一个事件,如机器人程序执行工作。
(2)事件源:发生事件的组件就是事件源,也就是被监听的对象,如机器人可以工作,可以跳舞,那么就可以把机器人看做是一个事件源。
(3)事件监听器(处理器):监听并负责处理事件的方法,如监听机器人工作情况,在机器人工作前后做出相应的动作,或者获取机器人的状态信息。
对Request的监听有ServletRequestListener和ServletRequestAttributeListener。前者可见监听Request的创建和销毁;而后者可以对Request的属性进行监听。
对Session的监听有HttpSessionListener和HttpSessionAttributeListener。HttpSessionListener可以监听HttpSession的创建跟销毁,而HttpSessionAttributeListener则是对session中属性的监听,它可以监听到session新增属性、移除属性和属性值被替换时。
对于ServletContext的监听器有ServletContextListener和ServletContextAttributeListener。ServletContextListener可以监听到ServletContext的创建和销毁,而ServletContextAttributeListener可以监听到ServletContext中属性的新增、移除和属性值的替换。
HttpSessionListener源码
public interface HttpSessionListener extends EventListener {
default void sessionCreated(HttpSessionEvent se) {
}
default void sessionDestroyed(HttpSessionEvent se) {
}
}
sessionCreated表示监听session创建,当有session创建,该方法就会执行
sessionDestroyed表示监听session销毁,当有session销毁,该方法就会执行
比如,我们可以在session创建时候,设置一个属性给它
public void sessionCreated(HttpSessionEvent se) {
se.getSession().getServletContext().setAttribute("name","m");
}
ServletRequestListener 的源码
public interface ServletRequestListener extends EventListener {
default void requestDestroyed(ServletRequestEvent sre) {
}
default void requestInitialized(ServletRequestEvent sre) {
}
}
requestInitialized表示监听requst初始化,requestDestroyed表示监听request销毁
我们可以很容易在requestInitialized方法获取到请求的信息,和进行一些处理
@Override
public void requestInitialized(ServletRequestEvent sre) {
HttpServletRequest request= (HttpServletRequest) sre.getServletRequest();
//获取cookie
Cookie[] cookies = request.getCookies();
}
spring有一个自己的监听器,叫ApplicationListener,是专门用来监听ApplicationEvent的。自定义监听器只需要实现该接口即可
下面是我找到的一个关于ApplicationListener不错的介绍
ApplicationContext事件机制是观察者设计模式的实现,通过ApplicationEvent类和ApplicationListener接口,可以实现ApplicationContext事件处理。
如果容器中有一个ApplicationListener Bean,每当ApplicationContext发布ApplicationEvent时,ApplicationListener Bean将自动被触发。这种事件机制都必须需要程序显示的触发。
其中spring有一些内置的事件,当完成某种操作时会发出某些事件动作。比如监听ContextRefreshedEvent事件,当所有的bean都初始化完成并被成功装载后会触发该事件,实现ApplicationListener接口可以收到监听动作,然后可以写自己的逻辑。
同样事件可以自定义、监听也可以自定义,完全根据自己的业务逻辑来处理。
ApplicationListener源码,可以看到只有onApplicationEvent方法
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
/**
* Handle an application event.
* @param event the event to respond to
*/
void onApplicationEvent(E event);
}
onApplicationEvent表示在ApplicationEvent中,监听某事件,发生则触发该方法
自定义事件
所以我们首先需要自定义一个事件,自定义事件只需要继承ApplicationEvent,覆写构造方法即可
public class TestEvent extends ApplicationEvent {
private User user;
public TestEvent(Object source,User user) {
super(source);
System.out.println("自定义事件");
}
}
接下来,我们就用自定义监听器来监听该事件,需要使用@Component将监听器交给spring管理,这样监听器才能起作用
//指定事件类型,在ApplicationListener写入具体类型
@Component
public class TestListener implements ApplicationListener<TestEvent> {
@Override
public void onApplicationEvent(TestEvent event) {
//进行逻辑处理
User user = event.getUser();
System.out.println(user);
}
}
当然,我们也可以不指定类型,使用以下方法
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof TestEvent){
.....
}
}
发布事件
定义完事件和监听器后,我们还需要将事件发布,这样监听器才能监听到。发布事件使用的是applicationContext的publishEvent方法。
//我将事件发布放在一个Controller里,当有访问时,就会发布事件,当然我们可以根据自己的需求发布事件
@Controller
public class InterceptorTestController {
@Autowired
private ApplicationContext applicationContext;
@RequestMapping(value = { "/test/interceptor" })
@ResponseBody
public String interceptorTest() {
User user = new User();
// 发布事件
TestEvent event = new TestEvent(this, user);
applicationContext.publishEvent(event);
return "hello";
}
}
当我访问该接口,输出以下结果,监听成功