java类加载器

    最近做一个Java Windows NT服务,为了方便管理和加载第三方类库,需要加载指定目录下的jar,故需要编写一个自己的类加载器。顺便梳理下相关知识。

类加载器双亲委派机制

    JVM在加载类时默认采用的是双亲委派机制。通俗的讲,就是某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给该类加载器的父类加载器,依次递归,如果父类加载器成功加载,就返回;如果父类加载器无法完成此加载任务时,就委派给他孩子加载,不成功依次递归


JVM预定义类加载器

java类加载器

    启动类加载器:本地代码实现,class = null.它负责将 $(JAVA_HOME)/lib 下面的类库加载到内存中.

    标准扩展类加载器:sun实现。class = sun.misc.Launcher$ExtClassLoader。负责将 $(JAVA_HOME)/lib/ext 或者由系统变量 java.ext.dir 指定位置中的类库加载到内存中.

    系统类加载器:sun实现。class = sun.misc.Launcher$AppClassLoader.负责加载classpath配置的类库.

自定义类加载器

    继承URLClassLoader。  一个简单实现的例子:

import java.io.File;
import java.io.FileFilter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;

public class NetClassLoader extends URLClassLoader{
	private static List<URL> EMPTY_URL_LIST = new ArrayList<URL>(0);

	public NetClassLoader(URL[] urls) {
		super(urls);
	}
	
	public NetClassLoader(String dir) {
		super(getJarURL(dir).toArray(new URL[]{}));
	}
	
	private static List<URL> getJarURL(String dir){
		
		if(dir == null ||  "".equals(dir.trim())){
			return EMPTY_URL_LIST;
		}
		
		File file = new File(dir);
		List<URL> jarsList = new ArrayList<URL>();
		if(file.isDirectory()){
			File[] files = file.listFiles(new FileFilter() {
				public boolean accept(File pathname) {
					return pathname.getName().endsWith(".jar") 
					                        || pathname.isDirectory();
				}
			});
			
			if(files.length > 0 ){
				for(File f : files){
					if(f.isFile()){
						addURL(jarsList,f);
					}else{//处理目录文件
						jarsList.addAll(getJarURL(f.getAbsolutePath()));
					}
				}
			}
			
		}else if(file.isFile() && dir.endsWith(".jar")){
			addURL(jarsList,file);
		} 
			
		return EMPTY_URL_LIST;
	}
	
	private static void addURL(List<URL> list,File file){
		
		try {
			URL url = file.toURI().toURL();
			list.add(url);
		} catch (MalformedURLException e) { 
			
		}

	}

}

    






你可能感兴趣的:(java类加载器)