web.xml中的ContextLoaderListener和DispatcherServlet区别
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区别的更多相关文章
- web.xml中:<context-param>与<init-param>的区别与作用及获取方法
<context-param>的作用: web.xml的配置中<context-param>配置作用1. 启动一个WEB项目的时候,容器(如:Tomcat)会去读它的配置文件w ...
- 在web.xml中classpath和classpath*的区别
classpath 和 classpath* 区别: classpath:只会到你指定的class路径中查找找文件; classpath*:不仅包含class路径,还包括jar文件中(class路径) ...
- web.xml 中<context-param>与<init-param>的区别与作用
<context-param>的作用: web.xml的配置中<context-param>配置作用 1. 启动一个WEB项目的时候,容器(如:Tomcat)会去读它的配置文件 ...
- web.xml中classpath*:与classpath:的区别
classpath对应src目录,该目录下的文件会在编译后被存放到WEB-INF文件夹下的classes目录. classpath:只会到你的class路径中查找配置文件,对于多个同名的配置文件,只会 ...
- 关于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 ...
- Web.xml中自动扫描Spring的配置文件及resource时classpath*:与classpath:的区别
Web.xml中自动扫描Spring的配置文件及resource时classpath*:与classpath:的区别 一.Web.xml中自动扫描Spring的配置文件(applicationCont ...
- SpringMVC(十六):如何使用编程方式替代/WEB-INF/web.xml中的配置信息
在构建springmvc+mybatis项目时,更常用的方式是采用web.xml来配置,而且一般情况下会在web.xml中使用ContextLoaderListener加载applicationCon ...
- SpringMVC: web.xml中声明DispatcherServlet时一定要加入load-on-startup标签
游历SpringMVC源代码后发现,在web.xml中注冊的ContextLoaderListener监听器不过初始化了一个根上下文,只完毕了组件扫描和与容器初始化相关的一些工作,并没有探測到详细每一 ...
- SpringMVC: web.xml中声明DispatcherServlet时一定要添加load-on-startup标签
游历SpringMVC源码后发现,在web.xml中注册的ContextLoaderListener监听器只是初始化了一个根上下文,仅仅完成了组件扫描和与容器初始化相关的一些工作,并没有探测到具体每个 ...
随机推荐
- Binary Tree HDU - 5573 (思维)
题目链接: B - Binary Tree HDU - 5573 题目大意: 给定一颗二叉树,根结点权值为1,左孩子权值是父节点的两倍,右孩子是两倍+1: 给定 n 和 k,让你找一条从根结点走到第 ...
- mysql 原理 ~ 索引通说
简介: 来说说索引吧目的:为了加快数据库的数据查找速度,索引应用而生基础知识基本定义 1 遍历 所谓遍历二叉树,就是按一定的规则和顺序走遍二叉树的所有结点,使每一个结点都被访问一次,而且只被访问一次 ...
- const的引用
const的引用 对常量的引用:把引用绑定到const对象上,就像绑定到其他对象上一样,不能被用作修改它所绑定的对象: ; const int &r1 = ci;//正确:引用及其对应的对象都 ...
- tomcat quartz 被触发两次
主要原因为tomcat server.xml 配置问题 <Host appBase="webapps" autoDeploy="true" name=&q ...
- Battery historian安装及使用
在介绍Battery historian之前首先来介绍一下 Android adb bugreport 工具,bugreport是什么,怎么用? android系统想要成为一个功能完备,生态繁荣的操作 ...
- Matlab 读取 ROS bag 文件指定消息数据
近期在接触Ros的时候遇到了一些问题,如何将rosbag中的信息提取出来进行进一步处理呢? 如三维点位置信息,视频信息(如果有的话)等等. 我采用的是MATLAB 读取bag信息 filepath=f ...
- understand 安装笔记
1. 下载64位 https://pan.baidu.com/s/1sJNSrG6n5Y0C1UFCZACYEA 或者去官网下载: https://scitools.com/download/arch ...
- mysql配置修改项
[mysqld] innodb_locks_unsafe_for_binlog = 1 transaction-isolation = READ-COMMITTED 作用:防死锁 ,提高并发入库速度
- Python备份MySQL数据库【转】
#!/usr/bin/env python # coding: utf- import os import time ''' defined variable ''' databases=['hch' ...
- LaTeX公式中的空格
两个quad空格 a \qquad b 两个m的宽度 quad空格 a \quad b 一个m的宽度 大空格 a\ b 1/3m宽度 中等空格 a\;b 2/7m宽度 小空格 a\,b 1/6m宽度 ...