在走读Java Servlet源码前,我的思路是有些混乱的,没有计划也不知道从哪里读起,所以直接选了Servlet接口作为突破口,但实际上选择Listener-Filter-Servlet-Request这条路线去走读源码,逻辑上会更清晰一点,因为它和web中信息流动的路线是一致的,也有助于回答我在上一篇Java Servlet源码走读一:Servlet接口中最后遗留的问题:web容器是在什么时候,如何去调用Servlet的方法的?
当然,在意识到思路混乱后,我首先将servlet3.1的规范文档通读了一遍,也是通过规范文档,我大致了解了应当从哪里作为突破口去更好的走读Servlet源码
Listener的定义
Listener一般翻译为监听器,所有的Listener接口都需要继承java.util.EventListener
接口,用于监听Servlet中发生的关键事件并进行处理。
在Servlet中定义了3类Listener:
- Servlet上下文事件(2个Listener接口):
- Http会话事件(5个Listener接口):
- Servlet请求事件(3个Listener接口):
选了3个监听器接口的定义源码,大致了解下定义了哪些接口,后面去看具体的实现类的时候,不至于一抹黑便可
ServletRequestListener
/**
* A ServletRequestListener can be implemented by the developer
* interested in being notified of requests coming in and out of
* scope in a web component. A request is defined as coming into
* scope when it is about to enter the first servlet or filter
* in each web application, as going out of scope when it exits
* the last servlet or the first filter in the chain.
*
* @since Servlet 2.4
*/
public interface ServletRequestListener extends EventListener {
/**
* The request is about to go out of scope of the web application.
* @param sre Information about the request
*/
public void requestDestroyed (ServletRequestEvent sre);
/**
* The request is about to come into scope of the web application.
* @param sre Information about the request
*/
public void requestInitialized (ServletRequestEvent sre);
}
注释已经讲解的很明白了,通过实现ServletRequestListener
接口可以监听到请求进/出事件
定义了2个回调接口:
requestDestroyed
:request从web应用中返回的时候调用
requestInitialized
:request进入web应用中的时候调用
ServletContextListener
/**
* Implementations of this interface receive notifications about changes to the
* servlet context of the web application they are part of. To receive
* notification events, the implementation class must be configured in the
* deployment descriptor for the web application.
*
* @see ServletContextEvent
* @since v 2.3
*/
public interface ServletContextListener extends EventListener {
/**
** Notification that the web application initialization process is starting.
* All ServletContextListeners are notified of context initialization before
* any filter or servlet in the web application is initialized.
* @param sce Information about the ServletContext that was initialized
*/
public void contextInitialized(ServletContextEvent sce);
/**
** Notification that the servlet context is about to be shut down. All
* servlets and filters have been destroy()ed before any
* ServletContextListeners are notified of context destruction.
* @param sce Information about the ServletContext that was destroyed
*/
public void contextDestroyed(ServletContextEvent sce);
}
通过实现ServletContextListener
接口可以监听到Servlet上下文初始化和销毁事件
定义了2个回调接口:
contextInitialized
:Servlet上下文初始化时调用
contextDestroyed
:Servlet上下文销毁时调用
HttpSessionListener
/**
* Implementations of this interface are notified of changes to the list of
* active sessions in a web application. To receive notification events, the
* implementation class must be configured in the deployment descriptor for the
* web application.
*
* @see HttpSessionEvent
* @since v 2.3
*/
public interface HttpSessionListener extends EventListener {
/**
* Notification that a session was created.
*
* @param se
* the notification event
*/
public void sessionCreated(HttpSessionEvent se);
/**
* Notification that a session is about to be invalidated.
*
* @param se
* the notification event
*/
public void sessionDestroyed(HttpSessionEvent se);
}
通过实现HttpSessionListener
接口可以监听到Servlet上下文初始化和销毁事件
定义了2个回调接口:
sessionCreated
:会话创建时调用
sessionDestroyed
:会话销毁时调用
总结:
1、用户可以通过自定义Listener实现对于Servlet的一些功能增强,比如在request进入web应用时候统一记录日志!
2、对于Servlet来说,它更多的是定义了一种规范(接口)告诉要使用Servlet的人如何去做,实际的处理是依赖具体实现类去做的(比如spring mvc里面大量对Servlet接口的扩展)
3、想完整的了解Servlet如何产生作用(也就是Servlet是如何初始化的,在什么时机初始化的,定义的方法是在什么时候调用的),需要了解Servlet容器比如tomcat的原理和机制(可以结合tomcat的一些书籍走读下源码)
网友评论