Skip to content

Latest commit

 

History

History
128 lines (111 loc) · 4.33 KB

线程上下文类加载器.md

File metadata and controls

128 lines (111 loc) · 4.33 KB

线程上下文类加载器

背景

Java提供了规范,各个厂商去实现这些规范,比如JDBC/JNDI,这写都是SPI(service provider interface),与api的区别是是否提供实现

这就出现一个问题,SPI的代码被定义在java基础库中,厂商提供的实现第三方jar,SPI会加载实例化第三方jar

java默认的类加载机制是双亲委派模型,即先通过父加载器加载,如果父加载器找不到,再通过子加载器加载

加载器之间的关系:BootstrapClassLoader > ExtensionClassLoader > AppClassLoader > CustomerClassLoader

  • BootstrapClassLoader: rt.jar
  • ExtensionClassLoader: JAVA_HOME/lib/ext/
  • AppClassLoader: ClassPath
  • CustomerClassLoader: 自定义加载器

接着讨论刚才的问题,BootstrapClassLoader中的SPI找不到了AppClassLoader中的mysql.jar的实现类 为了解决这种问题引入了ThreadContextClassLoader

当前线程ThreadContextClassLoader默认存放了AppClassLoader,这种做法破坏了双亲委派模型

通过DriverManager我们可以看到ClassLoader在JDBC中的使用逻辑

	// DriverManager
	private static void loadInitialDrivers() {
		...
		String[] driversList = drivers.split(":");
		println("number of Drivers:" + driversList.length);
		for (String aDriver : driversList) {
		    try {
		        println("DriverManager.Initialize: loading " + aDriver);
		        Class.forName(aDriver, true,
		                ClassLoader.getSystemClassLoader());//这里获取AppClassLoader
		    } catch (Exception ex) {
		        println("DriverManager.Initialize: load failed: " + ex);
		    }
		}
		...
	}

	// ClassLoader
    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");
	        sun.misc.Launcher l = sun.misc.Launcher.getLauncher();// 系统初始化在这里
	        if (l != null) {
	            Throwable oops = null;
	            scl = l.getClassLoader();// 这里获取
	            try {
	                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;
	    }
	}

	// Launcher
	public Launcher() {
	    Launcher.ExtClassLoader var1;
	    try {
	      var1 = Launcher.ExtClassLoader.getExtClassLoader();
	    } catch (IOException var10) {
	      throw new InternalError("Could not create extension class loader", var10);
	    }

	    try {
	      this.loader = Launcher.AppClassLoader.getAppClassLoader(var1);//获取AppClassLoader
	    } catch (IOException var9) {
	      throw new InternalError("Could not create application class loader", var9);
	    }

	    Thread.currentThread().setContextClassLoader(this.loader);//set ContextClassLoader= AppClassLoader
	    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);
	    }
  	}