首页 > 其他分享 >SpringBoot使用外部Web容器的解决方案

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

时间:2024-03-07 11:34:13浏览次数:28  
标签:容器 SpringBoot Web 解决方案 builder application context new

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
image

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

标签:容器,SpringBoot,Web,解决方案,builder,application,context,new
From: https://www.cnblogs.com/lisong0626/p/18058525

相关文章

  • 大厂的视频推荐索引构建解决方案
    关注我,紧跟本系列专栏文章,咱们下篇再续!作者简介:魔都技术专家兼架构,多家大厂后端一线研发经验,各大技术社区头部专家博主。具有丰富的引领团队经验,深厚业务架构和解决方案的积累。负责:中央/分销预订系统性能优化活动&优惠券等营销中台建设交易平台及数据中台等架构和开发设计......
  • WebApi后端实现大文件分片上传
    放开上传大小限制放开代码|框架层限制在Program.cs文件中添加如下代码不然会出现下面的限制错误builder.Services.Configure(x=>{x.AllowSynchronousIO=true;//配置可以同步请求读取流数据x.Limits.MaxRequestBodySize=int.MaxValue;}).Configure(x=>{x.A......
  • NetCore Rtsp视频流转Websocket实现Web实时查看摄像头
    .NetCoreRtsp视频流转Websocket实现Web实时查看摄像头最近工作中遇到需求需要实现这个功能,网上找了很多方案,大都是转为视频文件保存,实时查看的方案倒比较少,最终自己慢慢琢磨了很久在windows系统下实现了,里面的核心思路是:由FFmpeg.AutoGen捕捉Rtsp流视频帧,转为Bitmap,借由Websocke......
  • 玩转SpringBoot:SpringBoot的几种定时任务实现方式
    引言在现代软件开发中,定时任务是一种常见的需求,用于执行周期性的任务或在特定的时间点执行任务。这些任务可能涉及数据同步、数据备份、报表生成、缓存刷新等方面,对系统的稳定性和可靠性有着重要的影响。SpringBoot提供了强大且简单的定时任务功能,使开发人员能够轻松地管理和执......
  • 使用H5 实现 websocket 实现视频通讯 延迟较大
    发送端<div><canvasid="canvas"></canvas><videoid="srcvideo"></video></div><divid="xs"></div><buttonid="startBtn"onclick="setRecorder(format);&qu......
  • .NET Core WebAPI项目部署iis后Swagger 404问题解决
    .NETCoreWebAPI项目部署iis后Swagger404问题解决前言之前做了一个WebAPI的项目,我在文章中写到的是Docker方式部署,然后考虑到很多初学者用的是iis,下面讲解下iis如何部署WebAPI项目。环境准备iisASPNETCoreModuleV2重点.NETCoreRuntimeiis的配置这里就不讲了,主要讲解......
  • web实时消息推送方案 - (重要~个人简历要引申)
    一什么是消息推送推送的场景比较多,比如有人关注我的公众号,这时我就会收到一条推送消息,以此来吸引我点击打开应用。消息推送通常是指网站的运营工作等人员,通过某种工具对用户当前网页或移动设备APP进行的主动消息推送。消息推送一般又分为Web端消息推送和移动端消息推送。......
  • 从零开始搭建Springboot开发环境(Java8+Git+Maven+MySQL+Idea)之一步到位
    说明所谓万事开头难,对于初学Java和Springboot框架的小伙伴往往会花不少时间在开发环境搭建上面。究其原因其实还是不熟悉,作为在IT界摸爬滚打数年的老司机,对于各种开发环境搭建已经了然于胸,自己当年也是这么过来的。今天我就毕其功于一役,解放大家的时间,让凡人的环境配置见鬼去吧......
  • CTFshow web71-?
    查看根目录基本方法:var_dump print_rvar_export(上面两被过滤)var_dump(scandir("/");c=?><?php$a=newDirectoryIterator("glob:///*");foreach($aas$f){echo($f->__toString().'');}exit(0);?>后加exit(); 查看文件内容include("......
  • Day03---Web前端基础
    JavaScript的使用Javascript的定义JavaScript是运行在浏览器端的脚步语言,是由浏览器解释执行的,简称js,它能够让网页和用户有交互功能,增加良好的用户体验效果。前端开发三大块1、HTML:负责网页结构2、CSS:负责网页样式3、JavaScript:负责网页行为,比如:网页与用户的交互......