1.定义
ServiceLoader是SPI(Service Provider Interface)中的服务类加载的核心类
2.破坏双亲
SPI 的接口由 Java 核心库来提供,而这些 SPI 的实现代码则是作为 Java 应用所依赖的 jar 包被包含进类路径(CLASSPATH)里。SPI接口中的代码经常需要加载具体的实现类。那么问题来了,SPI的接口是Java核心库的一部分,是由引导类加载器来加载的;SPI的实现类是由系统类加载器来加载的。引导类加载器是无法找到 SPI 的实现类的,因为依照双亲委派模型,BootstrapClassloader无法委派AppClassLoader来加载类
线程上下文类加载器破坏了双亲委派模型,可以在执行线程中抛弃双亲委派加载链模式,使程序可以逆向使用类加载器
1. 如果不想不破坏双亲委派模型,只要去重写findClass方法
2. 如果想要去破坏双亲委派模型,需要去重写loadClass方法
3.实例ServiceLoder
为什么这么搞呢,我觉得就是插拔式的,用就加上不用就不用,对代码一点侵入都没有
创建接口
public interface LoaderInterface {
void interfaceTest();
}
两个实现类
public class ImpTest1 implements LoaderInterface{
@Override
public void interfaceTest() {
System.out.println("我是 1");
}
}
public class ImpTest1 implements LoaderInterface{
@Override
public void interfaceTest() {
System.out.println("我是 1");
}
}
指定实现类
META-INF/services目录下建立一个文本文件,文件名字为接口完全限定名,内容为实现类的完全限定名
使用main方法调用
public class TestServiceLoader {
public static void main(String[] args) {
ServiceLoader<LoaderInterface> ins = ServiceLoader.load(LoaderInterface.class);
for(LoaderInterface in : ins) {
in.interfaceTest();
}
}
}
输出结果为