为啥说java spi破坏双亲委派模型( 三 )
synchronized (getClassLoadingLock(name)) { // First, check if the class has already been loaded Class\u0026lt;?\u0026gt; c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); try { if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader }? if (c == null) { // If still not found, then invoke findClass in order // to find the class. long t1 = System.nanoTime(); c = findClass(name);? // this is the defining class loader; record the stats sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); } } if (resolve) { resolveClass(c); } return c; }findLoadedClass :先确认类加载任务指定的类全限定名是否已经被加载,没有加载过才能委派;
findBootstrapClassOrNull :如果 parent 为空这是指定了 bootstrap 加载器。
为什么要有双亲委派模型?
一个类在同一个类加载器中具有唯一性(Uniqueness),而不同类加载器中是允许同名类存在的,这里的同名是指全限定名相同。但是在整个JVM里,纵然全限定名相同,若类加载器不同,则仍然不算作是同一个类,无法通过 instanceOf 、equals 等方式的校验。
由于唯一性的存在,Class 被替换就有可能了,而双亲委派模型定义了一套类加载的优先层级,很好的防止核心类库被恶意替换。毕竟核心类库是 bootstrap classloader 加载的,而 bootstrap 是内嵌于JVM的,在双亲委派模型基础上,任何类加载任务都会交由 bootstrap classloader 这位大佬经手过目一次,只要是核心类库中的类,都会被 bootstrap classloader 加载,间接确保核心类库不被其他类加载器加载。
换言之,在遵循了双亲委派模型的规则之下,是不允许出现核心类库被替换或取代的可能,即不能在自己的 classpath 定义 java.lang.*之类的Class去替换JRE 中的Class。
classloader 加载模型是否适用所有场景?
未必。这个模型最大的局限在于,假定 A 作为 B 的 parent,A 加载的类 对 B 是可见的; 然而 B 加载的类 对 A 却是不可见的。
这是由 classloader 加载模型中的可见性(visibility)决定的
Visibility principle allows child class loader to see all the classes loaded by parent ClassLoader, but parent class loader can not see classes loaded by child.最典型不适用的场景便是 SPI 的使用。
SPI(Service Provider Interface)
Java 在核心类库中定义了许多接口,并且还给出了针对这些接口的调用逻辑,然而并未给出实现。开发者要做的就是定制一个实现类,在 META-INF/services 中注册实现类信息,以供核心类库使用。
推荐阅读
- 为啥看到书柜上的藏书会有心旷神怡的感觉
- 为啥知乎上普便有一种【我在北上广深打工,所以拥有更好的视野】这样的错觉
- 为啥工商银行的用户体验如此之差
- 汽车|看了中消协4S店服务测评调查结果,终于知道法系车为啥卖不好了
- 你为啥从窝窝商城离职?
- 为啥5G和2.4G默认的BSSID是相同的
- 为啥电器实体店的价格比淘宝贵那么多
- 现在在线学习视频有很多了,为啥大部分人还是喜欢下载下来观看
- dart这编程语言现在发展怎么样了,语法与Java,c#很相似,甚至更简洁
- 为啥到现在你还没有女朋友 ?
