SpringBoot(六)之内嵌容器

简介: 需要用哪个容器,就把其他两个容器注释掉。(

pring Boot 提供了一种便捷的方式来创建独立运行的 Spring 应用程序,内嵌容器(如 Tomcat、Jetty 或 Undertow)是其核心特性之一。这使得开发者不需要将应用程序部署到外部的应用服务器上,而是通过内嵌容器直接运行应用。这种方式简化了部署流程,并且提高了开发和测试的效率。


内嵌容器的特点

独立性:应用程序包含了所有必要的依赖和服务器配置,能够独立运行,而不依赖外部的应用服务器。

简化部署:通过 Maven 或 Gradle 构建后,可以生成一个可执行的 JAR 文件,直接通过命令行运行。

一致性:开发、测试和生产环境中的运行环境一致,减少了环境差异带来的问题。

如何替换默认容器

1.pom形式

如何引入underTow作为内嵌servlet容器


在spring-boot-starter-web中排除掉tomcat的jar包

引入undertow的依赖


<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <exclusions>
        <exclusion>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <!-- 使用 Undertow 替换掉 Tomcat -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-undertow</artifactId>
</dependency>

观察console

2024-05-17 16:38:26.099  INFO 1108 --- [           main] io.undertow                              : starting server: Undertow - 2.2.16.Final
2024-05-17 16:38:26.102  INFO 1108 --- [           main] org.xnio                                 : XNIO version 3.8.6.Final
2024-05-17 16:38:26.105  INFO 1108 --- [           main] org.xnio.nio                             : XNIO NIO Implementation Version 3.8.6.Final
2024-05-17 16:38:26.125  INFO 1108 --- [           main] org.jboss.threads                        : JBoss Threads version 3.1.0.Final
2024-05-17 16:38:26.162  INFO 1108 --- [           main] o.s.b.w.e.undertow.UndertowWebServer     : Undertow started on port(s) 8080 (http)
2024-05-17 16:38:26.168  INFO 1108 --- [           main] c.a.s.SpringBootAnnotationApplication    : Started SpringBootAnnotationApplication in 1.179 seconds (JVM running for 1.914)

通过日志观察,默认内嵌容器已经替换成underTow,同理jetty一样


2.主动配置

由于SpringBoot在获取servlet容器是通过ServletWebServerFactory类型来获取。ServletWebServerFactory一共有三个实现类,分别为JettyServletWebServerFactory,UndertowServletWebServerFactory,TomcatServletWebServerFactory。分别对应jetty,underTow,tomcat。


SpringBoot在AbstractApplicationContext.refresh()方法的onRefresh(),通过 ServletWebServerApplicationContext重写该方法创建webServer();



protected void onRefresh() {
        super.onRefresh();

        try {
            this.createWebServer();
        } catch (Throwable var2) {
            throw new ApplicationContextException("Unable to start web server", var2);
        }
}

在createWebServer()中有个获取WebServerFactory方法获取对应的实现类的方法getWebServerFactory();

protected ServletWebServerFactory getWebServerFactory() {
        String[] beanNames = this.getBeanFactory().getBeanNamesForType(ServletWebServerFactory.class);
        if (beanNames.length == 0) {
            throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.");
        } else if (beanNames.length > 1) {
            throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to multiple ServletWebServerFactory beans : " + StringUtils.arrayToCommaDelimitedString(beanNames));
        } else {
            return (ServletWebServerFactory)this.getBeanFactory().getBean(beanNames[0], ServletWebServerFactory.class);
        }
    }

getWebServerFactory(),通过在Spring容器中获取ServletWebServerFactory类型的bean,如果获取不到和获取多个都会抛出异常


所以我们可以通过手动配置ServletWebServerFactory对应的实现类,以此来切换不同的容器。


将tomcat,jetty,undertow的starter都引入到项目中

新建配置ServletServerConfig



@Configuration
public class ServletServerConfig {
    @Bean
    public ServletWebServerFactory underTowServletWebServerFactory(){
        UndertowServletWebServerFactory undertowServletWebServerFactory = new UndertowServletWebServerFactory();
        undertowServletWebServerFactory.setPort(8087);
        return undertowServletWebServerFactory;
    }
    //@Bean
    public ServletWebServerFactory tomcatServletWebServerFactory(){
        TomcatServletWebServerFactory tomcatServletWebServerFactory = new TomcatServletWebServerFactory();
        tomcatServletWebServerFactory.setPort(8081);
        return tomcatServletWebServerFactory;
    }
    //@Bean
    public ServletWebServerFactory jettyServletWebServerFactory(){
        JettyServletWebServerFactory jettyServletWebServerFactory = new JettyServletWebServerFactory();
        jettyServletWebServerFactory.setPort(8086);
        return jettyServletWebServerFactory;
    }
}

需要用哪个容器,就把其他两个容器注释掉。(不能创建多个ServletWebServerFactory,在getWebServerFactory()中会抛异常)


如何通过配置切换serlvet容器

在主动配置的基础上,可以通过对config进行改造


在application.yaml中配置servlet.server属性 ,具体1,2,3代表tomcat还是jetty由自己定义

利用SpringBoot注解@ConditionalOnProperty注解可以切换servlet容器



servlet:
  server: 2

@Configuration
public class ServletServerConfig {

    @Bean
    @ConditionalOnProperty(name = "servlet.server",havingValue = "1")
    public ServletWebServerFactory underTowServletWebServerFactory(){
        UndertowServletWebServerFactory undertowServletWebServerFactory = new UndertowServletWebServerFactory();
        undertowServletWebServerFactory.setPort(8087);
        return undertowServletWebServerFactory;
    }
    @Bean
    @ConditionalOnProperty(name = "servlet.server",havingValue = "2")
    public ServletWebServerFactory tomcatServletWebServerFactory(){
        TomcatServletWebServerFactory tomcatServletWebServerFactory = new TomcatServletWebServerFactory();
        tomcatServletWebServerFactory.setPort(8081);
        return tomcatServletWebServerFactory;
    }
    @Bean
    @ConditionalOnProperty(name = "servlet.server",havingValue = "3")
    public ServletWebServerFactory jettyServletWebServerFactory(){
        JettyServletWebServerFactory jettyServletWebServerFactory = new JettyServletWebServerFactory();
        jettyServletWebServerFactory.setPort(8086);
        return jettyServletWebServerFactory;
    }
}

ServletServerConfig中,1表示underTow,2表示tomdat,3,表示jetty。而application.yml中配置的2,则启动项目,观察console

2024-05-17 17:14:19.142  INFO 7500 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2024-05-17 17:14:19.148  INFO 7500 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]

