SpringBoot的嵌入式Servlet容器自动配置原理1

本文深入探讨SpringBoot如何定制和修改Servlet容器配置,包括ServerProperties和EmbeddedServletContainerCustomizer的使用。同时,详细介绍了如何注册Servlet、Filter和Listener,通过ServletRegistrationBean、FilterRegistrationBean和ServletListenerRegistrationBean实现组件注册。文章还提供了DispatcherServlet自动注册的示例,并讨论了使用其他Servlet容器如Jetty和Undertow的可能性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

 

前言

一、如何定制和修改Servlet容器的相关配置

二、注册Servlet三大组件【Servlet、Filter、Listener】

1、先来看ServletRegistrationBean

2、接下来是FilterRegistrationBean

3、最后一个是ServletListenerRegistrationBean

三、举例

四、知识扩充


前言

我们知道SpringBoot默认使用Tomcat作为嵌入式的Servlet容器

我们可以从pom文件中右键查看依赖图:

既然是嵌入式的容器了,于是不禁思考:我们该如何定制和修改Servlet容器的相关参数呢?

一、如何定制和修改Servlet容器的相关配置

1、修改和server有关的配置(ServerProperties【也是EmbeddedServletContainerCustomizer】)例如:

server.port=8081

server.context-path=/crud

 

我们进入到ServerProperties类中,它来绑定和服务器相关的配置,可以看到还能配置tomcat:

于是我们可以大致总结:通用的Servlet容器设置为server.xxx,那么Tomcat的设置则为server.tomcat.xxx

 

查看tomcat:

2、编写一个EmbeddedServletContainerCustomizer:嵌入式的Servlet容器的定制器。它也可以用来修改Servlet容器的配置。

2.x版源码中的类已经没有EmbeddedServletContainerCustomizer:

1.x版本是WebServerFactoryCustomizer类,这个类是个接口:

需要注意的是,在此处是规定了一个泛型,否则不能设置服务器属性,对比如下图,下方的方法才是正确的。另外我们需要注意,要想让这个方法起作用,就需要在方法头部加上@Bean,这样springboot才知道它的存在

编写完成后我们启动项目看看,发现端口号的确是配置后的8081:

 

二、注册Servlet三大组件【Servlet、Filter、Listener】

由于SpringBoot默认是以jar包的方式启动嵌入式的Servlet容器来启动SpringBoot的web应用,没有web.xml文件。而非是创建一个标准的web应用的目录结构,如果是的话,那应该在src下的main里面有个webapp,其下有META-INF,其下还有web.xml,把所有插件注册到web.xml。

如果不是注册到web.xml里面,那是否有其他办法呢?于是引入注册组件这一解决工具:

注册三大组件用以下方式

ServletRegistrationBean、FilterRegistrationBean、ServletListenerRegistrationBean

1、先来看ServletRegistrationBean

我们先创建一个ServletRegistrationBean类型的方法,

我们可以点进ServletRegistrationBean看看,发现里面有一个有参构造器,里面的参数,一个是我们可以直接传一个servlet,另一个则是映射路径

运行程序,打开浏览器,输入url,http://localhost:8080/crud/myServlet

2、接下来是FilterRegistrationBean

其实实现模式一样:先创建一个实现了Filter(注意是javax.servlet)的类MyFilter,我们在doFilter()方法中除了做一些输出,还需要放行

 

 

感兴趣可以点进FilterRegistrationBean看看,

而后就是编写FilterRegistrationBean类型的方法。这个方法里面我们设置对哪些servlet进行拦截过滤,并且对映射地址做出设置

如果我们在这里把路径写错了,少了斜杠

则会报错:

项目成功启动后,我们访问http://localhost:8080/crud/myServlet

此时查看控制台,输出了我们起初设置的内容

 

3、最后一个是ServletListenerRegistrationBean

先实现一个实现了ServletContextListener接口的类。里面有两个方法,一个是初始化,一个是销毁

之后就是编写一个ServletListenerRegistrationBean类型的方法

注意这里是个泛型:

之后我们运行程序,注意看,在控制台输出了如下信息:

之后我们再点击exit。注意!如下是正常的程序关闭按钮

于是我们发现控制台又有输出信息:

 

不过切记哟,不可以点以下这两个,(尽管我们基本上都会习惯性点这两个)这样的操作相当于直接拔电源了!

    

 

三、举例

最好的一个例子就是SpringBoot在帮我们自动SpringMVC的时候,自动的注册SpringMVC的前端控制器:DispatcherServlet。

我们进入DispatcherServletAutoConfiguration看看:

这里我们看到getPath()方法:

点进去看看

这个path是什么呢?看下图:

即默认拦截所有路径的,包括静态资源,但是不拦截jsp请求

而以往我们也接触过/*,它是会拦截jsp请求的。同时我们也知道,可以通过server.servletPath来修改SpringMVC前端控制器默认拦截的请求路径

 

四、知识扩充

使用其他servlet容器

Jetty:长连接

Undertow :不支持JSP

我们可以在代码中看看ConfigurableWebServerFactory的继承树,ctrl+h

替换为其他嵌入式Servlet容器

默认支持:

Tomcat(默认使用)

<dependency>

   <groupId>org.springframework.boot</groupId>

   <artifactId>spring-boot-starter-web</artifactId>

   引入web模块默认就是使用嵌入式的Tomcat作为Servlet容器;

</dependency>

jetty

<!-- 引入web模块 -->

<dependency>

   <groupId>org.springframework.boot</groupId>

   <artifactId>spring-boot-starter-web</artifactId>

   <exclusions>

      <exclusion>

         <artifactId>spring-boot-starter-tomcat</artifactId>

         <groupId>org.springframework.boot</groupId>

      </exclusion>

   </exclusions>

</dependency>



<!--引入其他的Servlet容器-->

<dependency>

   <artifactId>spring-boot-starter-jetty</artifactId>

   <groupId>org.springframework.boot</groupId>

</dependency>

Undertow

<!-- 引入web模块 -->

<dependency>

   <groupId>org.springframework.boot</groupId>

   <artifactId>spring-boot-starter-web</artifactId>

   <exclusions>

      <exclusion>

         <artifactId>spring-boot-starter-tomcat</artifactId>

         <groupId>org.springframework.boot</groupId>

      </exclusion>

   </exclusions>

</dependency>



<!--引入其他的Servlet容器-->

<dependency>

   <artifactId>spring-boot-starter-undertow</artifactId>

   <groupId>org.springframework.boot</groupId>

</dependency>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值