博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
分析AppClassLoader,ExtClassLoader 和URLClassLoader 的关系
阅读量:4313 次
发布时间:2019-06-06

本文共 6932 字,大约阅读时间需要 23 分钟。

测试代码: 

 

1 class Hello 2 { 3   public String str = "Hello World"; 4   public void fun() 5   { 6     System.out.println(str); 7   } 8 } 9 10 public class Test{12   public static void main(String[] args)13   {14     Hello hello = new Hello();15     hello.fun();16 17     System.out.println("----------------------");18 19     //Hello类的类加载器20     ClassLoader classLoaderOfHello = Hello.class.getClassLoader();21 22     System.out.println("Hello is Loaded by : "+classLoaderOfHello);23 24     System.out.println("----------------------");25 26     //Hello类的类加载器的Class对象27     Class AppClazz = classLoaderOfHello.getClass();28 29     //分析Hello类的类加载器的Class对象的类继承关系30     while(AppClazz != null)31     {32     System.out.println(AppClazz);33 34     AppClazz = AppClazz.getSuperclass();35     }36 37     System.out.println("----------------------");38 39     //取得扩展器加载器的类对象Class40     Class ExtClazz = classLoaderOfHello.getParent().getClass();41 42     while(ExtClazz != null)43     {44     System.out.println(ExtClazz);45 46     ExtClazz = ExtClazz.getSuperclass();47     }48   }49 }50 51

 

结论:

1.  用户自定义的类是由 应用(系统)类加载器AppClassLoader加载

2.  在”父亲委托机制”中,扩展类加载器ExtClassLoader是AppClassLoader的父亲,并不是继承关系,而是ExtClassLoader加载了AppClassLoader

3.  AppClassLoader 和 ExtClassLoader 都扩展于 URLClassLoader加载器.

4.  也同时说明AppClassLoader而非继承ExtClassLoader.

 

继承关系:

java.lang.Object

       --- java.lang.ClassLoader

              --- java.security.SecureClassLoader
                      ---  java.net.URLClassLoader
                            --- sun.misc.Launcher$ExtClassLoader

 

 

java.lang.Object

       --- java.lang.ClassLoader

              --- java.security.SecureClassLoader
                      ---  java.net.URLClassLoader
                            --- sun.misc.Launcher$AppClassLoader

 

 

其实很简单嘛,直接看AppClassLoader的源代码就可以了嘛,哈哈,终于找到了好东东,上

JDK7: http://download.java.net/openjdk/jdk7/

JDK6: http://download.java.net/openjdk/jdk6/

下载其源代码就可以了

现在直接来看其源代码:

/**
* The class loader used for loading from java.class.path.
* runs in a restricted security context.
*/
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>() {
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);
}

/**

* Override loadClass so we can checkPackageAccess.
*/
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));
}
}
return (super.loadClass(name, resolve));
}

/**

* allow any classes loaded from classpath to exit the VM.
*/
protected PermissionCollection getPermissions(CodeSource codesource)
{
PermissionCollection perms = super.getPermissions(codesource);
perms.add(new RuntimePermission("exitVM"));
return perms;
}

/**

* This class loader supports dynamic additions to the class path
* at runtime.
*
* @see java.lang.instrument.Instrumentation#appendToSystemClassPathSearch
*/
private void appendToClassPathForInstrumentation(String path) {
assert(Thread.holdsLock(this));

// addURL is a no-op if path already contains the URL

super.addURL( getFileURL(new File(path)) );
}

/**

* create a context that can read any directories (recursively)
* mentioned in the class path. In the case of a jar, it has to
* be the directory containing the jar, not just the jar, as jar
* files might refer to other jar files.
*/

private static AccessControlContext getContext(File[] cp)

throws java.net.MalformedURLException
{
PathPermissions perms =
new PathPermissions(cp);

ProtectionDomain domain =

new ProtectionDomain(new CodeSource(perms.getCodeBase(),
(java.security.cert.Certificate[]) null),
perms);

AccessControlContext acc =

new AccessControlContext(new ProtectionDomain[] { domain });

return acc;

}
}

