springMVC WebApplicationInitializer 替代web.xml 配置Servlet 之原理
Servlet 3.0之前 ,xml 配置
在过去搭建spring + springMCV ,首先第一步要做的是什么 ,就是要配置web.xml 文件 ,把springMVC 中的Servlet 加载到tomcat 。通过加载 dispatcher 来启动整个spring容器。web.xml 如下 。
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/dispatcher-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet> <servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Servlet 3.0后 ,java 配置
在Servlet 进入在3.0+时代后,Servlet 变支持了注解配置Servlet,而spring也推荐 java 代码的配置 。那么以上web.xml 配置Servlet,便可以通过实现WebApplicationInitializer 接口,来完成Servlet的配置 ,直接看代码,如下
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic; import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet; public class WebInitializer implements WebApplicationInitializer {// 1 实现接口
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(MyMvcConfig.class); //注册自己的配置文件
ctx.setServletContext(servletContext); // 2 把 ServletContext 注入到spring容器中
Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx)); // 3 加载 dispatcher Servlet。
servlet.addMapping("/");
servlet.setLoadOnStartup(1);
}
}
MyMvcConfig 为自己的配置java文件 。,这里做简单的为容器注入了试图解析器。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView; @Configuration // 配置文件的支持
@EnableWebMvc // 开启springMCV
@ComponentScan("xxx") //扫描加载java文件
public class MyMvcConfig {
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/classes/views/");
viewResolver.setSuffix(".jsp");
viewResolver.setViewClass(JstlView.class);
return viewResolver;
}
}
ok 其实这样配置,部署到tomcat中 ,运行,就会启动 WebInitializer.onStartup 来启动spring中的各种组件 。
原理分析
在第一次接触到的时候还是和困惑?这个tomcat 是怎么时候,怎么来运行 WebInitializer.onStartup这个方法的呢。?一跟踪代码方法spring两个jar包中有这个代码的引用 ,一个是支持jetty的一个,web jar包 ,
如下图,这里就只跟踪下web中的代码 ,对jetty就不研究了

