Java Launcher代码分析(JDK src 下Launcher包)

Launcher是JRE中用于启动程序入口main()的类。分析这个类有助于理解JRE系统类的加载机制。

该类主要功能是:创建ExtClassLoader和AppClassLoader,还根据配置创建SercurityManager,设置进程上下文类加载器。

(一)Launcher初始化代码

private static Launcher launcher = new Launcher();
public static Launcher getLauncher() {
return launcher;
}

public Launcher() {
// 1. 创建扩展类加载器:ExtClassLoader
ClassLoader extcl;
try {
extcl = ExtClassLoader.getExtClassLoader();
} catch (IOException e) {
throw new InternalError(
“Could not create extension class loader”);
}

// 2. 创建用于启动应用程序的类加载器:AppClassLoader
try {
loader = AppClassLoader.getAppClassLoader(extcl);
} catch (IOException e) {
throw new InternalError(
“Could not create application class loader”);
}

// 3. 设置当前线程的上下文类加载器为前一步创建的AppClassLoader实例
Thread.currentThread().setContextClassLoader(loader);

//4. 根据需求创建安全管理器:SecurityManager实例
String s = System.getProperty(“java.security.manager”);
if (s != null) {
SecurityManager sm = null;
if (“”.equals(s) || “default”.equals(s)) {
sm = new java.lang.SecurityManager();
} else {
try {
sm = (SecurityManager)loader.loadClass(s).newInstance();
} catch (IllegalAccessException e) {
} catch (InstantiationException e) {
} catch (ClassNotFoundException e) {
} catch (ClassCastException e) {
}
}
if (sm != null) {
System.setSecurityManager(sm);
} else {
throw new InternalError(
“Could not create SecurityManager: ” + s);
}
}
}

创建Launcher几乎是用了一个Singleton模式,但令人疑惑的是其构造方法访问修饰符为public,这样就破坏了Singleton模式,可能是需要在必要的时候创建另一个Launcher实例。

(二)ExtClassLoader

关键代码如下:
String s = System.getProperty(“java.ext.dirs”);
File[] dirs = analyze(s);
URLClassLoader(dirs, null, factory);

因此,ExtClassLoader将加载变量“java.ext.dirs”的值指示的路径下的类,默认是jre安装目录/lib/ext,可以通过Djava.ext.dirs=…,来修改,这个指定目录是一些JDK或JRE的可选择功能扩展包。

(三)AppClassLoader

关键代码是:
final String s = System.getProperty(“java.class.path”);
final File[] path = (s == null) ? new File[0] : getClassPath(s);
return (AppClassLoader)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
URL[] urls =
(s == null) ? new URL[0] : pathToURLs(path);
return new AppClassLoader(urls, extcl);
}
});

可见,AppClassLoader取的是环境变量java.class.path中设定的路径作为类加载的搜索路径。
可以通过对该变量的设定来修改默认配置,实际上我们也常常这样做——虽然我们很少修改java.ext.dirs的值。

你可能感兴趣的:(java,jdk,String,null,extension,代码分析)