概述
监听器,可以类比一下现实生活中的监听器:
现实中的监听器:
被监听对象:明星艺人
被监听事件:吸毒嫖娼
监听者:朝阳人民群众
触发事件:报警
web中的监听器:
被监听对象:ServletContext
被监听事件:该对象的创建、销毁
监听者:自己编写一个监听器
触发事件:调用监听器里面的对应代码
web中的监听器一共可以分为三大类8种:
- 三个域对象创建、销毁的监听器 ServletContextListener(Spring的入口)
- 三个域对象属性变更的监听器
- session数据钝化、活化的监听器
ServletContextListener的使用
- 编写一个类实现ServletContextListener接口
- 用注解申明@WebListener
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("context init");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("context destroy");
}
}
Listener的实现原理
tomcat的代码是很多年以前已经写好的,它是如何调用后面你写得代码呢?
先看一个案例:
宝宝哭的时候,爸爸妈妈要做出响应。
如果新加进来了爷爷奶奶,那爸爸妈妈爷爷奶奶都要做出响应。
我们现在要做到,当有新人物假如进来的时候不改变宝宝类中的代码,要怎么办呢?
首先,定义一个接口Relationship,在接口中定义一个action()方法

然后,在宝宝类中维护一个实现了Relationship接口的集合,每当有新成员加入,就把新成员加入集合里
这样,每当宝宝cry()就调用所有成员的action()方法
代码如下:
package test.update;
public class BabyTest {
public static void main(String[] args) {
Baby baby = new Baby();
// baby.addRelationShip(new Dad());
// baby.addRelationShip(new Mom());
baby.addRelationShip(new GrandPa());
baby.addRelationShip(new GrandMa());
baby.cry();
}
}
package test.update;
import java.util.ArrayList;
import java.util.List;
public class Baby {
private List<RelationShip> relations = new ArrayList<>();
public void addRelationShip(RelationShip relationShip){
this.relations.add(relationShip);
}
public void cry(){
for (RelationShip relation : relations) {
relation.action();
}
}
}
这其实就是观察者设计模式。
对应Listener:
- Relationship接口就相当于ServletContextListener接口
- Dad、Mom就相当于MyServletContextListener
- Baby就相当于ServletContext
ServletContext每次创建和销毁都会调用实现了ServletContextListener接口的类的对象的相应代码。

本文通过生动的类比,介绍了Web应用中的监听器概念及其应用场景,特别是ServletContextListener的使用方法,并探讨了监听器背后的实现原理。
971

被折叠的 条评论
为什么被折叠?