点进 SpringServletContainerInitializer 这个类,发现这个类 继承实现了 ServletContainerInitializer 这个接口 ,路径:javax.servlet.ServletContainerInitializer 。这个类可不是spring中的东西了 。完整代码 :
package org.springframework.web; import java.lang.reflect.Modifier;
import java.util.LinkedList;
import java.util.List;
import java.util.ServiceLoader;
import java.util.Set;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.HandlesTypes; import org.springframework.core.annotation.AnnotationAwareOrderComparator; /
@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {
@Override
public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
throws ServletException { List<WebApplicationInitializer> initializers = new LinkedList<WebApplicationInitializer>(); if (webAppInitializerClasses != null) {
for (Class<?> waiClass : webAppInitializerClasses) {
// Be defensive: Some servlet containers provide us with invalid classes,
// no matter what @HandlesTypes says...
if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
try {
initializers.add((WebApplicationInitializer) waiClass.newInstance());
}
catch (Throwable ex) {
throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);
}
}
}
} if (initializers.isEmpty()) {
servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
return;
} AnnotationAwareOrderComparator.sort(initializers);
servletContext.log("Spring WebApplicationInitializers detected on classpath: " + initializers); for (WebApplicationInitializer initializer : initializers) {
initializer.onStartup(servletContext);
}
} }
注意标记黄色部分,一看原来不就是,把所有 WebApplicationInitializer 遍历了一遍,然后调用了 onStartup 方法把 servletContext传进去吗。 而我们开始写的 WebInitializer就属于
WebApplicationInitializer ,所以我们的WebInitializer从这里开始运行。那么 ServletContainerInitializer 又 是怎么加载的? 这个就要跟tomcat那边的代码了,我猜,也是拿到 所有 ServletContainerInitializer 的实现类,运行了 onStartup方法 。
springMVC WebApplicationInitializer 替代web.xml 配置Servlet 之原理的更多相关文章
- eclipse环境Dynamic web module version 3.1版本的进步,简化Dynamic web object 中Servlet类的配置,不用web.xml配置<Servlet>
eclipse环境Dynamic web module version 3.1版本之前,Dynamic web object 中Servlet类的配置,要在web.xml 配置<Servlet& ...
- springmvc学习指南 之---第27篇 spring如何实现servlet3.0无web.xml 配置servlet对象的
writedby 张艳涛 基于web.xml配置,有人说麻烦,tomcat给按照servlet3.0,实现了基于注解@WebServlet,有人说springmvc的springmvc.xml配置麻烦 ...
- springmvc中的web.xml配置(包含中文乱码解决)
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http:// ...
- web.xml配置Servlet出错(DispatcherServlet)
想当然的把servlet-mapping当成servlet的属性 后台也不报错,但是输入url,就是死活不执行那个servlet servlet和servlet-mapping是同一级的对象
- springmvc框架通过web.xml配置404 500错误导向页
总不能用户输错了url就弹 这玩意吧? <error-page> <error-code>404</error-code> <location>/WEB ...
- Java web.xml 配置技巧—动态欢迎页地址
我们的 Java Web 项目在配置web.xml 欢迎页地址默认是index.html .index.jsp ,不知道有人注意过没有,如果我要配置成/index/user.action 或者 ...
- [转]web.xml中servlet ,filter ,listener ,interceptor的作用与区别
原文链接:https://blog.csdn.net/netdevgirl/article/details/51483273 一.概念: 1.servlet:servlet是一种运行服务器端的java ...
- Maven-SSM项目pom.xml配置以及springmvc配置以及mybatis配置及web.xml配置
一.Maven本地仓库的pom.xml配置 (全部是mysql数据库) <project xmlns="http://maven.apache.org/POM/4.0.0" ...
- springmvc web.xml配置之 -- DispatcherServlet
springMVC servlet配置与启动 看一下springmvc的web.xml常见配置: <servlet> <!-- 配置DispatcherServlet --> ...
随机推荐
- PTA 最小堆插入元素和删除堆顶(无哨兵元素) (20分)
PTA 最小堆插入元素和删除堆顶(无哨兵元素) (20分) 对于给定的最小堆(优先队列),分别实现插入元素和删除堆顶的函数. 函数接口定义: int insertIntoHeap(struct Hea ...
- Linux usb 4. Device 详解
文章目录 1. 简介 2. Platform Layer 2.1 Platform Device 2.2 Platform Driver 3. UDC/Gadget Layer 3.1 Gadget ...
- 连接url
celery broker redis with password broker_url = 'redis://user:password@redishost:6379/0' tooz zookeep ...
- c++学习笔记(五)
数组作为函数参数 定义 数组可以作为函数的参数使用,进行数据传送. 数组用作函数参数有两种形式,一种是把数组元素(下标变量)作为实参使用:另一种是把数组名作为函数的形参和实参使用. 1.数组元素作为函 ...
- 软件分享:网页监测及 IIS 重启工具 IISMonitor
本人以前编写过一款简单的工具软件 IISMonitor,这几天整理完善并补写了使用说明,分享出来,供大家免费使用.使用过程中,遇到什么问题或有什么建议,也可回帖留言,我尽力提供修改支持. 1.工具简介 ...
- C++getline()
#include <iostream>#include <cstring>#include <string>using namespace std;int main ...
- vagrant创建centos7后虚拟机磁盘爆满
1.问题现象 使用df -h命令,磁盘占用直接99%,明明啥也没干... 2.解决方案 找到C:\Users\你的用户名\.vagrant.d\boxes\centos7\0\virtualbox目 ...
- 记一次 .NET 某智能服装智造系统 内存泄漏分析
一:背景 1. 讲故事 上个月有位朋友找到我,说他的程序出现了内存泄漏,不知道如何进一步分析,截图如下: 朋友这段话已经说的非常言简意赅了,那就上 windbg 说话吧. 二:Windbg 分析 1. ...
- 学军中学csp-noip2020模拟5
Problem List(其实这几场全是附中出的) 这场比赛的题目相当有价值,特别是前两题,相当的巧妙. A.路径二进制 数据范围这么小,当然是搜索. \(30pts:\)大力搜索出奇迹,最后统计答案 ...
- 3D-DNA 挂载染色体
3D-DNA是一款简单,方便的处理Hi-C软件,可将contig提升到染色体水平.其githup网址:https://github.com/theaidenlab/3d-dna 3D-DNA流程简介 ...