类加载流程图

1.创建引导类加载器(C语言实现)(bootstrapClassLoader)
2.创建JVM启动器
3.实例化启动器过程中,初始化extClassLoader、AppClassLoader。
一、JVM启动器结构预览

扩展与应用类加载器都是启动器内部类
package sun.misc;public class Launcher {private static URLStreamHandlerFactory factory = new Launcher.Factory();//加载是实例化private static Launcher launcher = new Launcher();private static String bootClassPath = System.getProperty("sun.boot.class.path");private ClassLoader loader;private static URLStreamHandler fileHandler;public static Launcher getLauncher() {return launcher;}public Launcher() {Launcher.ExtClassLoader var1;try {//获取扩展类加载器对象。(扩展类加载器,是Launcher的一个内部类)var1 = Launcher.ExtClassLoader.getExtClassLoader();} catch (IOException var10) {throw new InternalError("Could not create extension class loader", var10);}try {//扩展类加载器作为入参,最终为AppClassLoader中parent属性赋值,即标识父加载器//(应用类加载器,是Launcher的一个内部类)this.loader = Launcher.AppClassLoader.getAppClassLoader(var1);} catch (IOException var9) {throw new InternalError("Could not create application class loader", var9);}Thread.currentThread().setContextClassLoader(this.loader);String var2 = System.getProperty("java.security.manager");if (var2 != null) {SecurityManager var3 = null;if (!"".equals(var2) && !"default".equals(var2)) {try {var3 = (SecurityManager) this.loader.loadClass(var2).newInstance();} catch (IllegalAccessException var5) {;} catch (InstantiationException var6) {;} catch (ClassNotFoundException var7) {;} catch (ClassCastException var8) {;}} else {var3 = new SecurityManager();}if (var3 == null) {throw new InternalError("Could not create SecurityManager: " + var2);}System.setSecurityManager(var3);}}/****获取应用类加载器appClassLoader**/public ClassLoader getClassLoader() {return this.loader;}public static URLClassPath getBootstrapClassPath() {return Launcher.BootClassPathHolder.bcp;}private static File[] getClassPath(String var0) {File[] var1;if (var0 != null) {int var2 = 0;int var3 = 1;boolean var4 = false;int var5;int var7;for (var5 = 0; (var7 = var0.indexOf(File.pathSeparator, var5)) != -1; var5 = var7 + 1) {++var3;}var1 = new File[var3];var4 = false;for (var5 = 0; (var7 = var0.indexOf(File.pathSeparator, var5)) != -1; var5 = var7 + 1) {if (var7 - var5 > 0) {var1[var2++] = new File(var0.substring(var5, var7));} else {var1[var2++] = new File(".");}}if (var5 < var0.length()) {var1[var2++] = new File(var0.substring(var5));} else {var1[var2++] = new File(".");}if (var2 != var3) {File[] var6 = new File[var2];System.arraycopy(var1, 0, var6, 0, var2);var1 = var6;}} else {var1 = new File[0];}return var1;}static class AppClassLoader extends URLClassLoader {final URLClassPath ucp = SharedSecrets.getJavaNetAccess().getURLClassPath(this);public static ClassLoader getAppClassLoader(final ClassLoader var0) throws IOException {final String var1 = System.getProperty("java.class.path");final File[] var2 = var1 == null ? new File[0] : Launcher.getClassPath(var1);return (ClassLoader) AccessController.doPrivileged(new PrivilegedAction<Launcher.AppClassLoader>() {public Launcher.AppClassLoader run() {URL[] var1x = var1 == null ? new URL[0] : Launcher.pathToURLs(var2);return new Launcher.AppClassLoader(var1x, var0);}});}AppClassLoader(URL[] var1, ClassLoader var2) {super(var1, var2, Launcher.factory);this.ucp.initLookupCache(this);}public Class<?> loadClass(String var1, boolean var2) throws ClassNotFoundException {int var3 = var1.lastIndexOf(46);if (var3 != -1) {SecurityManager var4 = System.getSecurityManager();if (var4 != null) {var4.checkPackageAccess(var1.substring(0, var3));}}if (this.ucp.knownToNotExist(var1)) {Class var5 = this.findLoadedClass(var1);if (var5 != null) {if (var2) {this.resolveClass(var5);}return var5;} else {throw new ClassNotFoundException(var1);}} else {return super.loadClass(var1, var2);}}protected PermissionCollection getPermissions(CodeSource var1) {PermissionCollection var2 = super.getPermissions(var1);var2.add(new RuntimePermission("exitVM"));return var2;}private void appendToClassPathForInstrumentation(String var1) {assert Thread.holdsLock(this);super.addURL(Launcher.getFileURL(new File(var1)));}private static AccessControlContext getContext(File[] var0) throws MalformedURLException {PathPermissions var1 = new PathPermissions(var0);ProtectionDomain var2 = new ProtectionDomain(new CodeSource(var1.getCodeBase(), (Certificate[]) null), var1);AccessControlContext var3 = new AccessControlContext(new ProtectionDomain[]{var2});return var3;}static {ClassLoader.registerAsParallelCapable();}}private static class BootClassPathHolder {static final URLClassPath bcp;private BootClassPathHolder() {}static {URL[] var0;if (Launcher.bootClassPath != null) {var0 = (URL[]) AccessController.doPrivileged(new PrivilegedAction<URL[]>() {public URL[] run() {File[] var1 = Launcher.getClassPath(Launcher.bootClassPath);int var2 = var1.length;HashSet var3 = new HashSet();for (int var4 = 0; var4 < var2; ++var4) {File var5 = var1[var4];if (!var5.isDirectory()) {var5 = var5.getParentFile();}if (var5 != null && var3.add(var5)) {MetaIndex.registerDirectory(var5);}}return Launcher.pathToURLs(var1);}});} else {var0 = new URL[0];}bcp = new URLClassPath(var0, Launcher.factory, (AccessControlContext) null);bcp.initLookupCache((ClassLoader) null);}}static class ExtClassLoader extends URLClassLoader {public static Launcher.ExtClassLoader getExtClassLoader() throws IOException {final File[] var0 = getExtDirs();try {return (Launcher.ExtClassLoader) AccessController.doPrivileged(new PrivilegedExceptionAction<Launcher.ExtClassLoader>() {public Launcher.ExtClassLoader run() throws IOException {int var1 = var0.length;for (int var2 = 0; var2 < var1; ++var2) {MetaIndex.registerDirectory(var0[var2]);}return new Launcher.ExtClassLoader(var0);}});} catch (PrivilegedActionException var2) {throw (IOException) var2.getException();}}void addExtURL(URL var1) {super.addURL(var1);}//因为bootstrapClassLoader是C++实现,没有具体java对象,故ExtClassLoader对象parent属性为空。public ExtClassLoader(File[] var1) throws IOException {super(getExtURLs(var1), (ClassLoader) null, Launcher.factory);SharedSecrets.getJavaNetAccess().getURLClassPath(this).initLookupCache(this);}private static File[] getExtDirs() {String var0 = System.getProperty("java.ext.dirs");File[] var1;if (var0 != null) {StringTokenizer var2 = new StringTokenizer(var0, File.pathSeparator);int var3 = var2.countTokens();var1 = new File[var3];for (int var4 = 0; var4 < var3; ++var4) {var1[var4] = new File(var2.nextToken());}} else {var1 = new File[0];}return var1;}private static URL[] getExtURLs(File[] var0) throws IOException {Vector var1 = new Vector();for (int var2 = 0; var2 < var0.length; ++var2) {String[] var3 = var0[var2].list();if (var3 != null) {for (int var4 = 0; var4 < var3.length; ++var4) {if (!var3[var4].equals("meta-index")) {File var5 = new File(var0[var2], var3[var4]);var1.add(Launcher.getFileURL(var5));}}}}URL[] var6 = new URL[var1.size()];var1.copyInto(var6);return var6;}public String findLibrary(String var1) {var1 = System.mapLibraryName(var1);URL[] var2 = super.getURLs();File var3 = null;for (int var4 = 0; var4 < var2.length; ++var4) {URI var5;try {var5 = var2[var4].toURI();} catch (URISyntaxException var9) {continue;}File var6 = (new File(var5)).getParentFile();if (var6 != null && !var6.equals(var3)) {String var7 = VM.getSavedProperty("os.arch");File var8;if (var7 != null) {var8 = new File(new File(var6, var7), var1);if (var8.exists()) {return var8.getAbsolutePath();}}var8 = new File(var6, var1);if (var8.exists()) {return var8.getAbsolutePath();}}var3 = var6;}return null;}private static AccessControlContext getContext(File[] var0) throws IOException {PathPermissions var1 = new PathPermissions(var0);ProtectionDomain var2 = new ProtectionDomain(new CodeSource(var1.getCodeBase(), (Certificate[]) null), var1);AccessControlContext var3 = new AccessControlContext(new ProtectionDomain[]{var2});return var3;}static {ClassLoader.registerAsParallelCapable();}}private static class Factory implements URLStreamHandlerFactory {private static String PREFIX = "sun.net.www.protocol";private Factory() {}public URLStreamHandler createURLStreamHandler(String var1) {String var2 = PREFIX + "." + var1 + ".Handler";try {Class var3 = Class.forName(var2);return (URLStreamHandler) var3.newInstance();} catch (ReflectiveOperationException var4) {throw new InternalError("could not load " + var1 + "system protocol handler", var4);}}}}
二、自定义类加载器
打破双亲委派,改写ClassLoader中查找父类加载器的逻辑即可,避免加载自定义类时,被委派给应用类加载器。(注意jdk核心代码需要,仍然使用双亲委派,不能使用自定义类加载器加载jdk核心包)
