类加载器 - 自定义系统类加载器及线程上下文类加载器
如果系统属性java.system.class.loader被定义了,这个属性的值就将做为返回的类加载器的名字。这个类是使用默认的系统类加载器所加载的,且必须要定义一个默认的参数为ClassLoader的构造方法,所生成的类加载器就被定义为新的系统类加载器。
如果安全管理器存在,并且调用者的类加载器是不是
null
和调用者的类加载器是不一样的,或者系统类加载器的祖先,则此方法调用安全管理器的checkPermission方法与RuntimePermission("getClassLoader")权限验证访问到系统类加载器。 如果没有,SecurityException
将被抛出。
源码解析
// 系统类加载器 // @GuardedBy("ClassLoader.class") private static ClassLoader scl; // 设置系统类加载器后,将其设置为true // @GuardedBy("ClassLoader.class") private static boolean sclSet; /** * getSystemClassLoader方法源码 */ @CallerSensitive public static ClassLoader getSystemClassLoader() { initSystemClassLoader(); if (scl == null) { return null; } SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkClassLoaderPermission(scl, Reflection.getCallerClass()); } return scl; } // 初始化系统类加载器 private static synchronized void initSystemClassLoader() { // 如果系统类加载器没有被设置 if (!sclSet) { // 如果系统类加载器已经被设置,不合理,抛出异常 if (scl != null) throw new IllegalStateException("recursive invocation"); // Launcher为系统类加载器和拓展类加载器的一个包装,代码并不开源 sun.misc.Launcher l = sun.misc.Launcher.getLauncher(); if (l != null) { Throwable oops = null; // 将Launcher默认的系统类加载器赋给了scl scl = l.getClassLoader(); try { // 获取到系统类加载器,可能是系统默认的AppClassLOader,有可能是用户自定义的系统类加载器 scl = AccessController.doPrivileged( new SystemClassLoaderAction(scl)); } catch (PrivilegedActionException pae) { // 异常处理 oops = pae.getCause(); if (oops instanceof InvocationTargetException) { oops = oops.getCause(); } } if (oops != null) { if (oops instanceof Error) { throw (Error) oops; } else { // wrap the exception throw new Error(oops); } } } // 系统类加载器已经被设置 sclSet = true; } } class SystemClassLoaderAction implements PrivilegedExceptionAction<ClassLoader> { private ClassLoader parent; SystemClassLoaderAction(ClassLoader parent) { this.parent = parent; } public ClassLoader run() throws Exception { // 获取系统属性 String cls = System.getProperty("java.system.class.loader"); // 如果系统属性为空,系统类加载器就是默认的AppClassLoader if (cls == null) { return parent; } //如果系统属性不为空,获取cls所对应的class的构造方法对象 Constructor<?> ctor = Class.forName(cls,