关于SPI打破双亲委派机制的一点见解

本文探讨了SPI如何在Java中打破双亲委派机制,但同时仍然使用该机制。双亲委派机制确保类加载器按层次递归加载类,而SPI允许子加载器在特定情况下加载本应由父加载器处理的类。通过JDBC驱动加载的示例,解释了Bootstrap Classloader如何委托给AppClassloader加载类,从而在保持双亲委派的同时,实现代理机制的灵活应用。
摘要由CSDN通过智能技术生成

先说结论

个人理解,“SPI打破双亲委派”的说法并不是说完全突破双亲委派直接加载,而是指在本应由父加载器加载的位置委托子加载器去加载,实际上最后还是会走双亲委派的流程。

什么是双亲委派机制(parents deletation model)

The Java platform uses a delegation model for loading classes. The basic idea is that every class loader has a “parent” class loader. When loading a class, a class loader first “delegates” the search for the class to its parent class loader before attempting to find the class itself.

由于翻译问题,这里双亲的 “双” 并没有太多特殊含义,也可以理解为父亲委派。简单来说,当一个类加载器得到一个类加载任务 T 的时候,首先会委派其 parent A 去加载,A 拿到任务后,也会进一步委派到 A 的 parent B。层层向上递归直到委派到启动类加载器。但我们知道,每个 classloader 负责的加载域是不一样的,启动类加载器需根据 T 给出的类全限定名(如 com.demo.Test)在其所负责的域里搜寻此类字节码,如果找到,则加载之;如果找不到,则表示无法加载,把代理权限往下(父->子)转移,直到某个加载器在负责的加载域中找到该类为止。
举个例子,孙子要买玩具,会先问爸爸有没有买过这个玩具,爸爸会问爷爷有没有买过,如果买过,那下一辈就不需要再买了。但是不同年龄层次的人了解的玩具肯定是不同的,如果爷爷没见过这种玩具,就会去让爸爸买,爸爸也没见过就会去让孙子买,大概就是这个意思吧。
ClassLoader层级图
父加载器与子加载器的关系并不是继承关系,而是组合关系!
父加载器与子加载器的关系并不是继承关系,而是组合关系!
父加载器与子加载器的关系并不是继承关系,而是组合关系!
重要的事情说三遍。

什么是SPI

SPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用框架扩展和替换组件。
举个例子,JDBC中,jdk只定义了Driver这个驱动类接口,而具体的实现由厂商自己开发。这里不是我们讨论的重点,可以从这篇文章中窥得一二
传送门
Java SPI机制

Java中关键的类加载器

与之前图相对应,Java中中比较核心的类加载器分别为

sun.misc.Launcher.ExtClassLoader
sun.misc.Launcher.AppClassLoader

这两个加载器都继承自URLClassLoader,再往上继承自SecureClassLoader,顶级抽象类便是ClassLoader。想要了解的同学可以去翻一下源码。

在Launcher类的构造器中,会将ExtClassLoader设置为AppClassLoader的父加载器。

public Launcher() {
   
        Launcher.ExtClassLoader var1;
        try {
   
            var1 = Launcher.ExtClassLoader.getExtClassLoader();
        } catch (IOException var10) {
   
            throw new InternalError("Could not create extension class loader", var10);
        }

        try {
   
            this.loader = Launcher.AppClassLoader.getAppClassLoader(var1);
        } catch (IOException var9) {
   
            throw new InternalError("Could not create application class loader", var9);
        }

        Thread.currentThread().
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值