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 --> ...
随机推荐
- Windows下git多用户配置
refer from :https://blog.csdn.net/qq_39892503/article/details/109374201 windows git多用户配置 在安装git结束,我们 ...
- rabbitMQ报错:Caused by: com.rabbitmq.client.ShutdownSignalException: connection error; protocol method:
1.输入的机器的 IP:15672进入Raabitmq的登陆管理界面 点击admin,进去点击set permission ok, 在运行应该就不会包这个错了
- Python布尔值
在学到Python数据类型时,发现与大多数语言没什么区别 布尔值可以用 and or not 来运算 and运算是与运算,所有条件都符合才为true >>> True and Tru ...
- dos的基本命令
打开cmd的方式 开始+系统+命令提示符 Win键+R 输入cmd打开控制台(推荐使用) 在任意的文件夹下面,按住shift键+鼠标右键点击,在此处打开命令行窗口 资源管理器的地址栏前面加上cmd + ...
- OpenStack平台的使用
一.OpenStack平台的使用 使用双节点部署,192.168.16.10为控制节点.192.168.16.20为计算节点. (一).创建镜像 1.在控制节点中找到qcow2镜像 [root@con ...
- Spring Boot + MyBatis 多模块项目搭建教程
一.前言 1.开发工具及系统环境 IDE:IntelliJ IDEA 2020.2.2 系统环境:Windows 2.项目目录结构 biz层:业务逻辑层 dao层:数据持久层 web层:请求处理层 二 ...
- [loj3276]遗迹
假设已知$a_{i}$,通过以下方式确定$b_{i}$:从后往前枚举每一个数$i$,先令$b_{i}=a_{i}$,再将$b_{i}$不断减1直至不存在$j>i$且$b_{i}=b_{j}$或$ ...
- Aggregated APIServer 构建云原生应用最佳实践
作者 张鹏,腾讯云容器产品工程师,拥有多年云原生项目开发落地经验.目前主要负责腾讯云 TKE 云原生 AI 产品的开发工作. 谢远东,腾讯高级工程师,Kubeflow Member.Fluid(CNC ...
- 八、hive3.1.2 安装及其配置(本地模式和远程模式)
目录 前文 hive3.1.2 安装及其配置(本地模式和远程模式) 1.下载hive包 2.修改其环境变量 3.MySQL配置 Centos7 MySQL安装步骤: 1.设置MySQL源 2.安装My ...
- 在SEO过程中,如何避免网站中出现软404
这篇文章分享一个SEO的问题,软404.我们在网站中经常见到的一个状态码就是404.无论我们是否开发一个网站,这都是要面对的一个问题 何谓软404 在说软404之前,我们首先要了解什么是404.404 ...