springboot 关于servlet容器配置修改及原理 组件注册 容器切换 使用外部tomcat流程及原理
1.嵌入式Servlet容器配置修改
-
- 1.通过全局配置文件修改
- 可以通过server.xxx 来进行web服务配置, 没有带服务器名称的则是通用配置
- 通过带了具体的服务器名称则是单独对该服务器进行设置,比如 server.tomcat.xxx 就是专门针对tomcat的配置
-
- 1.通过全局配置文件修改
-
- 2.通过WebServerFactoryCustomizer的Bean修改
- 修改server.xxx 配置的相关内容
- 会跟配置文件形成互补
- 2.通过WebServerFactoryCustomizer的Bean修改
@Component public class CustomizationBean implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> { @Override public void customize(ConfigurableServletWebServerFactory factory) { factory.setContextPath("/abc"); } }
2.注册servlet三大组件 servlet listener filter
方式一:servlet3.0规范提供的注解方式注册 需要使用 @ServletComponentScan 扫描才能生效
-
- @WebServlet
- @WebListener
- @WebFilter
@WebServlet(name="HelloServlet",urlPatterns = "/HelloServlet") //@WebFilter 使用方式相似 //@WebListener 使用方式相似 public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter writer = resp.getWriter(); writer.println("hello world 3333"); } }
@SpringBootApplication @ServletComponentScan public class SpringbootservletApplication { public static void main(String[] args) { SpringApplication.run(SpringbootservletApplication.class, args); } }
方式二:springboot 方式
public class BeanServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter writer = resp.getWriter(); writer.println("hello BeanServlet!"); } }
@Configuration public class SpringBootServlet { /** * SpringBoot提供的注册: * ServletRegistrationBean * FilterRegistrationBean * ServletListenerRegistrationBean */ @Bean public ServletRegistrationBean myServlet(){ ServletRegistrationBean<Servlet> servletServletRegistrationBean = new ServletRegistrationBean<>(); servletServletRegistrationBean.setServlet(new BeanServlet()); servletServletRegistrationBean.setName("BeanServlet"); servletServletRegistrationBean.addUrlMappings("/BeanServlet"); return servletServletRegistrationBean; } }
3.切换其他嵌入式Servlet容器
- Spring Boot包含对嵌入式Tomcat,Jetty和Undertow服务器的支持
- tomcat(默认)
- Jetty(socket)
- Undertow(响应式)
-
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!--1.排除tomcat 要想使用jetty 或者 undertow 必须排除tomcat--> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <!--2.依赖jetty <dependency> <artifactId>spring-boot-starter-jetty</artifactId> <groupId>org.springframework.boot</groupId> </dependency>--> <!--3.依赖undertow <dependency> <artifactId>spring-boot-starter-undertow</artifactId> <groupId>org.springframework.boot</groupId> </dependency>-->
4.使用外部Servlet容器
1. 下载tomcat服务 springboot3.1.2 对应 Tomcat10.1.11 版本不对应会有问题,访问不了
2.设置当前maven项目的打包方式
<!--打包方式 默认是jar-->
<packaging>war</packaging>
3.让tomcat相关的依赖不参与打包部署 ,因为外置tomcat服务器已经有这些jar包
<!--让它不参与打包部署--> <dependency> <artifactId>spring-boot-starter-tomcat</artifactId> <groupId>org.springframework.boot</groupId> <scope>provided</scope> </dependency>
4. 为了让它支持springboot需要加上一下代码: 才能启动springboot应用
public class TomcatStartSpringBoot extends SpringBootServletInitializer{ @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { return builder.sources(SpringbootservletApplication.class); } }
5.servlet容器的自动配置原理、
1.servlet自动配置类, 依赖任何一个servlet容器 ServletRequest 都会生效,若是没有任何servlet容器,ServletRequest 就会是红色的失效状态
如 排除了tomcat 容器 还没有加载其他容器,ServletRequest 就是红色的
@AutoConfiguration(after = SslAutoConfiguration.class) @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) //配置任何servlet容器,该类都会生效,否则不生效 @ConditionalOnClass(ServletRequest.class) //指定类型未servlet类型,若ServletRequest生效,一定是servlet类型 @ConditionalOnWebApplication(type = Type.SERVLET) //配置属性类 启用类所有server.xxx的配置信息绑定到 ServerProperties类上面 @EnableConfigurationProperties(ServerProperties.class) @Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
//一下是导入对应的依赖包才能生效的内嵌容器 ServletWebServerFactoryConfiguration.EmbeddedTomcat.class, ServletWebServerFactoryConfiguration.EmbeddedJetty.class, ServletWebServerFactoryConfiguration.EmbeddedUndertow.class }) public class ServletWebServerFactoryAutoConfiguration { }
ServletWebServerFactoryCustomizer 和 TomcatServletWebServerFactoryCustomizer 都是实现了
customize 接口进行的属性注入,那么谁调用的 customize()接口呢 。就是
BeanPostProcessorsRegistrar 并注册了
WebServerFactoryCustomizerBeanPostProcessor
6.外部tomcat启动springboot原理
tomcat不会主动去启动springboot应用 ,, 所以tomcat启动的时候肯定调用了SpringBootServletInitializer 的 SpringApplicationBuilder , 就会启动springboot
符合servlet 的spi规范
大概: 当servlet容器启动时候 就会去META-INF/services 文件夹中找到javax.servlet.ServletContainerInitializer, 这个文件里面肯定绑定一个ServletContainerInitializer. 当servlet容器启动时候就会去该文件中找到ServletContainerInitializer的实现类,从而创建它的实例调用onstartUp
- @HandlesTypes(WebApplicationInitializer.class).
- @HandlesTypes传入的类为ServletContainerInitializer感兴趣的
- 容器会自动在classpath中找到 WebApplicationInitializer 会传入到onStartup方法的webAppInitializerClasses中
- Set<class<?>> webAppInitializerClasses 这里面也包括之前定义的TomcatStartSpringBoot
/** * 外部tomcat启动 springboot 的配置文件 */ public class TomcatStartSpringBoot extends SpringBootServletInitializer{ @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { return builder.sources(SpringbootservletApplication.class); } }
代码关系图
SpringServletContainerInitializer的 onStartup 方法调用
SpringBootServletInitializer的 onStartup 方法
最后是通过run 方法启动的
注意springmvc 里在web.xml配置的 DispatcherServlet 和 ContextLoaderListener 也是
例如:ContextLoaderListener
分类:
spring
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2020-08-04 连redis 连不上怎么办!