Spring实际上是如何引导启动的?

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

文档非常清楚地解释了所有内容。 - Sotirios Delimanolis
2个回答

47

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

以下是翻译内容:
  1. 用户正在部署Web应用程序WAR文件。
  2. Servlet容器(Tomcat)读取web.xml文件。
  3. Servlet容器实例化ContextLoaderListener监听器(如果在web.xml中定义为<listener>),并执行以下操作:
    1. ContextLoaderListener创建新的WebApplicationContext,使用应用程序上下文XML配置。
    2. 您的ROOT上下文bean将由应用程序上下文中的BeanFactory注册和实例化。
  4. DispatcherServletServlet容器实例化。
    1. DispatcherServlet使用ROOT上下文作为其父上下文,创建自己的WebApplicationContext(默认为WEB-INF/{servletName}-servlet.xml)。
    2. 您的Servlet bean将由应用程序上下文中的BeanFactory注册和实例化。
    3. DispatcherServlet会在必要时注册一些默认的bean。

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

这是使用Servlet 3功能可以实现的。

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

使用基于Java的方法更加灵活。您可以将上下文创建交给DispatcherServlet,甚至可以将整个DispatcherServlet实例化交给servlet容器(只需注册servlet DispatcherServlet.class而不是其实例)。


如果我没有在web.xml中指定监听器,Tomcat如何找到ContextLoaderListener? - user3163426
在第一个场景中,ContextLoaderListener 必须在 web.xml 文件中声明为 <listener>web.xml 的结构和位置由 Servlet 规范明确定义。Tomcat 知道在哪里找到该文件以及如何处理其内容。 - Pavel Horal
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <servlet> <servlet-name>mvc-dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mvc-dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app> - user3163426
我的意思是,在我的默认示例中,我没有添加一些监听器,但所有的工作都正常。 - user3163426
1
FYI:Tomcat 7 的某些版本适用于第二种“非 web.xml”方法,某些版本则不适用。我发现 7.0.27 不行,而 7.0.69 可以。希望对某些人有帮助。 - davidfrancis
显示剩余7条评论

3

一个 ServletContextListener 是否真的是执行 SQL 迁移脚本的最佳位置?目前我不确定我的生产服务器何时以及如何应用这些脚本,我正在考虑在 ServletContextListener#contextInitialized 中执行此操作。 - Stefan Falk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接