SPI与打破双亲委派

[TOC]

面向的对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。 Java SPI就是提供这样的一个机制:为某个接口寻找服务实现的机制。

  1. 实现类的java包位置要放在主程序的classpath中;
  2. 在实现类的jar包的META-INF/services目录下创建一个以“接口全限定名”为命名的文件,内容为实现类的全限定名;
  3. 主程序通过java.util.ServiceLoder动态装载实现模块,它通过扫描META-INF/services目录下的配置文件找到实现类的全限定名,把类加载到JVM;

img

接口:java.sql.Driver,定义在java.sql包中,包所在的位置是:jdk\jre\lib\rt.jar中,java.sql包中还提供了其它相应的类和接口比如管理驱动的类:DriverManager类,很明显java.sql包是由BootstrapClassloader加载器加载的;而接口的实现类com.mysql.jdbc.Driver是由第三方实现的类库,由AppClassLoader加载器进行加载的,我们的问题是DriverManager再获取链接的时候必然要加载到com.mysql.jdbc.Driver类,这就是由BootstrapClassloader加载的类使用了由AppClassLoader加载的类,很明显和双亲委托机制的原理相悖,那它是怎么解决这个问题的?这就引申了我们第二个问题:如何打破双亲委派机制?

tomcat

和 jdk 提供的其它 SPI 一样,需要在 META-INF/services/javax.servlet.ServletContainerInitializer 文件中指定该类名

image-20210330205333633