哈,看了AppClassLoader的源代码后,大家明白了吧,AppClassLoader 继承了URLClassLoader,而且构造函数是直接调用URLClassLoader的构造

函数,loadClass(String name, boolean resolve)方法只是简单做了包的安全检查,然后就调用ClassLoader的 loadClass(String name, boolean resolve)方法了,其它的话,也是差不多..所以其功能和URLClassLoader差不多...

 

在ExtClassLoader也差不多,大家看看源代码就明了的:

/*

* Creates a new ExtClassLoader for the specified directories.
*/
public ExtClassLoader(File[] dirs) throws IOException {
super(getExtURLs(dirs), null, factory);
}

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;
}

private static URL[] getExtURLs(File[] dirs) throws IOException {

Vector<URL> urls = new Vector<URL>();
for (int i = 0; i < dirs.length; i++) {
String[] files = dirs[i].list();
if (files != null) {
for (int j = 0; j < files.length; j++) {
if (!files[j].equals("meta-index")) {
File f = new File(dirs[i], files[j]);
urls.add(getFileURL(f));
}
}
}
}
URL[] ua = new URL[urls.size()];
urls.copyInto(ua);
return ua;
}

/*

* Searches the installed extension directories for the specified
* library name. For each extension directory, we first look for
* the native library in the subdirectory whose name is the value
* of the system property <code>os.arch</code>. Failing that, we
* look in the extension directory itself.
*/
public String findLibrary(String name) {
name = System.mapLibraryName(name);
URL[] urls = super.getURLs();
File prevDir = null;
for (int i = 0; i < urls.length; i++) {
// Get the ext directory from the URL
File dir = new File(urls[i].getPath()).getParentFile();
if (dir != null && !dir.equals(prevDir)) {
// Look in architecture-specific subdirectory first
// Read from the saved system properties to avoid deadlock
String arch = VM.getSavedProperty("os.arch");
if (arch != null) {
File file = new File(new File(dir, arch), name);
if (file.exists()) {
return file.getAbsolutePath();
}
}
// Then check the extension directory
File file = new File(dir, name);
if (file.exists()) {
return file.getAbsolutePath();
}
}
prevDir = dir;
}
return null;
}

private static AccessControlContext getContext(File[] dirs)

throws IOException
{
PathPermissions perms =
new PathPermissions(dirs);

ProtectionDomain domain = new ProtectionDomain(

new CodeSource(perms.getCodeBase(),
(java.security.cert.Certificate[]) null),
perms);

AccessControlContext acc =

new AccessControlContext(new ProtectionDomain[] { domain });

return acc;

}
}

 

---------------------

作者:irelandken
来源:CSDN
原文:https://blog.csdn.net/irelandken/article/details/7046689
版权声明:本文为博主原创文章,转载请附上博文链接!

转载于:https://www.cnblogs.com/makai/p/11080430.html

你可能感兴趣的文章
关于CSS伪类选择器
查看>>
适用于带文字 和图片的垂直居中方法
查看>>
Part 2 - Fundamentals(4-10)
查看>>
使用Postmark测试后端存储性能
查看>>
NSTextView 文字链接的定制化
查看>>
第五天站立会议内容
查看>>
CentOs7安装rabbitmq
查看>>
(转))iOS App上架AppStore 会遇到的坑
查看>>
解决vmware与主机无法连通的问题
查看>>
做好产品
查看>>
项目管理经验
查看>>
笔记:Hadoop权威指南 第8章 MapReduce 的特性
查看>>
JMeter响应数据出现乱码的处理-三种解决方式
查看>>
获取设备实际宽度
查看>>
Notes on <High Performance MySQL> -- Ch3: Schema Optimization and Indexing
查看>>
Alpha冲刺(10/10)
查看>>
数组Array的API2
查看>>
为什么 Redis 重启后没有正确恢复之前的内存数据
查看>>
No qualifying bean of type available问题修复
查看>>
第四周助教心得体会
查看>>