Spring WebApplicationInitializer提供了一种在Servlet 3.0+兼容的servlet容器中配置Spring DispatcherServlet和ContextLoaderListener的编程方法。但它是如何工作的? servlet容器如何找到WebApplicationInitializer实现,它是否真的从类路径加载所有类?
答案 0 :(得分:9)
我假设您了解java SPI以及用于加载实现的java.util.ServiceLoader实用程序类的方式。其他please read it。
但简而言之,这个答案只是理解:如果有一个SPI,那么javax.servlet.ServletContainerInitializer
,
那么提供者应该实现它,并且必须在库jar文件的 META-INF / services / javax.servlet.ServletContainerInitializer 文件中声明实现 - Spring就是这样的提供者
在spring-web * .jar jar文件中声明这个并且有一个条目org.springframework.web.SpringServletContainerInitializer
然后ServletContainerInitializer的服务加载器可以加载实现。此加载特定于ServletContainer实现
我将解释这个特定于tomcat7 + ServletContainer。
Tomcat有LifecycleListeners,它们会监听生命周期事件,如启动,停止等。
org.apache.catalina.startup.ContextConfig
是ServletContext的启动事件监听器,用于配置 ServletContext 的属性以及关联的已定义servlet。
因此,当tomcat为Web应用程序初始化ServletContext
时,它将生成这样的事件,该事件将通知ContextConfig
甚至是监听方法。然后它会触发
它自己的processServletContainerInitializers方法,它扫描JAR以获取ServletContainerInitializer实现。
它通过将此职责委派给 WebappServiceLoader (Java的JAR ServiceLoader的变体)来实现这一点,他实际上负责从加载 ServletContainerInitializer 实现。 WEB-INF / lib 罐子。
因此,作为结论,控制流程将是这样的。
Tomcat初始化ServletContext
WebappServiceLoader在WEB-INF / lib jar中扫描 文件 META-INF / services / javax.servlet.ServletContainerInitializer 以便加载实现
SpringServletContainerInitializer
)
onStartup 方法将完成剩下的工作。HTH!
答案 1 :(得分:1)
来自docs:
该SPI的实现将由
自动检测 SpringServletContainerInitializer,它本身就是自举的 由任何Servlet 3.0容器自动完成。看到 SpringServletContainerInitializer或此引导的详细信息 机构。
和
运作机制
SpringServletContainerInitializer
这个类将被加载 实例化并由any调用其onStartup方法 假设在容器启动期间符合Servlet 3.0标准的容器 spring-web模块JAR存在于类路径中。 这通过JAR服务API {@link发生 ServiceLoader #load(Class)}方法检测弹簧网 模块 META-INF /服务/ javax.servlet.ServletContainerInitializer
服务提供商配置文件。见 http://download.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#Service%20Provider JAR服务API文档以及 8.2.4 部分 有关完整详细信息,请参阅Servlet 3.0最终草案规范。
所有文档都基本上是Servlet规范的一部分,用于检测实现SpringServletContainerInitializer
的{{1}},所以它一直到容器执行检测这些类的工作。