1. 事件监听器
在事件源上发生某个变动事件的时候,触发实现了特定接口的程序,通过该接口,可以从变动事件上拿到事件源,从而对事件源上的操作进行处理。
在这个体系中,有三个主体,事件源、事件本身、事件监听器
以 ServletContext 为例
事件源:ServletContext,在 Context 创建或者销毁的时候,会出发 ServletContextEvent 事件
事件:ServletContextEvent,getServletContext 获取到 ServletContext
事件监听器:ServletContextListener,接受 ServletContextEvent,可以获取到 ServletContext 进行处理
2. servlet 中的 Listener
2.1 ServletContextListener
在 ServletContext 创建和销毁的时候触发,调用 contextInitialized、contextDestroyed,多被框架类实现,用于在启动 web 工程的时候加入框架所需的处理
2.2 ServletContextAttributeListener
若有对象加入为 application (ServletContext) 对象的属性,则会调用 attributeAdded,同理在置换属性与移除属性时,会分别调用 attributeReplaced、attributeRemoved
2.3 ServletRequestListener
在 Request (HttpServletRequest) 对象创建或被销毁时,调用 requestInitialized、requestDestroyed
2.4 ServletRequestAttributeListener
若有对象加入为 Request (HttpServletRequest) 对象的属性,则会调用 attributeAdded,同理在置换属性与移除属性时,会分别调用 attributeReplaced、 attributeRemoved
2.5 HttpSessionListener
在 Session (HttpSession) 对象建立或被消灭时,会分别调用 sessionCreated、sessionDestroyed
2.6 HttpSessionAttributeListener
若有对象加入为 Session (HttpSession) 对象的属性,则会调用 attributeAdded,同理在置换属性与移除属性时,会分别调用 attributeReplaced、 attributeRemoved
2.7 HttpSessionActivationListener
Activate 与 Passivate 是用于置换对象的动作,当 Session 对象为了资源利用或负载平衡等原因而必须暂时储存至硬盘或其它储存器时(透过对象序列化),所作的动作称之为 Passivate,而硬盘或储存器上的Session 对象重新加载JVM时所采的动作称之为 Activate,所以容易理解的,sessionDidActivate 与 sessionWillPassivate 分别于 Activeate 后与将 Passivate 前调用
2.8 HttpSessionBindingListener
HttpSessionBindingListener 与其他的监听器不同,HttpSessionListener 只需要设置到 web.xml 中就可以监听整个应用中的所有session,HttpSessionBindingListener必须实例化后放入某一个session中,才可以进行监听,而且只能一对一的监听。实现 HttpSessionBindingListener 接口的对象被绑定到 Session 时调用 valueBound,解除绑定时调用 valueUnbound
3. web 工程中的 Listener
<context-param> <param-name>log4jConfigLocation</param-name> <param-value>/WEB-INF/log4j.properties</param-value> </context-param> <context-param> <param-name>log4jRefreshInterval</param-name> <param-value>60000</param-value> </context-param> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:coffeeTest-application.xml </param-value> </context-param> <listener> <listener-class> org.springframework.web.util.Log4jConfigListener </listener-class> </listener> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener>
3.1 初始化 Log4j 日志配置
Log4jConfigListener 用于启动 Log4j 日志,log4jConfigLocation 表示日志配置文件的路径,log4jRefreshInterval 为6000表示开一条 watchdog 线程每6秒扫描一下配置文件的变化
使用 Log4jConfigListener 最大的好处就是动态的改变记录级别和策略,不需要重启Web应用
这种动态的实现逻辑,规定一个具体配置文件,用一个线程每隔一段时间去取这个文件的最后修改时间,和上一次取的最后修改时间比较,如果大于,则重新加载这个配置文件
帖几段代码
class XMLWatchdog extends FileWatchdog {
XMLWatchdog(String filename) {
super(filename);
}
/**
Call {@link DOMConfigurator#configure(String)} with the
<code>filename</code> to reconfigure log4j. */
public void doOnChange() {
new DOMConfigurator().doConfigure(filename,
LogManager.getLoggerRepository());
}
}
FileWatchdog
protected void checkAndConfigure() {
boolean fileExists;
try {
fileExists = file.exists();
} catch(SecurityException e) {
LogLog.warn("Was not allowed to read check file existance, file:["+
filename+"].");
interrupted = true; // there is no point in continuing
return;
}
if(fileExists) {
long l = file.lastModified(); // this can also throw a SecurityException
if(l > lastModif) { // however, if we reached this point this
lastModif = l; // is very unlikely.
doOnChange();
warnedAlready = false;
}
} else {
if(!warnedAlready) {
LogLog.debug("["+filename+"] does not exist.");
warnedAlready = true;
}
}
}
3.2 初始化 spring 配置
ContextLoaderListener 的主要作用是在启动 Web 容器时,自动装配 Spring applicationContext.xml 的配置信息。其主要逻辑也是从 contextConfigLocation 处加载 spring 的配置文件,创建 spring 容器!具体的分析,待 spring 分析的时候再写吧!