将配置更改为3,再次启动,观察console

2024-05-17 17:15:01.473  INFO 5260 --- [           main] o.e.jetty.server.AbstractConnector       : Started ServerConnector@13579834{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
2024-05-17 17:15:01.473  INFO 5260 --- [           main] o.s.b.web.embedded.jetty.JettyWebServer  : Jetty started on port(s) 8080 (http/1.1) with context path '/'

目录
相关文章
|
4月前
|
前端开发 Java 应用服务中间件
Spring Boot 2.x 嵌入式 Servlet 容器
Spring Boot使用内嵌Tomcat,默认端口8080,可通过`application.properties`配置端口、上下文路径等。配置方式有两种:1) 直接在配置文件中添加`server.port`和`server.servlet.context-path`;2) 创建`WebServerFactoryCustomizer` Bean来自定义配置,如设置端口`factory.setPort(8083)`,这种方式优先级更高。
|
4月前
|
Java Spring 容器
深入理解Spring Boot中的容器与依赖注入
深入理解Spring Boot中的容器与依赖注入
|
5月前
|
Java API Docker
使用Spring Boot和Docker进行容器化部署
使用Spring Boot和Docker进行容器化部署
|
5月前
|
Java 应用服务中间件 容器
手写SpringBoot(二)之动态切换Servlet容器
我们在切换serlvet容器的时候,会将SpringBoot默认的tomcat jar包给排除掉,换上我们需要的jar包,比如jetty。
39 0
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
144 1
|
2月前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的服装商城管理系统
基于Java+Springboot+Vue开发的服装商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的服装商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
152 2
基于Java+Springboot+Vue开发的服装商城管理系统
|
18天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
95 62
|
16天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
34 2
|
19天前
|
JavaScript Java 项目管理
Java毕设学习 基于SpringBoot + Vue 的医院管理系统 持续给大家寻找Java毕设学习项目(附源码)
基于SpringBoot + Vue的医院管理系统,涵盖医院、患者、挂号、药物、检查、病床、排班管理和数据分析等功能。开发工具为IDEA和HBuilder X,环境需配置jdk8、Node.js14、MySQL8。文末提供源码下载链接。
|
2月前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的大学竞赛报名管理系统
基于Java+Springboot+Vue开发的大学竞赛报名管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的大学竞赛报名管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
218 3
基于Java+Springboot+Vue开发的大学竞赛报名管理系统