最简单的制作网站,江门网红桥,湛江网红打卡餐厅,wordpress主题域名授权转载自 破坏双亲委派模型 1.第一次破坏
由于双亲委派模型是在JDK1.2之后才被引入的#xff0c;而类加载器和抽象类java.lang.ClassLoader则在JDK1.0时代就已经存在#xff0c;面对已经存在的用户自定义类加载器的实现代码#xff0c;Java设计者引入双亲委派模型时不得不做出…转载自 破坏双亲委派模型 1.第一次破坏
由于双亲委派模型是在JDK1.2之后才被引入的而类加载器和抽象类java.lang.ClassLoader则在JDK1.0时代就已经存在面对已经存在的用户自定义类加载器的实现代码Java设计者引入双亲委派模型时不得不做出一些妥协。在此之前用户去继承java.lang.ClassLoader的唯一目的就是为了重写loadClass()方法因为虚拟机在进行类加载的时候会调用加载器的私有方法loadClassInternal()而这个方法唯一逻辑就是去调用自己的loadClass()。
2.第二次破坏
双亲委派模型的第二次“被破坏”是由这个模型自身的缺陷所导致的双亲委派很好地解决了各个类加载器的基础类的同一问题越基础的类由越上层的加载器进行加载基础类之所以称为“基础”是因为它们总是作为被用户代码调用的API但世事往往没有绝对的完美。
如果基础类又要调用回用户的代码那该么办
一个典型的例子就是JNDI服务JNDI现在已经是Java的标准服务 它的代码由启动类加载器去加载在JDK1.3时放进去的rt.jar但JNDI的目的就是对资源进行集中管理和查找它需要调用由独立厂商实现并部署在应用程序的ClassPath下的JNDI接口提供者的代码但启动类加载器不可能“认识”这些代码。
为了解决这个问题Java设计团队只好引入了一个不太优雅的设计线程上下文类加载器(Thread Context ClassLoader)。这个类加载器可以通过java.lang.Thread类的setContextClassLoader()方法进行设置如果创建线程时还未设置他将会从父线程中继承一个如果在应用程序的全局范围内都没有设置过的话那这个类加载器默认就是应用程序类加载器。
有了线程上下文加载器JNDI服务就可以使用它去加载所需要的SPI代码也就是父类加载器请求子类加载器去完成类加载的动作这种行为实际上就是打通了双亲委派模型层次结构来逆向使用类加载器实际上已经违背了双亲委派模型的一般性原则但这也是无可奈何的事情。Java中所有涉及SPI的加载动作基本上都采用这种方式例如JNDI、JDBC、JCE、JAXB和JBI等。
3.第三次破坏
双亲委派模型的第三次“被破坏”是由于用户对程序动态性的追求导致的这里所说的“动态性”指的是当前一些非常“热门”的名词代码热替换、模块热部署等简答的说就是机器不用重启只要部署上就能用。 OSGi实现模块化热部署的关键则是它自定义的类加载器机制的实现。每一个程序模块(Bundle)都有一个自己的类加载器当需要更换一个Bundle时就把Bundle连同类加载器一起换掉以实现代码的热替换。在OSGi幻境下类加载器不再是双亲委派模型中的树状结构而是进一步发展为更加复杂的网状结构当受到类加载请求时OSGi将按照下面的顺序进行类搜索 1将java.开头的类委派给父类加载器加载。 2否则将委派列表名单内的类委派给父类加载器加载。 3否则将Import列表中的类委派给Export这个类的Bundle的类加载器加载。 4否则查找当前Bundle的ClassPath使用自己的类加载器加载。 5否则查找类是否在自己的Fragment Bundle中如果在则委派给Fragment Bundle的类加载器加载。 6否则查找Dynamic Import列表的Bundle委派给对应Bundle的类加载器加载。 7否则类加载器失败。