【串线篇】spring boot使用外置的Servlet容器
嵌入式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容器的更多相关文章
- Spring Boot → 08:嵌入式Servlet容器自定义
Spring Boot → 08:嵌入式Servlet容器自定义
- SpringBoot 源码解析 (七)----- Spring Boot的核心能力 - 自定义Servlet、Filter、Listener是如何注册到Tomcat容器中的?(SpringBoot实现SpringMvc的原理)
上一篇我们讲了SpringBoot中Tomcat的启动过程,本篇我们接着讲在SpringBoot中如何向Tomcat中添加Servlet.Filter.Listener 自定义Servlet.Filt ...
- SpringBoot使用外置的Servlet容器
SpringBoot默认使用嵌入式的Servlet容器,应用打包成可执行的jar包 优点:简单.便携 缺点:默认不支持jsp,优化定制比较复杂(使用定制器serverProperties.自定义Emb ...
- springboot外置的Servlet容器
嵌入式Servlet容器:应用打成可执行的jar 优点:简单.便携: 缺点:默认不支持JSP.优化定制比较复杂(使用定制器[ServerProperties.自定义EmbeddedServle ...
- 使用外置的Servlet容器
嵌入式Servlet容器: 优点:简单.便捷 缺点:默认不支持JSP.优化定制比较复杂(使用定制器[ServerProperties.自定义EmbeddedServletContainerCustom ...
- 从零开始通过idea插件将一个spring boot项目部署到docker容器里运行
实操:将一个spring boot项目部署到docker容器里运行 实验需要的环境: 腾讯云+Ubuntu 16.04 x64+idea+插件docker integration+daocloud 第 ...
- spring boot本地开发与docker容器化部署的差异
spring boot本地开发与docker容器化部署的差异: 1. 文件路径及文件名区别大小写: 本地开发环境为windows操作系统,是忽略大小写的,但容器中区分大小写 2. docker中的容器 ...
- 从.Net到Java学习第四篇——spring boot+redis
从.Net到Java学习系列目录 “学习java已经十天,有时也怀念当初.net的经典,让这语言将你我相连,怀念你......”接上一篇,本篇使用到的框架redis.FastJSON. 环境准备 安装 ...
- 从.Net到Java学习第三篇——spring boot+mybatis+mysql
从.Net到Java学习第一篇——开篇 环境:mysql5.7 新建mysql数据库demo,然后执行如下sql脚本进行数据表创建和数据初始化: -- ------------------------ ...
随机推荐
- 常量const实践
这篇文章写的很好:https://www.cnblogs.com/zhangfeionline/p/5882790.html 自己是实践: 1. 定义时必须初始化值,不然如下错误: 2. 3. 使用:
- Eclipse高版本无法兼容FatJar的问题解决
发现eclipse打包jar无法连带打包第三方lib,于是选择安装插件fatjar,现在说明fatjar安装过程: 1.安装方法: 1)下载安装: https://sourceforge.ne ...
- TCP/IP 网络模型
前言 互联网是怎么构成的,又是怎么运作的?什么是 TCP/IP 网络?为什么远隔万里的计算机可以互相通信?计算机网络作为 IT 行业的基石,是工程师永远绕不开的话题. 计算机网络的分层体系结构 计算机 ...
- apache-httpd2.2编译安装
1.下载源码包 wget http://mirrors.hust.edu.cn/apache/httpd-2.2.32.tar.gz2.解压源码包 tar -zxvf httpd-2.2.32.tar ...
- 操作系统(5)实验0——makefile的写法
之前GCC那部分我提到过,gcc啥啥啥啥傻傻的那个指令只能够编译简单的代码,如果要干大事(例如突然心血来潮写个c开头的神经网络库之类的),还是要写Makefile来编译.其实在Windows下通常用I ...
- 牛客练习赛46 E 华华和奕奕学物理 (树状数组)
https://ac.nowcoder.com/acm/contest/894/E 一开始写了一个简单的模拟 通过率只有5%...... 看题解真的理解了好久!!肥宅大哭orz 题解如下 最后一句:“ ...
- Oracle 查看一个数据库实例下面所有的表大小
1. 因为 oracle有一些 lob字段 在user_extents 里面取出来的结果不是表名, 所以需要与user_lobs 表做关联查询才可以 本来想通过 关联查询来实现, 发现字表查询更简单 ...
- keystone验证安装
以管理员的身份来请求鉴权的标识 keystone --os-tenant-name admin --os-username admin --os-password 123456 --os-auth- ...
- shell学习笔记3---shell变量
Shell变量的定义.赋值和删除 脚本语言在定义变量时通常不需要指明类型,直接赋值就可以,Shell 变量也遵循这个规则. 在 Bash shell 中,每一个变量的值都是字符串,无论你给变量赋值时有 ...
- 01-Django-urls
# Django系统- 环境 - python3.6 - django1.18- 参考资料 - [django中文教程](http://python.usyiyi.cn/)# 环境搭建- anacon ...