Spring究竟是如何引导的?

  1. 有谁知道Spring实际上是如何引导的?
  2. 创建了哪些实例以及由谁创建?
  3. 我真的想知道是谁创建了WebApplicationContext和ContextLoader的实例。 这是Tomcat的工作吗?

Servlet上下文侦听器(web.xml)方法

  1. 用户正在部署Web应用程序WAR。
  2. Servlet容器 (Tomcat)读取web.xml
  3. Servlet上下文侦听器ContextLoaderListener 由servlet容器实例化(如果在web.xml定义为 )。
    1. ContextLoaderListener使用应用程序上下文XML配置创建新的WebApplicationContext
    2. 您的ROOT上下文bean由应用程序上下文中的BeanFactory注册和实例化。
  4. DispatcherServlet 由servlet容器实例化。
    1. DispatcherServlet创建自己的WebApplicationContext (默认情况下为WEB-INF/{servletName}-servlet.xml ),ROOT上下文为其父项。
    2. 您的servlet bean由应用程序上下文中的BeanFactory注册和实例化。
    3. DispatcherServlet注册一些默认bean,以防您自己没有提供它们。

Servlet容器初始化程序(非web.xml)方法

Servlet 3的function可以实现这一function。

  1. 用户正在部署Web应用程序WAR。
  2. Servlet容器通过Java的ServiceLoader搜索实现ServletContainerInitializer类。
  3. Spring的SpringServletContainerInitializer 由servlet容器找到并实例化。
  4. Spring的初始化程序读取 Web应用程序的类路径并搜索WebApplicationInitializer实现。
  5. 找到你的WebApplicationInitializer (顺便说一句, 检查它的JavaDoc !!!并由SpringServletContainerInitializer实例化。
    1. WebApplicationContext使用基于XML或@Configuration的配置创建新的ROOT WebApplicationContext
    2. WebApplicationContext使用基于XML或@Configuration的配置创建新的servlet WebApplicationContext
    3. 您的WebApplicationInitializer使用上一步中的上下文创建并注册新的DispatcherServlet
  6. Servlet容器完成Web应用程序初始化并实例化其在前面的步骤中由其类注册的组件(在我的示例中没有 )。

基于Java的方法更灵活。 您可以将上下文创建保留到DispatcherServlet ,甚至将DispatcherServlet本身的整个实例保留到servlet容器中(只需注册servlet DispatcherServlet.class而不是其实例)。

请参阅http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/htmlsingle/#context-create 。

原理是在标准webapp描述符(web.xml)中声明ServletContextListener。 这样的监听器确实由容器实例化,并在应用程序初始化和销毁​​时被调用。

Spring提供了这样一个ServletContextListener: ContextLoaderListener ,正如其名称所示,在初始化webapp时加载Spring上下文。