web.xml中四种配置参数的执行顺序是:context-param ---> Listener ---> Filter ---> Servlet;
1. web容器首先会读取位于web.xml中的两个节点<context-param>和<listener>;
2. 然后去创建一个ServletContext上下文,被所有的组件共享;
3. 将web.xml中配置的<context-param>转化为键值对,存放于servletContext中;
4. web容器负责实例化监听器并注册监听器以用来监听各种事件,由于可以配置多个监听器,所以监听器本身的注册及执行也是有顺序的:
web容器是根据监听器实现的接口以及在web.xml中的顺序注册的,在web应用程序执行的时候,监听器执行的顺序和它们的注册顺序是一致的;在容器关闭的时候,监听器是按照和注册顺序相反的顺序被通知调用;监听器可以按照如下进行分类:
Object
Event
Listener Interface and Event Class
Web context |
Initialization and destruction |
javax.servlet.ServletContextListener and ServletContextEvent |
Attribute added, removed, or replaced |
javax.servlet.ServletContextAttributeListener and ServletContextAttributeEvent |
|
Session |
Creation, invalidation, activation, passivation, and timeout |
javax.servlet.http.HttpSessionListener , javax.servlet.http.HttpSessionActivationListener , and HttpSessionEvent |
Attribute added, removed, or replaced |
javax.servlet.http.HttpSessionAttributeListener and HttpSessionBindingEvent |
|
Request |
A servlet request has started being processed by web components |
javax.servlet.ServletRequestListener and ServletRequestEvent |
Attribute added, removed, or replaced |
javax.servlet.ServletRequestAttributeListener and ServletRequestAttributeEvent |
监听器是设计模式中观察者模式的一种应用,容器维护了对某种事件的一个监听器列表,当事 件被触发的时侯,响应的监听器就会被按一定的顺序调用. Spring中的ContextLoaderListener实现了ServletContextListener,在ServletContext初始 化的时候,就会去初始化webapplicationcontext,从而完成spring IOC中bean的注册;
5. web容器通过调用Filter的init方法初始化Filter,Filter主要用于在请求被处理之前和之后拦截并作出响应;Filter可以通 过<filter-mapping>对特定的资源进行处理;当一个请求到来时,针对某种资源的filter会被组织成一个 filterChain,filter可以通过调用filterChanin.dofilter()调用后面的filter;如果在一个filter的 doFilter方法中调用filterChain.doFilter(),那么filterChian.doFilter()之后的代码将会在 response返回的时候才会被执行;如下段代码,当程序进入到filterChain.doFilter(request, response)时,下一个filter的doFilter方法会被调用,如果下一个filter的doFilter方法中也有 filterChain.doFilter(request, response),将会继续对下下一个filter的doFilter方法,直到针对当前请求的最后一个filter,然后进入Servlet进行应用 逻辑的处理,待处理结束后,会按照刚才调用filter相反的顺序逐一执行filterChain.doFilter(request, response)之后的代码.
以下是在我的应用程序中的输出:
6. 在filterChain中的filter方法执行完毕的时候,相应的servlet会被调用,sevlet可以通过<servlet- mapping>进行配置使其对特定的url进行处理;在sevlet处理完成后,应用程序可能会再次进入filter,执行某个filter内 doFilter()方法中filterChain.doFilter()之后的代码.