之前并没有意愿写关于下面内容的小作文。因为总结SPI相关的标准(SPI机制之JDK中的SPI - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)),而这个也是关于标准的,Servlet3.0以上标准的一个小知识点。就回忆了一下下面的内容,好记性不如烂笔头还是老老实实做总结笔记吧。

  一般入门的web项目,使用集成开发工具都会自建一个web.xml的文件。该文件中配置servlet/filter/listener等相关信息。如下图:

    

  Spring提供接口WebApplicationInitializer,通过自定义实现该接口配置web.xml里的相关信息。查看该接口源码:

    

  同时该接口源码注释中提供了多个示例,下图是示例之一:

    

  ,这个servletContext可以直接理解为常用的容器tomcat的一个实例。如果使用其他的符合servlet标准的容器,也可以理解为其他容器的一个实例。

  为什么单拧这个出来呢?之前关于Spring Boot自动配置SpringMVC简单提到过其可以直接在容器中运行。那么web项目的启动信息是如何与容器比如tomcat中直接运行的,即tomcat是如何识别这个web项目的?这里就涉及一个标准~Servlet3.0以上版本的标准吧。

  为什么?实际上Servlet3.0以上的标准中,运行时可插拔性为SpringBoot自动配置MVC后并自动在容器中运行提供了可能。具体实现通过ServletContainerInitializer

  1)ServletContainerInitializer类通过jar services API查找。对于每一个应用,应用启动时,有容器创建一个ServletContainerInitializer实例。

  2)自定义的应用提供的ServletContainerInitializer试了下必须绑定在jar包的META-INF/services目录中的一个叫做javax.servlet.ServletContainerInitializer的文件中,并根据这个文件指定ServletContainerInitializer的实现。

    这个规则其实就是SPI机制的约定之一。

  3)除了ServletContainerInitializer外,还提供一个注解@HandlesTypes。在ServletContainerInitializer实现上的HandlesTypes注解用于表示感兴趣的一些类,他们可以指定@HandlesTypes的value中的注解(类型、方法或自动级别的),或者是其类型的超类继承/实现之一。

  以上通过具体操作的解释如下:

  1、编写自定义一个类实现ServletContainerInitializer

    

    其方法名就是onStartup,调用自定义实现WebApplicationInitializer的类或子类的方法onStartup

  2、通过@HandlesTypes传递web配置信息,编写实现WebApplicationInitializer的类即可。(可以是其他类或子类,但是此处是针对SpringMVC,必须实现WebApplicationInitializer)

    

    具体的一个实现如下:

    

  3、文件编写META-INF/services目录中的一个叫做javax.servlet.ServletContainerInitializer

    

    

    文件内容为实现ServletContainerInitializer的类全限定名。

  这样启动tomcat容器时,tomcat自动扫描该项目jar下的所有META-INF/services目录中的一个叫做javax.servlet.ServletContainerInitializer的文件,执行文件MySpringServletContainerInitializer类的onStartup方法,其通过反射自动调用MyWebApplicationInitializer的onStartup方法。

  javax.servlet.ServletContainerInitializer作为纽带将容器与WebApplicationInitializer关联起来。下面验证SpringBoot中SpringMVC自动配置是否符合此逻辑:

  1、SpringBoot添加web依赖

    

  2、查看加载的jar中是否存在META-INF/services目录中的一个叫做javax.servlet.ServletContainerInitializer

    

    

  3、查看SpringServletContainerInitializer类具体实现

    

  4、查看WebApplicationInitializer的实现

    

  

  

  

最新文章

  1. java 将一张图片拷贝到另外一个地方。(IO流)
  2. Java的历史
  3. 什么是I帧,P帧,B帧
  4. POJ 3259 Wormholes 虫洞(负权最短路,负环)
  5. HW4.21
  6. 移动端开发(四):swiper.js
  7. JS跨域访问问题
  8. Apache .htaccess语法之RewriteRule
  9. 裸二分图匹配poj1469
  10. 九天学会Java,第二天,算术运算
  11. 查找数组中重复的唯一元素+时间复杂度O(n)+空间复杂度O(1)
  12. Apache-Flink深度解析-DataStream-Connectors之Kafka
  13. 后台登录(包含验证码)的php代码实现
  14. 关于centos7和centos6中平滑升级nginx到新版本v1.12.1修复nginx最新漏洞CVE-2017-7529的解决方案
  15. Postgresql_根据执行计划优化SQL
  16. Linux:条件变量
  17. 亲历H5移动端游戏微信支付接入及那些坑(四)——参考文档
  18. grunt学习三-bower(二)
  19. k8s dockerk个人学习(1)
  20. 使用Font Awesome替换你的网站图标(icons 图标)

热门文章

  1. kubernetes运行应用2之DaemonSet详解
  2. [FatFs 学习] SD卡总结-SPI模式
  3. 2月2日 体温APP开发记录
  4. golang中内存地址计算-根据内存地址获取下一个内存地址对应的值
  5. DBeaver下载安装与连接MySQL数据库
  6. 数据库查询语句遇到:Unknown column 'XXXX' in 'where clause'解决方法
  7. K8S集群架构
  8. 「JOI 2015 Final」舞会
  9. IDEA中的.iml文件和.idea文件夹作用和意义
  10. Spring Boot配置多个DataSource (转)