SpringBoot使用外部Web容器的解决方案

这篇具有很好参考价值的文章主要介绍了SpringBoot使用外部Web容器的解决方案。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Spring Boot 默认内嵌了Web容器(如Tomcat、Jetty或Undertow),这使得应用可以作为独立的可执行JAR或WAR文件运行,无需外部Web容器。然而,在某些情况下,你可能想要将Spring Boot应用部署到外部的Web容器中,比如Apache Tomcat或Jetty。

嵌入式的Web容器:应用可以打包成可执行的Jar。
优点:简单、便携。
缺点:默认不支持JSP、优化定制比较复杂(使用定制器ServerProperties、自定义EmbeddedServletContainerCustomizer,自己编写嵌入式Servlet容器的创建工厂EmbeddedServletContainerFactory)。

外部的Web容器:外面安装Tomcat服务器,应用war包的方式打包运行。

解决步骤

将Spring Boot应用部署到外部的Web容器的步骤:
1.创建一个Maven项目,声明为WAR。
2.排除内嵌Tomcat容器

<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>

3.重新导入Tomcat启动器,依赖范围改为provided

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-tomcat</artifactId>
   <scope>provided</scope>
</dependency>

4.必须编写一个SpringBootServletInitializer的子类,并调用configure方法

public class ServletInitializer extends SpringBootServletInitializer {

   @Override
   protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
       //传入SpringBoot应用的主程序
      return application.sources(SpringBootWebApplication.class);
   }
}

5.启动服务器就可以使用。

底层原理

JAR包:执行SpringBoot主类的main方法,启动ioc容器,创建嵌入式的Servlet容器。
WAR包:启动Tomcat服务器,服务器启动SpringBoot应用SpringBootServletInitializer,然后启动ioc容器。
查看Servlet3.0及以上的运行规则
1)服务器启动(web应用启动)会创建当前web应用里面每一个jar包里面ServletContainerInitializer实例。

2)ServletContainerInitializer的实现放在jar包的META-INF/services文件夹下,有一个名为javax.servlet.ServletContainerInitializer的文件,内容就是ServletContainerInitializer的实现类的全类名。

3)还可以使用@HandlesTypes,在应用启动的时候加载我们感兴趣的类。

流程
1.启动Tomcat
2.查看文件内容
org\springframework\spring-web\4.3.14.RELEASE\spring-web-4.3.14.RELEASE.jar!\META-INF\services\javax.servlet.ServletContainerInitializer:
Spring的web模块里面有这个文件:org.springframework.web.SpringServletContainerInitializer
3.SpringServletContainerInitializer将@HandlesTypes(WebApplicationInitializer.class)标注的所有这个类型的类都传入到onStartup方法的泛型参数Set<Class<?>>中;为这些WebApplicationInitializer类型的类创建实例
4.每一个WebApplicationInitializer都调用自己的onStartup
SpringBoot使用外部Web容器的解决方案

5.相当于我们的SpringBootServletInitializer的类会被创建对象,并执行onStartup方法
6.SpringBootServletInitializer实例执行onStartup的时候会createRootApplicationContext,创建容器。源码查看:

protected WebApplicationContext createRootApplicationContext(
      ServletContext servletContext) {
    //1、创建SpringApplicationBuilder
   SpringApplicationBuilder builder = createSpringApplicationBuilder();
   StandardServletEnvironment environment = new StandardServletEnvironment();
   environment.initPropertySources(servletContext, null);
   builder.environment(environment);
   builder.main(getClass());
   ApplicationContext parent = getExistingRootWebApplicationContext(servletContext);
   if (parent != null) {
      this.logger.info("Root context already created (using as parent).");
      servletContext.setAttribute(
            WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, null);
      builder.initializers(new ParentContextApplicationContextInitializer(parent));
   }
   builder.initializers(
         new ServletContextApplicationContextInitializer(servletContext));
   builder.contextClass(AnnotationConfigEmbeddedWebApplicationContext.class);
    
    //调用configure方法,子类重写了这个方法,将SpringBoot的主程序类传入了进来
   builder = configure(builder);
    
    //使用builder创建一个Spring应用
   SpringApplication application = builder.build();
   if (application.getSources().isEmpty() && AnnotationUtils
         .findAnnotation(getClass(), Configuration.class) != null) {
      application.getSources().add(getClass());
   }
   Assert.state(!application.getSources().isEmpty(),
         "No SpringApplication sources have been defined. Either override the "
               + "configure method or add an @Configuration annotation");
   // Ensure error pages are registered
   if (this.registerErrorPageFilter) {
      application.getSources().add(ErrorPageFilterConfiguration.class);
   }
    //启动Spring应用
   return run(application);
}

7.Spring的应用就启动并且创建IOC容器

public ConfigurableApplicationContext run(String... args) {
   StopWatch stopWatch = new StopWatch();
   stopWatch.start();
   ConfigurableApplicationContext context = null;
   FailureAnalyzers analyzers = null;
   configureHeadlessProperty();
   SpringApplicationRunListeners listeners = getRunListeners(args);
   listeners.starting();
   try {
      ApplicationArguments applicationArguments = new DefaultApplicationArguments(
            args);
      ConfigurableEnvironment environment = prepareEnvironment(listeners,
            applicationArguments);
      Banner printedBanner = printBanner(environment);
      context = createApplicationContext();
      analyzers = new FailureAnalyzers(context);
      prepareContext(context, environment, listeners, applicationArguments,
            printedBanner);
       
       //刷新IOC容器
      refreshContext(context);
      afterRefresh(context, applicationArguments);
      listeners.finished(context, null);
      stopWatch.stop();
      if (this.logStartupInfo) {
         new StartupInfoLogger(this.mainApplicationClass)
               .logStarted(getApplicationLog(), stopWatch);
      }
      return context;
   }
   catch (Throwable ex) {
      handleRunFailure(context, listeners, analyzers, ex);
      throw new IllegalStateException(ex);
   }
}

