嵌入式Servlet容器:应用打成可执行的jar 优点:简单、便携;

缺点:默认不支持JSP、优化定制比较复杂

(使用定制器【ServerProperties/自定义EmbeddedServletContainerCustomizer】)

(自己编写嵌入式Servlet容器的创建工厂【EmbeddedServletContainerFactory】);

那么如果要使用外置的servlet呢?

应用war包的方式打包;

外置的Servlet容器:外面安装Tomcat---

步骤

一、必须创建一个war项目;(利用idea创建好目录结构)

二、将嵌入式的Tomcat指定为provided;

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring‐boot‐starter‐tomcat</artifactId>

<scope>provided</scope>

</dependency>

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

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

四、启动服务器就可以使用;

原理

jar包:执行SpringBoot主类的main方法,启动ioc容器,创建嵌入式的Servlet容器;

war包:启动服务器,服务器启动SpringBoot应用【SpringBootServletInitializer】,启动ioc容器;

servlet3.0(Spring注解版):

8.2.4  Shared libraries / runtimes pluggability: 规则:

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>;为这些WebApplicationInitializer类型的类创建实例;

4)、每一个WebApplicationInitializer都调用自己的onStartup;

五、相当于我们的SpringBootServletInitializer的类会被创建对象,并执行onStartup方法

六、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)); 15 }
builder.initializers(
new ServletContextApplicationContextInitializer(servletContext));
builder.contextClass(AnnotationConfigEmbeddedWebApplicationContext.class);
//调用configure方法,子类重写了这个方法,将SpringBoot的主程序类传入了进来
builder = configure(builder); 22
//使用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);
}

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

【串线篇】spring boot使用外置的Servlet容器的更多相关文章

  1. Spring Boot → 08:嵌入式Servlet容器自定义

    Spring Boot → 08:嵌入式Servlet容器自定义

  2. SpringBoot 源码解析 (七)----- Spring Boot的核心能力 - 自定义Servlet、Filter、Listener是如何注册到Tomcat容器中的?(SpringBoot实现SpringMvc的原理)

    上一篇我们讲了SpringBoot中Tomcat的启动过程,本篇我们接着讲在SpringBoot中如何向Tomcat中添加Servlet.Filter.Listener 自定义Servlet.Filt ...

  3. SpringBoot使用外置的Servlet容器

    SpringBoot默认使用嵌入式的Servlet容器,应用打包成可执行的jar包 优点:简单.便携 缺点:默认不支持jsp,优化定制比较复杂(使用定制器serverProperties.自定义Emb ...

  4. springboot外置的Servlet容器

    嵌入式Servlet容器:应用打成可执行的jar ​ 优点:简单.便携: ​ 缺点:默认不支持JSP.优化定制比较复杂(使用定制器[ServerProperties.自定义EmbeddedServle ...

  5. 使用外置的Servlet容器

    嵌入式Servlet容器: 优点:简单.便捷 缺点:默认不支持JSP.优化定制比较复杂(使用定制器[ServerProperties.自定义EmbeddedServletContainerCustom ...

  6. 从零开始通过idea插件将一个spring boot项目部署到docker容器里运行

    实操:将一个spring boot项目部署到docker容器里运行 实验需要的环境: 腾讯云+Ubuntu 16.04 x64+idea+插件docker integration+daocloud 第 ...

  7. spring boot本地开发与docker容器化部署的差异

    spring boot本地开发与docker容器化部署的差异: 1. 文件路径及文件名区别大小写: 本地开发环境为windows操作系统,是忽略大小写的,但容器中区分大小写 2. docker中的容器 ...

  8. 从.Net到Java学习第四篇——spring boot+redis

    从.Net到Java学习系列目录 “学习java已经十天,有时也怀念当初.net的经典,让这语言将你我相连,怀念你......”接上一篇,本篇使用到的框架redis.FastJSON. 环境准备 安装 ...

  9. 从.Net到Java学习第三篇——spring boot+mybatis+mysql

    从.Net到Java学习第一篇——开篇 环境:mysql5.7 新建mysql数据库demo,然后执行如下sql脚本进行数据表创建和数据初始化: -- ------------------------ ...

随机推荐

  1. IDEA 中常用快捷键的使用

    IDEA 中快捷键的使用 1:知道类名全局查找类:   Ctrl+Shift+Alt+N;      全局搜索: Ctrl+Shift+R 2:快速定位到类的文件夹: 3:  优化导入的类和包 (删除 ...

  2. FreeBSD上安装Cassandra 3.10

    哈哈,你居然点进来了,来吧,一起吐槽FreeBSD啊,装了一上午Cassandra 3.10都没有装成功, 终于,鄙人一条 shutdown -p now 结束了FreeBSD,默默打开了CentOS ...

  3. Ubuntu C/C++的编译环境

    Ubuntu缺省情况下,并没有提供C/C++的编译环境,因此还需要手动安装.但是如果单独安装gcc以及g++比较麻烦,幸运的是,Ubuntu提供了一个build-essential软件包.查看该软件包 ...

  4. datalist的模板里的label要绑定一个函数

    列下如何在前台绑定数据时呼叫後台方法 如下GetInfoByID是后台方法,Eval("ID").ToString()是你在前台绑定数据传入的字段名 <asp:Label I ...

  5. 阶段3 1.Mybatis_01.Mybatis课程介绍及环境搭建_04.mybatis概述

  6. 为终端配置proxy

    转自:https://my.oschina.net/u/818848/blog/677225?p=1 做开发的同学,应该都会经常接触终端,有些时候我们在终端会做一些网络操作,比如下载gradle包等, ...

  7. 【SD系列】SAP SD模块-送达方和售达方的区别和联系

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[SD系列]SAP SD模块-送达方和售达方的区 ...

  8. ionic3构建过程中遇到的找不到AndroidManifest.xml的问题

    问题如下: Failed to install 'ionic-plugin-keyboard': Error: ENOENT: no such file or directory, open '/Us ...

  9. 应用安全 - CMS - Discuz漏洞汇总

    SSV-90861 Date:2012 类型:敏感信息泄露 影响范围:DZ x2.5  POC:http://www.xx.xx/uc_server/control/admin/db.php http ...

  10. sourceInsight下标题栏显示文件完整路径

    用sourceInsight看代码方便,但是标题栏中不显示文件的完整路径,有时候就会很麻烦,做如下设置即可显示完整的路径 options -> preferences -> Display ...