Spring Boot 支持以下内嵌的 Web 容器:
这些内嵌的 Web 容器都可以在 Spring Boot 应用中直接使用,无需额外的安装和配置。Spring Boot 会自动根据项目的依赖和配置来选择合适的 Web 容器,并进行相应的配置和启动。
你可以根据项目的需求和特点选择适合的 Web 容器。例如,如果对性能有较高要求,可以考虑使用 Undertow;如果需要与现有 Tomcat 环境集成,则可以选择 Tomcat。
以jetty为例,我们只需要将默认的tomcat依赖排除,并将jetty依赖引入,即可完成内嵌web容器的切换。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!--1、移除tomcat依赖(exclusions:排除)--> <exclusions> <exclusion> <artifactId>spring-boot-starter-tomcat</artifactId> <groupId>org.springframework.boot</groupId> </exclusion> </exclusions></dependency><!--2、加入jetty依赖--><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jetty</artifactId></dependency>
启动项目,我们可以看到,jetty确实启动了。
Spring Boot 内嵌 Web 容器的启动原理可以概括为以下几个步骤:
相关源码如下:
SpringApplication类createApplicationContext方法,根据当前web应用的类型选择匹配的应用上下文类型,这边会创建AnnotationConfigServletWebServerApplicationContext。
protected ConfigurableApplicationContext createApplicationContext() { Class<?> contextClass = this.applicationContextClass; if (contextClass == null) { try { switch (this.webApplicationType) { case SERVLET: contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS); break; case REACTIVE: contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS); break; default: contextClass = Class.forName(DEFAULT_CONTEXT_CLASS); } } catch (ClassNotFoundException ex) { throw new IllegalStateException( "Unable create a default ApplicationContext, please specify an ApplicationContextClass", ex); } } return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass); }
AnnotationConfigServletWebServerApplicationContext类createWebServer方法,会创建我们配置的web容器。
private void createWebServer() { WebServer webServer = this.webServer; ServletContext servletContext = getServletContext(); if (webServer == null && servletContext == null) { ServletWebServerFactory factory = getWebServerFactory(); this.webServer = factory.getWebServer(getSelfInitializer()); getBeanFactory().registerSingleton("webServerGracefulShutdown", new WebServerGracefulShutdownLifecycle(this.webServer)); getBeanFactory().registerSingleton("webServerStartStop", new WebServerStartStopLifecycle(this, this.webServer)); } else if (servletContext != null) { try { getSelfInitializer().onStartup(servletContext); } catch (ServletException ex) { throw new ApplicationContextException("Cannot initialize servlet context", ex); } } initPropertySources(); }
这边使用了工厂模式,不同的web容器有自己的工厂。
这边我们以TomcatServletWebServerFactory为例,看下它的getWebServerFactory方法。
public WebServer getWebServer(ServletContextInitializer... initializers) { if (this.disableMBeanRegistry) { Registry.disableRegistry(); } Tomcat tomcat = new Tomcat(); File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat"); tomcat.setBaseDir(baseDir.getAbsolutePath()); Connector connector = new Connector(this.protocol); connector.setThrowOnFailure(true); tomcat.getService().addConnector(connector); customizeConnector(connector); tomcat.setConnector(connector); tomcat.getHost().setAutoDeploy(false); configureEngine(tomcat.getEngine()); for (Connector additionalConnector : this.additionalTomcatConnectors) { tomcat.getService().addConnector(additionalConnector); } prepareContext(tomcat.getHost(), initializers); return getTomcatWebServer(tomcat); }
这边创建了tomcat容器并初始化,然后返回。
本文链接:http://www.28at.com/showinfo-26-88925-0.htmlSpring Boot 内嵌 Web 容器启动原理,惊爆你的眼球!
声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com
上一篇: 关于 Python 的十个核心概念精讲
下一篇: 一文彻底搞明白享元模式