sun.misc.Launcher

针对 jdk1.8,jdk9 以后就没有该文件了。
http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/raw-file/8477fd88653c/src/share/classes/sun/misc/Launcher.java

public class Launcher {
  	// 自定义通讯协议设计
    private static URLStreamHandlerFactory factory = new Launcher.Factory();
  	// 不伦不类,说你是单例你却有个公有的构造方法
    private static Launcher launcher = new Launcher();
    // Bootstrap classloader 加载的路径
    private static String bootClassPath = System.getProperty("sun.boot.class.path");
    // Application classloader
    private ClassLoader loader;
    // 没有用到
    private static URLStreamHandler fileHandler;
  	// ...
}

Launcher 构造方法

public Launcher() {                                                                                                     
    // 创建 ExtClassLoader                                                                                                
    ClassLoader extcl;                                                                                                  
    try {                                                                                                               
        extcl = ExtClassLoader.getExtClassLoader();                                                                     
    } catch (IOException e) {                                                                                           
        throw new InternalError("Could not create extension class loader", e);                                          
    }                                                                                                                   
                                                                                                                        
    try {                                                                                                               
        // 创建 AppClassLoader                                                                                            
        // AppClassLoader 的爹设置为 ExtClassLoader                                                                          
        loader = AppClassLoader.getAppClassLoader(extcl);                                                               
    } catch (IOException e) {                                                                                           
        throw new InternalError("Could not create application class loader", e);                                        
    }                                                                                                                   
                                                                                                                        
    // 将线程上下文加载器设置为 AppClassLoader                                                                                      
    Thread.currentThread().setContextClassLoader(loader);                                                               
                                                                                                                        
    // Finally, install a security manager if requested                                                                 
    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 | InstantiationException | ClassNotFoundException | ClassCastException e) { 
            }                                                                                                           
        }                                                                                                               
        if (sm != null) {                                                                                               
            System.setSecurityManager(sm);                                                                              
        } else {                                                                                                        
            throw new InternalError("Could not create SecurityManager: " + s);                                          
        }                                                                                                               
    }                                                                                                                   
}                                                                                                                       

BootClassPathHolder 私有内部类,也是一种线程安全的单例实现模式。

private static class BootClassPathHolder {                                                                  
    static final URLClassPath bcp;                                                                          
                                                                                                            
    static {                                                                                                
        URL[] urls;                                                                                         
        if (bootClassPath != null) {                                                                        
            urls = AccessController.doPrivileged(                                                           
                    new PrivilegedAction<URL[]>() {                                                         
                        @Override                                                                           
                        public URL[] run() {                                                                
                            File[] classPath = getClassPath(bootClassPath);
                          	// 加快索引速度,JDK9 以后移除了。
                            int len = classPath.length;                                                     
                            Set<File> seenDirs = new HashSet<File>();                                       
                            for (int i = 0; i < len; i++) {                                                 
                                File curEntry = classPath[i];                                               
                                // Negative test used to properly handle nonexistent jars on boot class path
                                if (!curEntry.isDirectory()) {                                              
                                    curEntry = curEntry.getParentFile();                                    
                                }                                                                           
                                if (curEntry != null && seenDirs.add(curEntry)) {                           
                                    MetaIndex.registerDirectory(curEntry);                                  
                                }                                                                           
                            }                                                                               
                            return pathToURLs(classPath);                                                   
                        }                                                                                   
                    }                                                                                       
            );                                                                                              
        } else {                                                                                            
            urls = new URL[0];                                                                              
        }                                                                                                   
        bcp = new URLClassPath(urls, factory, null);                                                        
        bcp.initLookupCache(null);                                                                          
    }                                                                                                       
}                                                                                                                                                                                                                                                                                                                

可以看到 getAppClassLoader 每次都是重新 new 一个 AppClassLoader。

static class AppClassLoader extends URLClassLoader {
  	// 并行加载
    static {                                                                                        
        ClassLoader.registerAsParallelCapable();                                                    
    }                                                                                               
                                                                                                    
    public static ClassLoader getAppClassLoader(final ClassLoader extcl) throws IOException {       
        final String s = System.getProperty("java.class.path");                                     
        final File[] path = (s == null) ? new File[0] : getClassPath(s);                            
                                                                                                    
        return AccessController.doPrivileged(                                                       
                new PrivilegedAction<AppClassLoader>() {                                            
                    @Override                                                                       
                    public AppClassLoader run() {                                                   
                        URL[] urls = (s == null) ? new URL[0] : pathToURLs(path);                   
                        return new AppClassLoader(urls, extcl);                                     
                    }                                                                               
                });                                                                                 
    }                                                                                               
                                                                                                    
    final URLClassPath ucp;                                                                         
                                                                                                    
    AppClassLoader(URL[] urls, ClassLoader parent) {                                                
        super(urls, parent, factory);                                                               
        ucp = SharedSecrets.getJavaNetAccess().getURLClassPath(this);                               
        ucp.initLookupCache(this);                                                                  
    }                                                                                               
                                                                                                    
