spring-boot - 哪一段代码实际上为springMVC注册了调度程序servlet?

时间:2016-08-29 15:29:29

标签: java spring spring-mvc spring-boot

我试图找出spring-bootWebApplicationInitializer的哪个实现实际注册了调度程序servlet。

我没有发现SpringBootServletInitializer或其父类型的任何代码都是这样做的。

相反,AbstractDispatcherServletInitializer完成了这项工作,但它是抽象的,我无法在Eclipse的帮助下找到任何具体的实现。

那么,实际调用哪一段代码来为springMVC注册调度程序servlet?

这是后续问题:How does spring-boot able to serve specific url?

3 个答案:

答案 0 :(得分:18)

以下是最终注册DispatcherServlet的Spring Boot初始化步骤的说明。

示例代码

@EnableAutoConfiguration
public class TestSpring {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(TestSpring.class, args);
    }
}

Spring Boot初始化步骤

以下是步骤:

  1. SpringApplication.run()创建EmbeddedWebApplicationContext应用程序上下文;
  2. 调用其refresh()方法;
  3. 刷新过程会读取起始类TestSpring的注释。它寻找导入注释。 EnableAutoConfiguration就是其中之一。对于导入注释,刷新过程从注释value获取相应的类并调用其selectImports()方法;
  4. 如果是@EnableAutoConfiguration,则相应的班级为EnableAutoConfigurationImportSelectorselectImports()会从META-INF/spring.factories加载大量其他导入选择器;
  5. 此过程以递归方式继续。此外,还会读取这些导入选择器中的所有bean定义。即它包括由带有@Bean注释的方法定义的bean,即需要Spring上下文自动调用相应方法来实例化它们的bean;
  6. resfresh()继续并到达onRefresh(),内部调用createEmbeddedServletContainer()方法;
  7. 在上一步的读取bean定义中,搜索并实例化实现ServletContextInitializer的bean。其中之一是bean,由DispatcherServletAutoConfiguration.DispatcherServletRegistrationConfiguration#dispatcherServletRegistration()类型的ServletRegistrationBean方法定义,扩展ServletContextInitializer。正如你可以从类的名称猜测的那样,当调用它们的ServletContext方法时,这样的初始值设定项将给定的servlet(在本例中为 DispatcherServlet )添加到给定的onStartup();
  8. 创建了一个tomcat嵌入式服务器(尚未完全启动)。在上一步中找到的所有ServletContextInitializer都将传递给此tomcat初始化 - 这是调用那些onStartup()的{​​{1}}方法并创建ServletContextInitializer的地方并注册为servlet ;
  9. 应用程序上下文的DispatcherServlet结束;
  10. 调用onRefresh(),其中tomcat最终由finishRefresh();
  11. 启动
  12. 应用程序上下文的TomcatEmbeddedServletContainer.start()结束和其他最终初始化步骤;
  13. 该应用正在运行。

答案 1 :(得分:2)

当您在自动配置期间查找Spring Boot执行的操作时,您应该查看*AutoConfiguration类。在这种情况下,DispatcherServletAutoConfiguration

答案 2 :(得分:0)

如果要将Spring Boot应用程序部署为传统WAR,则Servlet 3.0 specification详细说明服务提供商如何设置它,以便3.0兼容的servlet容器将自动引导任何Web资产(Servlet,Filter, ServletContextInitializer' s)进入servlet容器。 "魔术"是在spring-web依赖中完成的。如果您取消它,那么您将找到文件" spring-web / META-INF / services / javax.servlet.ServletContainerInitializer"。打开文件,您将看到单行" org.springframework.web.SpringServletContainerInitializer"。此类委托给所有实现WebApplicationInitializer的类,更具体地说是它们的onStartup(ServletContext servletContext)方法。我在Spring Boot中已经知道了一个具体的类,即SpringBootServletInitializer