Spring Boot一个非常突出的优点就是不需要我们额外再部署Servlet容器,它内置了多种容器的支持。我们可以通过配置来指定我们需要的容器。
本文以我们平时最常使用的容器Tomcat为列来介绍以下两个知识点:
在Spring Boot中,怎么进行Tomcat的深度配置。
Spring Boot整合启动Tomcat的流程对于看源代码,每个人都有自己的方法。我自己在看源代码的时候喜欢结合IDEA的Debug功能一起看。比如说现在我们要研究Spring Boot是在哪个环节点启动Tomcat的,
我的思路是:Tomcat在启动时会调用各个组件的init方法和start方法,那么我只需要在这些方法上打上端点,然后就能在调用栈上看出Spring Boot是在哪个环节点启用
Tomcat的了。
按照这个思路,我在Tomcat的Connector组件的init方法上打了端点,通过调用栈能很清楚的看出Spring Boot是在容器的onRefresh方法中调用Tomcat的。
protected void onRefresh() { super.onRefresh(); try { this.createWebServer(); } catch (Throwable var2) { throw new ApplicationContextException("Unable to start web server", var2); } }找到了调用点,那么一切都好办了。从上面的方法中可以看出,重点内容就在this.createWebServer()这个方法中。
在Spring Boot中使用的容器类是ServletWebServerApplicationContext系列的容器,这个系列的容器可以内嵌Web容器。这个我们
可以从这个容器的属性和方法中可以看出来。
下面是TomcatServletWebServerFactory的getWebServer方法。
public class TomcatServletWebServerFactory的getWebServer{ //... @Override public WebServer getWebServer(ServletContextInitializer... initializers) { //创建Tomcat容器 Tomcat tomcat = new Tomcat(); File baseDir = (this.baseDirectory != null ? this.baseDirectory : createTempDir("tomcat")); tomcat.setBaseDir(baseDir.getAbsolutePath()); //创建连接器,默认NIO模式,可以通过WebServerFactoryCustomizer改变具体模式 Connector connector = new Connector(this.protocol); tomcat.getService().addConnector(connector); //自定义连接器 customizeConnector(connector); tomcat.setConnector(connector); tomcat.getHost().setAutoDeploy(false); configureEngine(tomcat.getEngine()); //可以通过WebServerFactoryCustomizer添加额外的连接器,这边将这些连接器绑定到Tomcat for (Connector additionalConnector : this.additionalTomcatConnectors) { tomcat.getService().addConnector(additionalConnector); } //组测Listener、Filter和Servlet,自定义Context等操作 //这个方法可以重点看下 prepareContext(tomcat.getHost(), initializers); //创建TomcatWebServer,并调用start方法 return getTomcatWebServer(tomcat); } //内嵌的Tomcat容器 public TomcatWebServer(Tomcat tomcat, boolean autoStart) { Assert.notNull(tomcat, "Tomcat Server must not be null"); this.tomcat = tomcat; this.autoStart = autoStart; //这边触发Tomcat的启动流程,是Tomcat启动的入口点 initialize(); } //...省略部分代码 }至此Spring Boot内嵌的Tomcat已将顺序启动了。那么Spring Boot是在什么时候注册DispatchServlet的呢?
配置Listener、Filter和ServletSpring Boot配置Listener、Filter和Servlet可以參考我之前写的文章Spring Boot使用嵌入式容器,那怎么配置自定义Filter呢
推荐使用ServletListenerRegistrationBean、FilterRegistrationBean和ServletRegistrationBean的方式注册Listener、Filter和Servlet。
Spring Boot注册DispatcherServlet在传统的Spring MVC项目中,我们都会在web.xml中注册DispatcherServlet这个入口类,那么在Spring Boot中是在哪里注册的呢?