Java Launcher代码分析(JDK src 下Launcher包)
源:http://blog.csdn.net/a379039233/article/details/6160800
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的值。

浙公网安备 33010602011771号