    @Override                                                                                       
    public Class<?> loadClass(String name, boolean resolve)                                         
            throws ClassNotFoundException {                                                         
        int i = name.lastIndexOf('.');                                                              
        if (i != -1) {                                                                              
            SecurityManager sm = System.getSecurityManager();                                       
            if (sm != null) {                                                                       
                sm.checkPackageAccess(name.substring(0, i));                                        
            }                                                                                       
        }                                                                                           
        // 在缓存中查找                                                                                           
        if (ucp.knownToNotExist(name)) {                                                            
            Class<?> c = findLoadedClass(name);                                                     
            if (c != null) {                                                                        
                if (resolve) {                                                                      
                    resolveClass(c);                                                                
                }                                                                                   
                return c;                                                                           
            }                                                                                       
            throw new ClassNotFoundException(name);                                                 
        }                                                                                           
        return (super.loadClass(name, resolve));                                                    
    }
  	// ...
}    

整个 JVM 内只有一个 ExtClassLoader

static class ExtClassLoader extends URLClassLoader {                                     
    static {                                                                             
        ClassLoader.registerAsParallelCapable();                                         
    }                                                                                    
    // 单例                                                                                     
    private static volatile ExtClassLoader instance = null;                              
                                                                                         
    public static ExtClassLoader getExtClassLoader() throws IOException {                
        if (instance == null) {                                                          
            synchronized (ExtClassLoader.class) {                                        
                if (instance == null) {                                                  
                    instance = createExtClassLoader();                                   
                }                                                                        
            }                                                                            
        }                                                                                
        return instance;                                                                 
    }                                                                                    
                                                                                         
    private static ExtClassLoader createExtClassLoader() throws IOException {            
        try {                                                                            
            return AccessController.doPrivileged(                                        
                    new PrivilegedExceptionAction<ExtClassLoader>() {                    
                        @Override                                                        
                        public ExtClassLoader run() throws IOException {                 
                            final File[] dirs = getExtDirs();                            
                            int len = dirs.length;                                       
                            for (int i = 0; i < len; i++) {                              
                                MetaIndex.registerDirectory(dirs[i]);                    
                            }                                                            
                            return new ExtClassLoader(dirs);                             
                        }                                                                
                    });                                                                  
        } catch (java.security.PrivilegedActionException e) {                            
            throw (IOException) e.getException();                                        
        }                                                                                
    }                                                                                    
                                                                                                                                                                                                                                                                                                                                                  
    public ExtClassLoader(File[] dirs) throws IOException {                              
        super(getExtURLs(dirs), null, factory);                                          
        SharedSecrets.getJavaNetAccess().                                                
                getURLClassPath(this).initLookupCache(this);                             
    }                                                                                                                                                                            
		// ...                                                                                                                                                                                                                                                       
}                                                                                                                                                                                                                  

测试

@Test                                                               
public void test3() {                                               
    System.out.println(new Launcher());                             
    System.out.println(new Launcher());                             
    System.out.println(new Launcher().getClassLoader());            
    System.out.println(new Launcher().getClassLoader());            
    System.out.println(new Launcher().getClassLoader().getParent());
    System.out.println(new Launcher().getClassLoader().getParent());
}                                                                                                                                       
/* 输出
sun.misc.Launcher@18ef96
sun.misc.Launcher@6956de9
sun.misc.Launcher$AppClassLoader@769c9116
sun.misc.Launcher$AppClassLoader@6aceb1a5
sun.misc.Launcher$ExtClassLoader@61e4705b
sun.misc.Launcher$ExtClassLoader@61e4705b
*/
System.getProperty("sun.boot.class.path")
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/resources.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/rt.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/sunrsasign.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/jsse.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/jce.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/charsets.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/jfr.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/classes
System.getProperty("java.ext.dirs")
/Users/N3verL4nd/Library/Java/Extensions
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/ext
/Library/Java/Extensions
/Network/Library/Java/Extensions
/System/Library/Java/Extensions
/usr/lib/java
System.getProperty("java.class.path")
idea 相关
/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar
/Applications/IntelliJ IDEA.app/Contents/plugins/junit/lib/junit-rt.jar
/Applications/IntelliJ IDEA.app/Contents/plugins/junit/lib/junit5-rt.jar
/Users/N3verL4nd/Library/Caches/IntelliJIdea2019.2/captureAgent/debugger-agent.jar

jre 相关
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/charsets.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/deploy.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/javaws.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/jce.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/jfr.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/jfxswt.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/jsse.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/management-agent.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/plugin.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/resources.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/rt.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/lib/ant-javafx.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/lib/dt.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/lib/javafx-mx.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/lib/jconsole.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/lib/packager.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/lib/sa-jdi.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/lib/tools.jar

jre ext
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/ext/cldrdata.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/ext/dnsns.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/ext/jaccess.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/ext/jfxrt.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/ext/localedata.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/ext/nashorn.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/ext/sunec.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/ext/zipfs.jar

项目相关
/Users/N3verL4nd/Desktop/MTThriftStudy/target/test-classes
/Users/N3verL4nd/Desktop/MTThriftStudy/target/classes

pom 配置的包
/Users/N3verL4nd/.m2/repository/org/springframework/spring-webmvc/5.0.8.RELEASE/spring-webmvc-5.0.8.RELEASE.jar
/Users/N3verL4nd/.m2/repository/org/springframework/spring-aop/5.0.8.RELEASE/spring-aop-5.0.8.RELEASE.jar
...
发布了778 篇原创文章 · 获赞 323 · 访问量 209万+

猜你喜欢

转载自blog.csdn.net/lgh1992314/article/details/104459985