日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

自定义ClassLoader

發(fā)布時(shí)間:2024/7/23 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 自定义ClassLoader 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

來源:http://a123159521.iteye.com/blog/1095264


package com.classloader.util;import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.net.URLStreamHandlerFactory; import java.security.CodeSource; import java.security.PermissionCollection; import java.util.Enumeration; import java.util.jar.Manifest;public class NetworkClassLoader extends URLClassLoader {String baseUrl;public String getBaseUrl() {return baseUrl;}public void setBaseUrl(String baseUrl) {this.baseUrl = baseUrl;}public NetworkClassLoader(){this(new URL[]{});}/*** URL 以'/'結(jié)尾的為目錄* 否則為jar包* 未指定其父類加載器為系統(tǒng)類加載器* @param urls*/public NetworkClassLoader(URL[] urls) {super(urls);}/*** 同上,指定classLoader* @param urls* @param parent*/public NetworkClassLoader(URL[] urls, ClassLoader parent) {super(urls,parent);}/*** 同上,URL工廠處理器* @param urls* @param parent* @param factory*/public NetworkClassLoader(URL[] urls, ClassLoader parent,URLStreamHandlerFactory factory) {super(urls,parent,factory);}/*** [添加baseUrl]* @param url*/public void addURL(String url){URL uurl=null;try {uurl = new URL(baseUrl+url);} catch (MalformedURLException e) {// TODO Auto-generated catch blocke.printStackTrace();}addURL(uurl);}/*** 添加url[添加baseUrl]*/protected void addURL(URL url) {super.addURL(url);}/*** 返回urls*/public URL[] getURLs() {return super.getURLs();}/*** 查找類對象* 從以上的URLS中查找加載當(dāng)前類對象[會(huì)打開所有的jars去查找指定的類]* (可以通過調(diào)用findClass來得到以上URL加載包中的類)*/protected Class<?> findClass(String name) throws ClassNotFoundException {return super.findClass(name);}/*** defineClass SecureClassLoader定義為最終方法,不允許更改.* 在使用這個(gè)類對象前,必須先resolved(解析)*//*** 查找資源[自定義相對URL查找路徑]* 從以上的URLS中查找當(dāng)前名稱的資源* 這個(gè)必須重寫,因?yàn)槭莗ublic 哈哈*/public URL findResource(String name) {URL url = null;try {url = new URL(baseUrl+name);} catch (MalformedURLException e) {// TODO Auto-generated catch blocke.printStackTrace();}return url;}/*** 查找資源列表[URL查找路徑]*/public Enumeration<URL> findResources(String name) throws IOException {return super.findResources(name);}/*** 在當(dāng)前的ClassLoader中,定義一個(gè)新的Package,Package的屬性由Manifest指定.這個(gè)包的源文件*/protected Package definePackage(String name, Manifest man, URL url)throws IllegalArgumentException {return super.definePackage(name, man, url);}/*** 加載路徑權(quán)限*/protected PermissionCollection getPermissions(CodeSource codesource) {return super.getPermissions(codesource);} }
以下是用法:?

NetworkClassLoader loader = new NetworkClassLoader();loader.setBaseUrl("file:///F:\\框架\\maven\\app\\jms\\src\\main\\webapp\\modules\\");loader.addURL("App/lib/test.jar");loader.addURL("App/lib/test1.jar");loader.addURL("App/template/view.vm");loader.addURL("App/config.xml");
這里初始化了此類加載器所使用的類資源,配置文件等。?
以下是如何加載類資源:?

Class clazz= loader.findClass("com.jvm.look.A");//加載類 以下是加載配置文件資源?
URL uuu = loader.findResource("App/config.xml"); 有一點(diǎn)需要注意的,這個(gè)類加載器還是雙親委托機(jī)制,比如有一個(gè)類"com.annotation.table.Test"在父類加載器中如果已經(jīng)加載過了,那么如果這個(gè)類在test.jar中存在,那么不會(huì)重新定義加載,而使用父類加載器加載的類,有人問了,那我如何覆蓋父類加載器中定義的類。?
可以進(jìn)行如下操作:?
Class clazz2= loader.findClass("com.annotation.table.Test"); 重新加載類,類的加載序列我在上一篇已經(jīng)講過了,不熟悉的可以看以上文章.?
可能有人會(huì)問了,如果每一個(gè)類都這樣,那我不崩潰了,我需要把我加載的jar覆蓋父類加載器中定義的所有類.?
/*** 覆蓋父加載器中定義的類,使用當(dāng)前類加載器加載資源,那么所有的類都在此加載器中執(zhí)行.* 這樣,所有URL中的類都通過此類加載器加載,也就是說URL中的類的定義類加載器就是當(dāng)前類加載器.* 建議:盡量不要使用這種方式覆蓋父加載器定義的類.[按一種約定雙親委托機(jī)制加載]* (如果重載了,那么盡量使用此loader加載類,這樣所有邏輯都在此ClassLoader中運(yùn)行,當(dāng)然還有SDK還是從雙親加載)* 可以在SDK中定義接口,在此JAR里面提供實(shí)現(xiàn).*/public void initAllJar(){URL[] urls = this.getURLs();for(URL urll:urls){String url = urll.getFile();//重新定義這個(gè)架包中的所有類.if(url.endsWith("jar")){File jarFile = getJarFile(url);JarFile jarFileTemp = null;try {jarFileTemp = new JarFile(jarFile);Enumeration<JarEntry> en = jarFileTemp.entries();while (en.hasMoreElements()) {JarEntry je = en.nextElement();String name = je.getName();if (name.endsWith(CLASS_FILE)) {String className = name.substring(0, name.length()- CLASS_FILE.length());findClass(pathToDot(className));}}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}/*** 轉(zhuǎn)jar包路徑和jar文件名為具體文件.** @param root* @param jar* @return*/private File getJarFile(String file) {if (file.startsWith(PREFIX_FILE))file = file.substring(PREFIX_FILE.length());int end = file.indexOf(JAR_URL_SEPERATOR);if (end != (-1))file = file.substring(0, end);return new File(file);}/*** 轉(zhuǎn)路徑為包名[/ ==> .]/[\\ ==> .]* @param s* @return*/private String pathToDot(String s) {return s.replace('/', '.').replace('\\', '.');}
其實(shí)JDK中已經(jīng)提供了好幾個(gè)ClassLoader,大家可以擴(kuò)展,比如項(xiàng)目中有兩個(gè)架包版本,結(jié)構(gòu)全部都一樣,但是兩個(gè)架包都必須運(yùn)行。這時(shí)自定義類加載器就有用了。


創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的自定义ClassLoader的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。