1.深入web.xml
Part1
p1首先tomcat启动的话,首先会去访问web.xml,读取到两个节点 <listener></listener> 和 <context-param></context-param>。
Part2
接着容器会创建一个ServletContext(上下文),整个WEB项目共享这个上下文。
Part3
接着容器会将读取到<context-param>转化为键值对,并交给ServletContext。
Part4
容器创建<listener></listener>中的类实例,即创建监听(备注:listener定义的类可以是自定义的类但必须需要实现ServletContextListener)。
Part5
注明一下web.xml加载顺序 context-param -> listener -> filter -> servlet
2.我们以springmvc为例作深入叙述
Part1
加载spring的配置文件
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
我们来仔细看看,ContextLoaderListener这个监听到是干嘛的?
package org.springframework.web.context;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
public ContextLoaderListener() {
}
public ContextLoaderListener(WebApplicationContext context) {
super(context);
}
@Override
public void contextInitialized(ServletContextEvent event) {
initWebApplicationContext(event.getServletContext());
}
@Override
public void contextDestroyed(ServletContextEvent event) {
closeWebApplicationContext(event.getServletContext());
ContextCleanupListener.cleanupAttributes(event.getServletContext());
}
}
从源码不难看出,ContextLoaderListener 继承于ContextLoader并且实现了ServletContextListener ,
ServletContextListener 是ServletContext的监听器,那么我们是不是就不用加上ContextLoaderListener这个监听器呢?答案是肯定的。我们可以不需要利用这ContextLoaderListener 作为监听器,那么用跟不用有啥区别呢?答案就是假如不使用ContextLoaderListener ,我们就没法使用WebApplicationContext,
再往下探究,WebApplicationContext到底是个啥?
WebApplicationContext是实现ApplicationContext接口的子类。是专门为WEB应用准备的。
- 它允许从相对于Web根目录的路径中加载配置文件完成初始化工作。从WebApplicationContext中可以获取ServletContext引用,整个Web应用上下文对象将作为属性放置在ServletContext中,以便Web应用环境可以访问Spring上下文。例如通过类或者名字获取ioc容器中的bean对象。
2.WebApplicationContext还为bean提供了三个新的作用域,request、session和globalsession。
其中两个参数HttpServletRequest:服务器从客户端拿去数据 HttpServletResponse:服务器向前台传送数据
可想而知我们平时都使用了到这两个参数,所以一般我们都会加上这个配置。
Part2
接下来我们可以自定自己的监听器。
<listener>
<listener-class>org.yick.exam.listener.ExamInitListener</listener-class>
</listener>
package org.yick.exam.listener;
import javax.servlet.ServletContextEvent;
import org.springframework.web.context.ContextLoaderListener;
import org.yick.exam.common.LogPrinter;
public class ExamInitListener extends ContextLoaderListener {
@Override
public void contextInitialized(ServletContextEvent event) {
super.contextInitialized(event);
LogPrinter.print("作者 :" + super.getCurrentWebApplicationContext().getServletContext().getInitParameter("author"));
LogPrinter.print("项目 :" + super.getCurrentWebApplicationContext().getServletContext().getInitParameter("project"));
}
@Override
public void contextDestroyed(ServletContextEvent event) {
super.contextDestroyed(event);
}
}
这个监听器做了很简单的一个操作,就是继承了ContextLoaderListener,里面既可以实现自己需要初始化的对象或者一些功能以外,还可以轻松的实现了WebApplicationContext的初始化。
下一章继续讲。。。