结论:启动Servlet容器,再启动SpringBoot应用文章来源地址https://www.toymoban.com/news/detail-837893.html

到了这里,关于SpringBoot使用外部Web容器的解决方案的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • T599聚合物电容器:在汽车应用中提供更长的使用寿命的解决方案

    自从电子技术被引入汽车工业以来,汽车的技术含量一直在提升。诸多技术被应用在汽车上,使汽车的形象更接近于轮子上的超级计算机。更多传感器、更强大的计算能力和电力被装载到汽车上,汽车应用中的电子产品数量正在迅速增长。随着电动汽车和自动驾驶汽车的发展

    2024年02月11日
    浏览(59)
  • WEB使用WebSocket调用打印机:发票打印、套打打印解决方案

    WebSocket是一种在单个TCP连接上进行全双工通信的协议。它在Web浏览器和服务器之间建立持久连接,使得双方可以实时地发送数据。与HTTP不同,WebSocket连接一旦建立,将持续存在,直到明确关闭。 二、打印机与WebSocket的集成 要将打印机与WebSocket集成,首先需要在服务器端实现

    2024年02月03日
    浏览(70)
  • 在 Unity 解决方案中引用外部工程(.csproj)或 NuGet 包

    本人近期制作一服务端和客户端程序,采用下列架构实现: 服务端(Server.exe) 中间件(Shared.dll,实现两端共享的那部分代码) 客户端(Client.exe,用 Unity 实现) 在不使用 Unity 的情况下,一般把三个工程(.csproj)放入同一解决方案(.sln),然后在服务端和客户端添加对中

    2024年02月02日
    浏览(32)
  • Android13关于获取外部存储文件的相关问题及解决方案记录

      Android的学习路上... 测试设备:vivo X90s 安卓版本: Android13 开发环境:AndroidStudio Flamingo SDK:33 最近我在Android13的环境下尝试写一个 文件选择器 ,以便日后的开发使用。但是我们知道,从Android13 (API33) 开始,外部存储权限发生了变化,要想读取外部存储文件,使用原来的权

    2024年01月15日
    浏览(59)
  • 外部navicat无法连接mysql数据库的问题原因及解决方案

    问题起因是这样:在linux操作中的docker中部署了一个数据库,数据库启动之后,端口也映射了(创建容器时用 -p 30036:3306进行的映射),但是在外不想使用navicat连接时,怎么都连不上,本人遇到的问题如下 一、端口虽然映射了,但是服务器上的30036端口并未对外开放,因此要先开

    2024年02月07日
    浏览(51)
  • Springboot3整合使用ja-captcha行为验证码解决方案

    截止到目前(2023-04-20),Springboot最新稳定版本已经迭代到3.0.5,而我们项目中使用的行为验证码框架 aj-captcha 还没有适配Springboot3,码云上类似的请求也没有得到过回应,于是决定自己动手适配一下,研究下来发现适配3.x并没有那么难,这里记录一下适配过程,希望能帮到他人

    2023年04月20日
    浏览(38)
  • 【解决方案】‘python‘ 不是内部或外部命令,也不是可运行的程序或批处理文件

    有时候,在 cmd 中输入 python,会提醒 ‘python’ 不是内部或外部命令,也不是可运行的程序或批处理文件。 我将python安装在E盘之后,输入python,显示如下问题 这个问题本质其实就是,windows的cmd并不能识别python这个符号(即无法识别这个符号是一个可执行程序),因为windows这

    2024年02月14日
    浏览(61)
  • 解决docker容器之间网络互通 启动web服务只能本地localhost访问无法从外部访问

    docker容器之间相互访问 1.查看当前的网络 Copy [root@host ~]# docker network ls NETWORK ID          NAME                DRIVER              SCOPE 3dd4643bb158        bridge              bridge              local 748b765aca52        host                host                local 4d59a0cd3ff

    2024年02月10日
    浏览(48)
  • 【容器】K8s容器内部dns解析慢解决方案

    K8s内,要对做内部域名解析的劫持,解析 *.lol.com 至 172.34.18.12。 通过在coredns的配置文件配置 *.lol.com 的泛域名解析(如下所示),能够解析成功。但是在容器内部解析公网/内部地址慢。正常的http请求花费5-6秒。 DNS解析慢可能出现的问题在解析链路的各个环节。我们按照解析

    2024年01月25日
    浏览(43)
  • Modelsim恢复编辑器的解决方案——只能将外部编辑器删除后,重新匹配编辑器

    1,Modelsim和Questasim是相互兼容的,配置的编辑器变成了sublime,且更换不了编辑器 2,解决问题的方案,还是没得到解决 在网上搜索了:Modelsim如何恢复默认编辑器。类似相关的文档,都没有得到解决。 主要参考文献: 1,modelsim更改默认编辑器以及恢复默认编辑器 上述文章,

    2024年02月13日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包