博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringBoot--引入和使用其它Servlet容器配置(Jetty、Undertow)
阅读量:2442 次
发布时间:2019-05-10

本文共 5763 字,大约阅读时间需要 19 分钟。

SpringBoot对Servlet容器的支持

在这里插入图片描述

Tomcat(默认使用)

org.springframework.boot
spring-boot-starter-web
引入web模块默认就是使用嵌入式的Tomcat作为Servlet容器;

Jetty

org.springframework.boot
spring-boot-starter-web
spring-boot-starter-tomcat
org.springframework.boot
spring-boot-starter-jetty
org.springframework.boot

Undertow

org.springframework.boot
spring-boot-starter-web
spring-boot-starter-tomcat
org.springframework.boot
spring-boot-starter-undertow
org.springframework.boot

使用外置的Servlet容器

  1. 嵌入式Servlet容器:应用打成可执行的jar

    • 优点:简单、便携;
    • 缺点:默认不支持JSP、优化定制比较复杂(使用定制器【ServerProperties、自定义EmbeddedServletContainerCustomizer】,自己编写嵌入式Servlet容器的创建工厂【EmbeddedServletContainerFactory】);
  2. 外置的Servlet容器:外面安装Tomcat—应用war包的方式打包;

步骤

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

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

org.springframework.boot
spring-boot-starter-tomcat
provided

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

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

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

原理

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

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lZrWQfzJ-1576159214901)(images/搜狗截图20180302221835.png)]

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); }}

转载地址:http://qwpqb.baihongyu.com/

你可能感兴趣的文章
ipad iphone开发_如何在iPhone或iPad上的消息中快速选择表情符号
查看>>
如何在iPhone和iPad上使用操作和共享扩展
查看>>
windows 网络唤醒_如何停止唤醒Windows PC的网络活动
查看>>
社交网站facebook_如何退出Facebook,Twitter,Google +和其他社交网络
查看>>
windows 所有者窗口_如何在任何版本的Windows中更改注册的PC所有者
查看>>
使用Prime提前一周观看新的Aquaman电影,方法如下
查看>>
为什么uber有星级_位智拼车和Uber / Lyft有什么区别?
查看>>
所需的密钥从密钥环中丢失_如果丢失U2F密钥该怎么办
查看>>
如何在Windows 10的设置中禁用建议横幅
查看>>
Pixel 3 XL上的开发人员选项将使您“隐藏”缺口
查看>>
kde gnome_KDE Apps如何在GNOME下运行?
查看>>
启动磁盘10.11.4_如何在Windows 8.1中检查应用程序的磁盘使用情况
查看>>
如何制作优质的YouTube视频
查看>>
如何在Windows 10的照片中启用暗模式
查看>>
新的Apple Watch面Kong即将到来,这就是它们的外观
查看>>
怎么打开avi文件文件损坏_什么是AVI文件(以及如何打开一个文件)?
查看>>
chrome恢复翻译选项_使用此隐藏选项使Chrome再次看起来正常
查看>>
python包的obo文件_出售:1976苹果1.仍然有效,要价$ 300,000 OBO
查看>>
技嘉主板控制机箱风扇_在机箱外为主板加电是否安全?
查看>>
bittorrent_最好的免费BitTorrent客户
查看>>