在之前的《SpringBoot之二:部署Spring Boot应用程序方式》章节有过一个实践,需要启动类继承自SpringBootServletInitializer方可正常部署至常规tomcat下,其主要能够起到web.xml的作用。下面通过源码简单解析为何其能够替代web.xml。
 
本章概要
1、源码分析如何实现SpringBootServletInitializer整个加载过程;
2、实现自定义WebApplicationInitializer配置加载;
3、实现自定义ServletContainerInitializer 配置加载;
 
示例代码如下
1、首先web.xml主要配置各种servlet,filter,listener等,如常见的Log4jConfigListener、OpenSessionInViewFilter、CharacterEncodingFilter、DispatcherServlet等,此部分信息均是容器启动时加载。
2、在springboot中我们从SpringBootServletInitializer源码入手:
3、WebApplicationInitializer接口是通过spring的SpringServletContainerInitializer中指定的用于启动组件的。具体见《SpringMVC之五:自定义DispatcherServlet配置及配置额外的 servlets 和 filters》中的WebApplicationInitializer说明。
4、通过3中的说明可以很清楚的理解其服务启动容器加载过程配置的装载过程,在SpringServletContainerInitializer中可以发现所有WebApplicationInitializer实现类在执行onStartup方法前需要根据其注解@order值排序,下面自定义一个WebApplicationInitializer实现类:
package com.dxz.demo.config;

import javax.servlet.ServletContext;
import javax.servlet.ServletException; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.web.WebApplicationInitializer; @Order(1)
public class MyWebApplicationInitializer implements WebApplicationInitializer {
private Logger logger = LoggerFactory.getLogger(MyWebApplicationInitializer.class); @Override
public void onStartup(ServletContext paramServletContext) throws ServletException {
logger.info("启动加载自定义的MyWebApplicationInitializer");
System.out.println("启动加载自定义的MyWebApplicationInitializer");
} }
打成WAR包部署至常规tomcat下启动服务验证:
 
注:之前有专门讲解如何装载servlet、filter、listener的注解,且可以通过两种不同的方式。那么第三种方式可以通过WebApplicationInitializer的实现类来进行装载配置。但此方式仅限部署至常规容器下生效,采用jar方式应用内置容器启动服务不加载
 
5、既然可以通过自定义的WebApplicationInitializer来实现常规容器启动加载,那么我们是否可以直接自定义ServletContainerInitializer来实现启动加载配置呢:
5.1、首先编写一个待注册的servlet:
package com.dxz.demo.config;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class Servlet4 extends HttpServlet { @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Servlet4");
resp.setContentType("text/html");
resp.getWriter().write("Servlet4");
} @Override
public void init() throws ServletException {
super.init();
System.out.println("Servlet4 loadOnStart");
} }
5.2、编写实现ServletContainerInitializer的自定义实现类:

package com.dxz.demo.config;

import java.util.Set;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; public class MyServletContainerInitializer implements ServletContainerInitializer {
private Logger logger = LoggerFactory.getLogger(MyServletContainerInitializer.class); @Override
public void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException {
logger.info("启动加载自定义的MyServletContainerInitializer");
System.out.println("启动加载自定义的MyServletContainerInitializer");
ServletRegistration.Dynamic testServlet = servletContext.addServlet("servlet4",
"com.shf.springboot.servlet.Servlet4");
testServlet.setLoadOnStartup(1);
testServlet.addMapping("/servlet4");
}
}
5.3、对新增的servlet设置其请求路径,同时打成WAR包部署至tomcat启动服务,但请求http://localhost:8080/SpringBoot1/servlet4却失败,此时发现需要了解servlet3对于ServletContainerInitializer 的加载机制是如何的,在官方有类似这样的描述“该接口的实现必须声明一个JAR资源放到程序中的META-INF/services下,并且记有该接口实现类的全路径,才会被运行时(server)的查找机制或是其它特定机制找到”。那么我们先参考spring-web-4.3.2.RELEASE.jar中
我们可以将自定义的类配置到一个jar包下部署至WEB-INF\lib目录下,
5.3.1、首先新建如下目录结构的文件并填写内容如下:
5.3.2、然后通过如下命令生成jar包
 
5.3.3、将myTest.jar放置WEB-INF\lib目录下重启服务,再次请求:
 
 
注:与4中实现WebApplicationInitializer一样,该方式仅限于部署常规容器生效。故jar通过内置容器启动的服务无法加载servlet4配置。

最新文章

  1. Redis 数据类型及其特点
  2. geotrellis使用(十三)数据导入BUG解决方案说明
  3. OData V4 系列 查询操作
  4. import com.sun.image.codec.jpeg.JPEGCodec不通过 找不到包
  5. 7.添加基于Spring的WebService拦截器
  6. 解决Wireshark没有网卡问题
  7. linux shell脚本通过参数名传递参数值
  8. 使用html5的离线缓存技术
  9. table合并单元格colspan和rowspan .
  10. HDU5140---Hun Gui Wei Company (主席树)
  11. my_query()的引号注意
  12. Java核心技术(Java白皮书)卷Ⅰ 第一章 Java程序设计概述
  13. [FreeRadius2]遇到问题记录
  14. docker学习------记录centos7.5下docker安装更换国内源的处理过程
  15. 在spring中实现quartz2.2.1的动态调度(开始、暂停、停止等)
  16. Git和Svn对比
  17. 【Java】 大话数据结构(9) 树(二叉树、线索二叉树)
  18. [Leetcode] 863. All Nodes Distance K in Binary Tree_ Medium tag: BFS, Amazon
  19. 【Spring学习笔记-MVC-15】Spring MVC之异常处理
  20. 20155315 2017-05-10 《Java程序设计》课堂代码检查

热门文章

  1. 十二道MR习题 - 3 - 交集并集差集
  2. 关于VirtualBox在桥接模式下无法联网解决方案
  3. java 在Excel中插入图片 POI实现
  4. Autolayout .Compact or .Regular [iPhone/iPad]
  5. Cassandra key说明——Cassandra 整体数据可以理解成一个巨大的嵌套的Map Map&lt;RowKey, SortedMap&lt;ColumnKey, ColumnValue&gt;&gt;
  6. 在VMware永久修改网
  7. Markdown速成班
  8. mysql中delete的表别名使用方法
  9. HihoCoder 1104 : Suzhou Adventure(树形DP)
  10. python库之_thread