ContextLoaderListener和DispatcherServlet都会在Web容器启动的时候加载一下bean配置. 区别在于:

  DispatcherServlet一般会加载MVC相关的bean配置管理(如: ViewResolver, Controller, MultipartResolver, ExceptionHandler, etc.)

  ContextLoaderListener一般会加载整个Spring容器相关的bean配置管理(如: Log, Service, Dao, PropertiesLoader, DataSource Bean, etc.)

ContextLoaderListener继承ContextLoader类,实现ServletContextListener接口(该接口监听servlet容器的启动和销毁),ContextLoaderListener重写了监听容器启动和销毁的方法,在启动时(contextInitialized),会调用initWebApplicationContext方法,进行web容器初始化。

	/**
* Initialize the root web application context.
*/
@Override
public void contextInitialized(ServletContextEvent event) {
initWebApplicationContext(event.getServletContext());
} /**
* Close the root web application context.
*/
@Override
public void contextDestroyed(ServletContextEvent event) {
closeWebApplicationContext(event.getServletContext());
ContextCleanupListener.cleanupAttributes(event.getServletContext());
}

在initWebApplicationContext方法时父类contextloader内的方法(精简):

在方法内回调用createWebApplicationContext()创建容器,该容器回根据spring内部的配置文件创建,最后强制为ConfigurableWebApplicationContext对象

	public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
throw new IllegalStateException(
"Cannot initialize context because there is already a root application context present - " +
"check whether you have multiple ContextLoader* definitions in your web.xml!");
}
try {
// Store context in local instance variable, to guarantee that
// it is available on ServletContext shutdown.
if (this.context == null) {
this.context = createWebApplicationContext(servletContext);//ConfigurableWebApplicationContext类型对象
}
if (this.context instanceof ConfigurableWebApplicationContext) {//进行初始化操作
ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;
if (!cwac.isActive()) {
// The context has not yet been refreshed -> provide services such as
// setting the parent context, setting the application context id, etc
if (cwac.getParent() == null) {
// The context instance was injected without an explicit parent ->
// determine parent for root web application context, if any.
ApplicationContext parent = loadParentContext(servletContext);
cwac.setParent(parent);
}
configureAndRefreshWebApplicationContext(cwac, servletContext);//真正初始化,在该方法内部有refresh()方法,在方法回调用ConfigurableWebApplicationContext父类的refresh()方法进行容器初始化
                                                            //也就是AbstractApplicationContext类中的refresh()方法
}
}
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); return this.context;
} }
    protected WebApplicationContext createWebApplicationContext(ServletContext sc) {
Class<?> contextClass = determineContextClass(sc);
if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
throw new ApplicationContextException("Custom context class [" + contextClass.getName() +
"] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]");
}
return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
}
    protected Class<?> determineContextClass(ServletContext servletContext) {
String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM);
if (contextClassName != null) {
try {
return ClassUtils.forName(contextClassName, ClassUtils.getDefaultClassLoader());
}
catch (ClassNotFoundException ex) {
throw new ApplicationContextException(
"Failed to load custom context class [" + contextClassName + "]", ex);
}
}
else {
contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName());
try {//通过反射得到一个class对象
return ClassUtils.forName(contextClassName, ContextLoader.class.getClassLoader());
}
catch (ClassNotFoundException ex) {
throw new ApplicationContextException(
"Failed to load default context class [" + contextClassName + "]", ex);
}
}
}

DispatcherServlet本质是一个servlet,能够拦截请求

servlet会有初始化init,同dispatcherservlet,会进行一些初始化操作:

    protected void initStrategies(ApplicationContext context) {

      //初始化多部请求解析器,没有默认的实现
      initMultipartResolver(context); //文件上传
      //初始化地域解析器,默认实现是AcceptHeaderLocaleResolver
      initLocaleResolver(context);
      //初始化主题解析器,默认实现是FixedThemeResolver
      initThemeResolver(context);
      //初始化处理器映射,这是个集合, 默认实现是BeanNameUrlHandlerMapping和DefaultAnnotationHandlerMapping
      initHandlerMappings(context);
      //初始化处理器适配器,这是个集合,默认实现是HttpRequestHandlerAdapter,SimpleControllerHandlerAdapter和AnnotationMethodHandlerAdapter
      initHandlerAdapters(context);
      //初始化处理器异常解析器,这是个集合,默认实现是AnnotationMethodHandlerExceptionResolver,ResponseStatusExceptionResolver和DefaultHandlerExceptionResolver
      initHandlerExceptionResolvers(context);
      //初始化请求到视图名解析器,默认实现是DefaultRequestToViewNameTranslator
      initRequestToViewNameTranslator(context);
      //初始化视图解析器,这是个集合,默认实现是InternalResourceViewResolver
      initViewResolvers(context);

}

