Java Spring实际上是如何引导的?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21714290/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 10:14:09  来源:igfitidea点击:

How is Spring actually bootstrap?

javaspringspring-mvc

提问by user3163426

  1. Does anybody know how Spring is actually bootstraps?
  2. Which instances created and by whom?
  3. I really want to know who creates instances of WebApplicationContext and ContextLoader. Is it work of Tomcat?
  1. 有谁知道 Spring 实际上是如何引导的?
  2. 哪些实例由谁创建?
  3. 我真的很想知道谁创建了 WebApplicationContext 和 ContextLoader 的实例。它是Tomcat的工作吗?

采纳答案by Pavel Horal

Servlet context listener (web.xml) approach

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

  1. A web application WAR is being deployed by user.
  2. Servlet container(Tomcat) reads web.xml.
  3. Servlet context listener ContextLoaderListeneris being instantiated (if defined as <listener>inside the web.xml) by servlet container.
    1. ContextLoaderListenercreates new WebApplicationContextwith application context XML configuration.
    2. Your ROOT context beans are registered and instantiated by BeanFactoryinside the application context.
  4. DispatcherServletis being instantiated by servlet container.
    1. DispatcherServletcreates its own WebApplicationContext(WEB-INF/{servletName}-servlet.xmlby default) with the ROOT context as its parent.
    2. Your servlet beans are registered and instantiated by BeanFactoryinside the application context.
    3. DispatcherServletregisters some default beans in case you did not provide them yourself.
  1. 用户正在部署 Web 应用程序 WAR 。
  2. Servlet 容器(Tomcat) 读取web.xml.
  3. Servlet 上下文侦听ContextLoaderListener器正在被 Servlet 容器实例化(如果定义为<listener>在 内部web.xml)。
    1. ContextLoaderListenerWebApplicationContext使用应用程序上下文 XML 配置创建新的。
    2. 您的 ROOT 上下文 beanBeanFactory在应用程序上下文中注册和实例化。
  4. DispatcherServlet正在被 servlet 容器实例化。
    1. DispatcherServlet使用 ROOT 上下文作为其父级创建自己的WebApplicationContextWEB-INF/{servletName}-servlet.xml默认情况下)。
    2. 您的 servlet beanBeanFactory在应用程序上下文中注册和实例化。
    3. DispatcherServlet注册一些默认 bean,以防您自己不提供它们。

Servlet container initializer (non web.xml) approach

Servlet 容器初始值设定项(非 web.xml)方法

This one is possible with Servlet 3 features.

这可以通过 Servlet 3 功能实现。

  1. A web application WAR is being deployed by user.
  2. Servlet containersearches for classes implementing ServletContainerInitializervia Java's ServiceLoader.
  3. Spring's SpringServletContainerInitializeris found and instantiated by servlet container.
  4. Spring's initializer readsweb application's class-path and searches for WebApplicationInitializerimplementations.
  5. Your WebApplicationInitializeris found (btw. check its JavaDoc!!!) and instantiated by SpringServletContainerInitializer.
    1. Your WebApplicationInitializercreates new ROOT WebApplicationContextwith XML or @Configurationbased configuration.
    2. Your WebApplicationInitializercreates new servlet WebApplicationContextwith XML or @Configurationbased configuration.
    3. Your WebApplicationInitializercreates and registers new DispatcherServletwith the context from previous step.
  6. Servlet containerfinishes the web application initialization and instantiates components which were registered by their class in previous steps (nonein my example).
  1. 用户正在部署 Web 应用程序 WAR 。
  2. Servlet 容器搜索ServletContainerInitializer通过 Java 的ServiceLoader.
  3. SpringSpringServletContainerInitializer由 servlet 容器找到并实例化
  4. Spring 的初始化程序读取Web 应用程序的类路径并搜索WebApplicationInitializer实现。
  5. WebApplicationInitializer被找到了(顺便说一句。检查它的 JavaDoc!!!)并通过SpringServletContainerInitializer.
    1. WebApplicationInitializerWebApplicationContext使用 XML 或@Configuration基于配置创建新的 ROOT 。
    2. WebApplicationInitializerWebApplicationContext使用 XML 或@Configuration基于配置创建新的 servlet 。
    3. WebApplicationInitializerDispatcherServlet在上一步的上下文中创建和注册新的。
  6. Servlet 容器完成 Web 应用程序初始化并实例化在前面步骤中由它们的类注册的组件(在我的示例中没有)。

Java based approach is much more flexible. You can leave the context creation to DispatcherServletor even the whole instantiation of DispatcherServletitself to servlet container (just register servlet DispatcherServlet.classinstead of its instance).

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

回答by JB Nizet

See http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/htmlsingle/#context-create.

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

The principle is to declare a ServletContextListener in the standard webapp descriptor (web.xml). Such a listener is indeed instantiated by the container and is called when the application is initialized and when it's destroyed.

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

Spring provides such a ServletContextListener: ContextLoaderListenerwhich, as its name indicates, loads a Spring context when the webapp is initialized.

Spring 提供了这样一个 ServletContextListener:ContextLoaderListener,顾名思义,它在 webapp 初始化时加载 Spring 上下文。