1.ClassLoader 源码
1.通过 ClassLoader.getSystemClassLoader()
进入源码分析。
public static void main(String[] args) {
//1.获取classloader的方法
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
}
2.进入方法
/**
* <p> If the system property "<tt>java.system.class.loader</tt>" is defined
* when this method is first invoked then the value of that property is
* taken to be the name of a class that will be returned as the system
* class loader. The class is loaded using the default system class loader
* and must define a public constructor that takes a single parameter of
* type <tt>ClassLoader</tt> which is used as the delegation parent. An
* instance is then created using this constructor with the default system
* class loader as the parameter. The resulting class loader is defined
* to be the system class loader
* 会返回一个默认的ClassLoader,默认的是SystemClassLoader,如
* 果‘java.system.class.loader’没有指定默认的加载器外。
*/
public static ClassLoader getSystemClassLoader() {
initSystemClassLoader();
if (scl == null) {
return null;
}
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkClassLoaderPermission(scl, Reflection.getCallerClass());
}
return scl;
}
// The class loader for the system
// @GuardedBy("ClassLoader.class")
//系统类加载器
private static ClassLoader scl;
// Set to true once the system class loader has been set
// @GuardedBy("ClassLoader.class")
//如果为true,则系统加载器已经初始化了
private static boolean sclSet;
//初始化系统加载器,包括初始化父加载器
private static synchronized void initSystemClassLoader() {
if (!sclSet) {//boolean类型的静态变量,标记是否被初始化了,解决并发问题
if (scl != null)
throw new IllegalStateException("recursive invocation");
//获取Launcher类实例,jvm加载器都是它的内部类,直接去2看Launcher源码
sun.misc.Launcher l = sun.misc.Launcher.getLauncher();
if (l != null) {
Throwable oops = null;
//scl为classloader内部的缓存静态变量,存储系统类加载器
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;
}
}
//检测用户是否自定义设置了默认的加载类
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");
if (cls == null) {
return parent;
}
//获取自定义类加载器的构造参数,必须是含参的构造参数
Constructor<?> ctor = Class.forName(cls, true, parent)
.getDeclaredConstructor(new Class<?>[] { ClassLoader.class });
//创建实例,父加载器是parent
ClassLoader sys = (ClassLoader) ctor.newInstance(
new Object[] { parent });
//更改上下文使用的加载器
Thread.currentThread().setContextClassLoader(sys);
// 返回
return sys;
}
}
2.Launcher源码
//通过调用静态方法,获取单例实例
public static Launcher getLauncher() {
return launcher;
}
private static Launcher launcher = new Launcher();
//构造方法
public Launcher() {
// Create the extension class loader
//创建扩展类类加载器
ClassLoader extcl;
try {
//获取到一个ExtClassLoader加载器
extcl = ExtClassLoader.getExtClassLoader();
} catch (IOException e) {
throw new InternalError(
"Could not create extension class loader", e);
}
// Now create the class loader to use to launch the application
//创建一个SystemClassLoader加载器,将extcl作为参数
try {
loader = AppClassLoader.getAppClassLoader(extcl);
} catch (IOException e) {
throw new InternalError(
"Could not create application class loader", e);
}
// Also set the context class loader for the primordial thread.
//设定当前线程上下文使用的系统类加载器
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 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);
}
}
}
static class ExtClassLoader extends URLClassLoader {
static {
ClassLoader.registerAsParallelCapable();
}
/**
* create an ExtClassLoader. The ExtClassLoader is created
* within a context that limits which files it can read
*/
public static ExtClassLoader getExtClassLoader() throws IOException
{
final File[] dirs = getExtDirs();
try {
// Prior implementations of this doPrivileged() block supplied
// aa synthesized ACC via a call to the private method
// ExtClassLoader.getContext().
return AccessController.doPrivileged(
new PrivilegedExceptionAction<ExtClassLoader>() {
public ExtClassLoader run() throws IOException {
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();
}
}
void addExtURL(URL url) {
super.addURL(url);
}
/**** 扩展类类加载器 ****/
static class ExtClassLoader extends URLClassLoader {
/**
* create an ExtClassLoader. The ExtClassLoader is created
* within a context that limits which files it can read‘’
* 创建一个扩展类类加载器,这个类加载器限制在他读的文件内
*/
public static ExtClassLoader getExtClassLoader() throws IOException
{
//获取加载的文件目录
final File[] dirs = getExtDirs();
try {
// Prior implementations of this doPrivileged() block supplied
// aa synthesized ACC via a call to the private method
// ExtClassLoader.getContext().
//创建并返回一个ExtClassLoader
return AccessController.doPrivileged(
new PrivilegedExceptionAction<ExtClassLoader>() {
public ExtClassLoader run() throws IOException {
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();
}
}
//获取ExtClassLoader加载的文件目录
private static File[] getExtDirs() {
//配置参数
String s = System.getProperty("java.ext.dirs");
File[] dirs;
if (s != null) {
StringTokenizer st =
new StringTokenizer(s, File.pathSeparator);
int count = st.countTokens();
dirs = new File[count];
for (int i = 0; i < count; i++) {
dirs[i] = new File(st.nextToken());
}
} else {
dirs = new File[0];
}
return dirs;
}
}
/**
* The class loader used for loading from java.class.path.
* runs in a restricted security context.
*/
//SystemClassLoader类加载器的内部类
static class AppClassLoader extends URLClassLoader {
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);
// Note: on bugid 4256530
// Prior implementations of this doPrivileged() block supplied
// a rather restrictive ACC via a call to the private method
// AppClassLoader.getContext(). This proved overly restrictive
// when loading classes. Specifically it prevent
// accessClassInPackage.sun.* grants from being honored.
//
return AccessController.doPrivileged(
new PrivilegedAction<AppClassLoader>() {
public AppClassLoader run() {
URL[] urls =
(s == null) ? new URL[0] : pathToURLs(path);
return new AppClassLoader(urls, extcl);
}
});
}
/*
* Creates a new AppClassLoader
*/
AppClassLoader(URL[] urls, ClassLoader parent) {
super(urls, parent, factory);
}
}
/**
可以返回查看ClassLoader源码了
*/
项目练习地址和笔记:
github: https://github.com/mashenghao/jvn