中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么破壞Java雙親委派模型

發布時間:2021-11-16 13:48:13 來源:億速云 閱讀:242 作者:iii 欄目:大數據

本篇內容主要講解“怎么破壞Java雙親委派模型”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么破壞Java雙親委派模型”吧!

自定義示例一

重寫findClass不會破壞雙親委派模型,同時也驗證了雙親委派模型的正確性。

package com.example.classloader;

import org.junit.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class TestClassLoader {

	@Test
	public void test() {
		Class<?> class0 = TestClassLoader.class;
		try {
			// false
			System.out.println(class0.getClassLoader() instanceof MyClassLoader);
			Class<?> class1 = class0.getClassLoader().loadClass("com.example.classloader.TestClassLoader");
			ClassLoader classLoader = new MyClassLoader();
			Class<?> class2 = classLoader.loadClass("com.example.classloader.TestClassLoader");
			// true
			System.out.println(class0.equals(class1));
			// true
			System.out.println(class1.equals(class2));
			// sun.misc.Launcher$AppClassLoader@18b4aac2
			System.out.println(class0.getClassLoader());
			// sun.misc.Launcher$AppClassLoader@18b4aac2
			System.out.println(class1.getClassLoader());
			// sun.misc.Launcher$AppClassLoader@18b4aac2
			System.out.println(class2.getClassLoader());
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	/**
	 *  自定義一個類加載器從指定磁盤目錄加載類
	 *  重寫findClass不破壞雙親委派模型
	 */
	public class MyClassLoader extends ClassLoader {
		@Override
		protected Class<?> findClass(String name) {
			String myPath = "/Users/lsx/code/demo/target/classes/" + name.replace(".", "/") + ".class";
			byte[] classBytes = null;
			FileInputStream in = null;

			try {
				File file = new File(myPath);
				in = new FileInputStream(file);
				classBytes = new byte[(int) file.length()];
				in.read(classBytes);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			Class<?> clazz = defineClass(name, classBytes, 0, classBytes.length);
			return clazz;
		}
	}
}

自定義示例二

重寫loadClass破壞雙親委派模型,父類的加載(Object)也會交由我們自自定義的類加載器加載。而很明顯在我們自定義的加載目錄下是不會有Object.class這個文件的,所以會拋出異常。

/**
	 *  重寫loadClass破壞雙親委派模型
	 * java.io.FileNotFoundException: /Users/lsx/code/demo/target/classes/java/lang/Object.class (No such file or directory)
	 */
	public class MyClassLoader extends ClassLoader {
		@Override
		public Class<?> loadClass(String name) {
			String myPath = "/Users/lsx/code/demo/target/classes/" + name.replace(".", "/") + ".class";
			System.out.println(myPath);
			byte[] classBytes = null;
			FileInputStream in = null;

			try {
				File file = new File(myPath);
				in = new FileInputStream(file);
				classBytes = new byte[(int) file.length()];
				in.read(classBytes);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			System.out.println();
			Class<?> clazz = defineClass(name, classBytes, 0, classBytes.length);
			return clazz;
		}
	}

總結:如果不想打破雙親委派模型就重寫ClassLoader類中的findClass()方法即可,無法被父類加載器加載的類最終會通過這個方法被加載。而如果想打破雙親委派模型則需要重寫loadClass()方法。

JDBC對雙親委派模型的破壞(加載SPI接口實現類)

原生的JDBC中Driver驅動本身只是一個接口,并沒有具體的實現,具體的實現是由不同數據庫類型去實現的。例如,MySQL的mysql-connector-.jar中的Driver類具體實現的。 原生的JDBC中的類是放在rt.jar包的,是由啟動類加載器進行類加載的,在JDBC中的Driver類中需要動態去加載不同數據庫類型的Driver類,而mysql-connector-.jar中的Driver類是用戶自己寫的代碼,那啟動類加載器肯定是不能進行加載的,既然是自己編寫的代碼,那就需要由應用程序啟動類去進行類加載。于是乎,這個時候就引入線程上下文件類加載器(Thread Context ClassLoader)。有了這個東西之后,程序就可以把原本需要由啟動類加載器進行加載的類,由應用程序類加載器去進行加載了。通過線程上下文加載器去加載所需要的SPI代碼,也就是父類加載器請求子類加載器去完成類加載的動作,實際是通過打破了雙親委派模型的層次結構來逆向使用類加載器,違背了雙親委派模型的一般性原則。具體參考以JDBC為例談雙親委派模型的破壞

OSGI對雙親委派模型的破壞

雙親委派模型的第三次“被破壞”是由于用戶對程序的動態性的追求導致的。為了實現熱插拔、熱部署、模塊化,意思是添加一個功能或減去一個功能不用重啟,只需要把這模塊連同類加載器一起換掉就實現了代碼的熱替換。例如OSGi的出現,在OSGi環境下類加載器不再是雙親委派模型中的樹狀結構,而是進一步發展為網狀結構

到此,相信大家對“怎么破壞Java雙親委派模型”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

塔河县| 新郑市| 新安县| 赞皇县| 永昌县| 平泉县| 唐海县| 阿瓦提县| 若尔盖县| 临猗县| 库车县| 新津县| 宁波市| 延长县| 保靖县| 安西县| 威海市| 陇川县| 和硕县| 梅州市| 叶城县| 吴桥县| 漠河县| 寿光市| 南陵县| 深圳市| 莱阳市| 利津县| 当涂县| 临猗县| 邯郸县| 桐梓县| 淮阳县| 平遥县| 奎屯市| 监利县| 康保县| 海南省| 建宁县| 南江县| 宿松县|