Spring Boot「19」WebApplicationInitializer 源码分析
01-WebApplicationInitializer
源码分析
ServletContainerInitializer
是 javax.servlet-api-*.jar 中定义的接口,在 web 容器启动时为提供给第三方组件机会做一些初始化的工作。使用的就是 Java SPI 机制,详细信息在下面的章节中介绍。例如,Tomcat 遵循了 Java SPI 自己实现了一套服务发现机制org.apache.catalina.startup.WebappServiceLoader
。
org.apache.catalina.startup.ContextConfig#processServletContainerInitializers
方法中,使用 WebappServiceLoader 加载 SPI javax.servlet.ServletContainerInitializer
的所有实现。
org.springframework.web.WebApplicationInitializer
由 spring-web-5.1.5.RELEASE.jar 提供,该包的**/META-INFO/services**目录下提供了对 SPI javax.servlet.ServletContainerInitializer
的实现org.springframework.web.SpringServletContainerInitializer
,并且标注其处理的类是WebApplicationInitializer.class
。
当我们在应用中实现WebApplicationInitializer
接口,并实现其中的方法onStartup
方法,就会在SpringServletContainerInitializer#onStartup
被调用时,逐个调用WebApplicationInitializer#onStartup
02-SPI 机制
SPI(Service Provider Interface)是 Java 6 引入的一种发现和加载特定接口实现的特性。它由四部分组成:
Service,一组接口或类,提供特定的功能或特性;
SPI,一个接口或抽象类,作为 1.中服务的代理或接入点;
Service Provider,2.中 SPI 的特定实现;一般配置在 /META-INF/services/ 文件夹下以 SPI 全量名为文件名,文件内容为服务提供者,即具体的特定实现。
ServiceLoader,
java.util.ServiceLoader
,SPI 机制的核心,用来发现并加载 Service Provider;
注:1 和 2 组成了 Java 生态系统中常被提到的 API。
02.1-java.sql.Driver
示例
完整代码参考gitee.com。
java.sql.Driver 是 SPI,mysql-connector-java-8.0.7-dmr.jar
hsqldb-2.3.4.jar
是两个不同的 Service Provider,所以在 jar 包中的**/META-INF/services/java.sql.Driver**中包含对应的具体实现类。
02.2-源码分析
java.sql.DriverManager 中有一个静态代码块,当该类初始化时会被调用。
继续追踪loadInitialDrivers()
方法的实现可以发现,该方法中包含了与上节示例中类似的代码:
执行完毕后,发现类路径下的两个实现类都被加载到 JVM 中。
[1] Java基础之SPI机制[2] Java Service Provider Interface[3] Java常用机制-SPI[4] 常见的SPI示例
版权声明: 本文为 InfoQ 作者【Samson】的原创文章。
原文链接:【http://xie.infoq.cn/article/c2bcacb386c5eee0707e6646b】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论