Spring Boot使用外部Servlet容器

更多信息:

本篇算是学习笔记

视频
尚硅谷
配置文件的信息
Spring Boot文档
狂神老师的bilibli账号:如果想学相关的知识可以关注一下
编辑器:IntelliJ IDEA 2020.1



使用外部Servlet容器

嵌入式Servlet容器
优点:简单、便捷
缺点:不支持JSP、优化定制比较复杂、自己编写嵌入式Servlet容器的创建工厂
解决方法:如果想要支持JSP,我们可以使用外部Servlet容器

外置的Servlet容器:外面安装Tomcat—应用war包的方式打包;

创建项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
启动方式:打成war包的方式放在服务器,或是把服务器整合到IntelliJ IDEA

将服务器整合到IntelliJ IDEA

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
将嵌入式的Tomcat指定为provide
在这里插入图片描述

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

在这里插入图片描述
为了使用这个实现类的configure方法

package com.atguigu.springboot;

import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

/**
 * SpringApplicationBuilder: Spring应用构建器调用sources方法
 * 传入SpringBoot04WebJspApplication.class的主程序
 */
public class ServletInitializer extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        //传入主程序
        return application.sources(SpringBoot04WebJspApplication.class);
    }

}

注意:当我们直接启动项目的主程序是无法启动成功的


原理

jar包,我们直接启动项目的主程序是可以启动成功的启动ioc容器,创建嵌入式的Servlet容器;

war包:我们不能直接运行主方法,启动服务器,服务器帮我们启动SpringBoot应用(SpringBootServletInitializer支持),启动ioc容器;

在这里插入图片描述
文件内容就是ServletContainerInitializer的实现类的全类名
在这里插入图片描述

流程

启动Servlet容器,再启动SpringBoot应用

  1. 启动Tomcat

  2. jrepository\org\springframework\spring-web\5.3.2\spring-web-5.3.2.jar!\META-INF\services\javax.servlet.ServletContainerInitializer

    Spring的web模块里面有这个文件:org.springframework.web.SpringServletContainerInitializer
    当项目启动时,我们要创建它的实例对象

在这里插入图片描述
SpringServletContainerInitializer
在这里插入图片描述
WebApplicationInitializer
在这里插入图片描述

ServletInitializer
SpringBootServletInitializer实例执行onStartup的时候会createRootApplicationContext;创建容器
在这里插入图片描述
在这里插入图片描述
createRootApplicationContext方法

 protected WebApplicationContext createRootApplicationContext(ServletContext servletContext) {
 		//创建SpringApplicationBuilder 
        SpringApplicationBuilder builder = this.createSpringApplicationBuilder();
        //设置主类
        builder.main(this.getClass());
        ApplicationContext parent = this.getExistingRootWebApplicationContext(servletContext);
        if (parent != null) {
            this.logger.info("Root context already created (using as parent).");
            servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, (Object)null);
            builder.initializers(new ApplicationContextInitializer[]{new ParentContextApplicationContextInitializer(parent)});
        }

        builder.initializers(new ApplicationContextInitializer[]{new ServletContextApplicationContextInitializer(servletContext)});
        builder.contextFactory((webApplicationType) -> {
            return new AnnotationConfigServletWebServerApplicationContext();
        });
        //调用configure方法,返回SpringApplicationBuilder
        //子类会重写将我们的主程序类导入
        builder = this.configure(builder);
        builder.listeners(new ApplicationListener[]{new SpringBootServletInitializer.WebEnvironmentPropertySourceInitializer(servletContext)});
        //使用builder创建Spring应用
        SpringApplication application = builder.build();
        if (application.getAllSources().isEmpty() && MergedAnnotations.from(this.getClass(), SearchStrategy.TYPE_HIERARCHY).isPresent(Configuration.class)) {
            application.addPrimarySources(Collections.singleton(this.getClass()));
        }

        Assert.state(!application.getAllSources().isEmpty(), "No SpringApplication sources have been defined. Either override the configure method or add an @Configuration annotation");
        if (this.registerErrorPageFilter) {
            application.addPrimarySources(Collections.singleton(ErrorPageFilterConfiguration.class));
        }

        application.setRegisterShutdownHook(false);
        //启动spring应用
        return this.run(application);
    }

run方法
在这里插入图片描述
在这里插入图片描述







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值