web.xml中的ContextLoaderListener和DispatcherServlet区别的更多相关文章

  1. web.xml中:<context-param>与<init-param>的区别与作用及获取方法

    <context-param>的作用: web.xml的配置中<context-param>配置作用1. 启动一个WEB项目的时候,容器(如:Tomcat)会去读它的配置文件w ...

  2. 在web.xml中classpath和classpath*的区别

    classpath 和 classpath* 区别: classpath:只会到你指定的class路径中查找找文件; classpath*:不仅包含class路径,还包括jar文件中(class路径) ...

  3. web.xml 中<context-param>与<init-param>的区别与作用

    <context-param>的作用: web.xml的配置中<context-param>配置作用 1. 启动一个WEB项目的时候,容器(如:Tomcat)会去读它的配置文件 ...

  4. web.xml中classpath*:与classpath:的区别

    classpath对应src目录,该目录下的文件会在编译后被存放到WEB-INF文件夹下的classes目录. classpath:只会到你的class路径中查找配置文件,对于多个同名的配置文件,只会 ...

  5. 关于jsp web项目,jsp页面与servlet数据不同步的解决办法(报错404、405等)即访问.jsp和访问web.xml中注册的/servlet/的区别

    报错信息: Type Status Report Message HTTP method GET is not supported by this URL Description The method ...

  6. Web.xml中自动扫描Spring的配置文件及resource时classpath*:与classpath:的区别

    Web.xml中自动扫描Spring的配置文件及resource时classpath*:与classpath:的区别 一.Web.xml中自动扫描Spring的配置文件(applicationCont ...

  7. SpringMVC(十六):如何使用编程方式替代/WEB-INF/web.xml中的配置信息

    在构建springmvc+mybatis项目时,更常用的方式是采用web.xml来配置,而且一般情况下会在web.xml中使用ContextLoaderListener加载applicationCon ...

  8. SpringMVC: web.xml中声明DispatcherServlet时一定要加入load-on-startup标签

    游历SpringMVC源代码后发现,在web.xml中注冊的ContextLoaderListener监听器不过初始化了一个根上下文,只完毕了组件扫描和与容器初始化相关的一些工作,并没有探測到详细每一 ...

  9. SpringMVC: web.xml中声明DispatcherServlet时一定要添加load-on-startup标签

    游历SpringMVC源码后发现,在web.xml中注册的ContextLoaderListener监听器只是初始化了一个根上下文,仅仅完成了组件扫描和与容器初始化相关的一些工作,并没有探测到具体每个 ...

随机推荐

  1. pythonの信号量

    #!/usr/bin/env python import threading,time def run(n): # 申请锁 semaphore.acquire() time.sleep(1) prin ...

  2. 20165221 JAVA第二周学习心得及体会

    基本数据类型与数组理论学习 根据第二章的网课链接,归纳出以下板块: 知识框架 标识符与关键字 1.标识符 其本质是文件名字 标识符的第一个字符不能为数字,标识符不能为关键字(如inter) 标识符不能 ...

  3. [转] 一文弄懂神经网络中的反向传播法——BackPropagation

    在看CNN和RNN的相关算法TF实现,总感觉有些细枝末节理解不到位,浮在表面.那么就一点点扣细节吧. 这个作者讲方向传播也是没谁了,666- 原文地址:https://www.cnblogs.com/ ...

  4. nginx 配置域名转发

    自己测试环境,配置下载目录和一个jenkins的地址: 域名跳转,反向代理 # cat ../nginx.conf user www www; worker_processes ; error_log ...

  5. Centos下配置php环境

    Centos下配置php环境   目录[-] 环境: GD2 2 安装PHP 5.2.14(FastCGI模式) 1)编译安装PHP 5.2.14所需的支持库: 2)编译安装MySQL 5.5.3-m ...

  6. 【转】采用dlopen、dlsym、dlclose加载动态链接库

    1.前言 为了使程序方便扩展,具备通用性,可以采用插件形式.采用异步事件驱动模型,保证主控制逻辑不变,将各个业务以动态链接库的形式加载进来,这就是所谓的插件.linux提供了加载和处理动态链接库的系统 ...

  7. undefined reference to symbol '_ZNK11GenICam_3_016GenericException17GetSourceFileNameEv'

    今天在编译DALSA二次开发的源码时,出现了如下错误: /usr/bin/ld: ./out/camera.o: undefined reference to symbol '_ZNK11GenICa ...

  8. mysql 5.6 windows 启动脚本

    2018-4-25 17:02:08 星期三 下载mysql 5.6 zip(免安装版)到本机 一台电脑上可能装有多个版本的mysql, 启动时为了不影响: 1. 解压后文件夹根目录改名为 mysql ...

  9. Light OJ 1009

    题意: 给你一个二分图, (可能不连通) 求可能多的子集元素个数: 思路: 直接DFS 给二分图染色就有了, 统计联通块中个数, 去最大值相加即可. #include<bits/stdc++.h ...

  10. 用puttygen工具把私钥id_rsa转换成公钥id_rsa.ppk

    1 前言 有时候需要ppk格式的公钥,可以用putty来处理 2 步骤 1. 产生密钥 可以参考Gitlab的SSH配置(linux和windows双版本) $ ssh-keygen -t rsa - ...