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监听器只是初始化了一个根上下文,仅仅完成了组件扫描和与容器初始化相关的一些工作,并没有探测到具体每个 ...
随机推荐
- python web cgi
知识详解: cgi:通用网关接口,网络脚本的解析 python cgi 自带有cgi轻量级服务器,我们通过cgi命令可以开启该服务器 python2 python -m CGIHTTPServer p ...
- STL之permutation/ equal_range/ binary_range学习
1,is_permutation 函数,判断其中一个序列是不是另外一个序列的全排列. 包括四个参数,前两个是第一个数组需要判断的起始位置和终止位置.后两个是第二个数组需要判断的起始位置和终止位置. # ...
- ESD总结
设计人员完全可以让系统在经过ESD事件后不发生故障并仍能继续运行.将这个目标谨记在心,下面让我们更好地理解ESD冲击时到底发生了什么,然后介绍如何设计正确的系统架构来应对ESD. 简单模型 将一个电容 ...
- workqueue --最清晰的讲解
带你入门: 1.INIT_WORK(struct work_struct *work, void (*function)(void *), void *data) 上面一句只是定义了work和work ...
- MySQL中interactive_timeout和wait_timeout的区别【转】
在用mysql客户端对数据库进行操作时,打开终端窗口,如果一段时间没有操作,再次操作时,常常会报如下错误: ERROR 2013 (HY000): Lost connection to MySQL s ...
- 解决Windows 10笔记本接显示器分屏后没有声音的问题
Windows 10 版本号:17763.292 1.首先右键点击任务栏托盘中的[扬声器]图标,选择[声音],如下图所示. 2.选择[播放],然后选择[扬声器],再点击[设为默认值],如下所示. 3. ...
- ubuntu Qt linuxdeployqt打包
1.下载PatchELF 0.9.,https://nixos.org/patchelf.html 安装:./configure make sudo make install 2.终端命令设置设置环境 ...
- PHP导出MySQL数据字典 Summer-Mysql-Dic
2017年11月9日09:30:29 用 PHP 写的一个类文件, 用来导出MySQL数据字典 导出表信息; 字段信息, 索引信息 可以导出浏览器适用的样式, 也可以导出word文档 建议上线前用这个 ...
- Android App增量升级
移动互联网主打的就是用户体验和产品的快速迭代,通过用户反馈和用户行为跟踪及时调整产品方向,这样才能持续保持生命力和创造力.说的接地气点就是,你频繁的升级更新,有时只是修复了几个bug或者微调了下界面, ...
- Webapi 跨域 解决解决错误No 'Access-Control-Allow-Origin' header is present on the requested resource 问题
首先是web端(http://localhost:53784) 请求 api(http://localhost:81/api/)时出现错误信息: 查看控制台会发现错误:XMLHttpRequest c ...