jvm双亲委派机制详解( 三 )


?那意味着我们需要去打破双亲委派机制 。看AppClassLoader的类加载逻辑,主要逻辑在父类ClassLoader.loadClass()方法中 , 我们只需要在自定义的类加载器中重写该方法即可 。主要修改逻辑:如果类型是com.hyz.jvm开头的类,则从自定义类加载器中去读?。?否则委托给上层类加载器加载 。
/** * 32 * 重写类加载方法,实现自己的加载逻辑 , 不委派给双亲加载 * 33 * @param name * 34 * @param resolve * 35 * @return * 36 * @throws ClassNotFoundException * 37 */protected Class<?> loadClass(String name, boolean resolve)throws ClassNotFoundException {synchronized (getClassLoadingLock(name)) {// First, check if the class has already been loadedClass<?> c = findLoadedClass(name);if (c == null) {// If still not found, then invoke findClass in order// to find the class.long t1 = System.nanoTime();if (!name.startsWith("com.hyz.jvm")) {c = this.getParent().loadClass(name);} else {c = findClass(name);}// this is the defining class loader; record the statssun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);sun.misc.PerfCounter.getFindClasses().increment();}if (resolve) {resolveClass(c);}return c;}}?应用到打破双亲委派机制的实际应用场景是在Tomcat加载war包 。比如war1用的是spring4版本,war2用的是spring5版本,那就意味着加载着2个war包不能用同一个类加载器实例,需要各自指定一个自定义的类加载器实例,各自去加载所需的spring版本库文件 。
总结:双亲委派机制保证了核心类的安全,确保不会被修改,也保证了不会加载到重复的字节码文件 。

推荐阅读