首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

jvm 类加载器 跟 tomcat类加载器

2012-11-03 
jvm 类加载器 和 tomcat类加载器方法说明getParent() 返回该类加载器的父类加载器。loadClass(String name)

jvm 类加载器 和 tomcat类加载器

方法说明getParent() 返回该类加载器的父类加载器。loadClass(String name) 加载名称为 name的类,返回的结果是 java.lang.Class类的实例。findClass(String name) 查找名称为 name的类,返回的结果是 java.lang.Class类的实例。findLoadedClass(String name) 查找名称为 name的已经被加载过的类,返回的结果是 java.lang.Class类的实例。defineClass(String name, byte[] b, int off, int len) 把字节数组 b中的内容转换成 Java 类,返回的结果是 java.lang.Class类的实例。这个方法被声明为 final的。resolveClass(Class<?> c) 链接指定的 Java 类。

对于 表 1中给出的方法,表示类名称的 name参数的值是类的二进制名称。需要注意的是内部类的表示,如 com.example.Sample$1com.example.Sample$Inner等表示方式。这些方法会在下面介绍类加载器的工作机制时,做进一步的说明。下面介绍类加载器的树状组织结构。


?

代码清单 1演示了类加载器的树状组织结构。


清单 1. 演示类加载器的树状组织结构

????//要先加载相关实体资源(.jar) 再加载查找的资源本身
????protected ResourceEntry findResourceInternal(String name, String path) {
????????//先根据类名从缓存中查找对应资源 ,有则直接返回?
????????ResourceEntry entry = (ResourceEntry) resourceEntries.get(name);
????????if (entry != null)
????????????return entry;
????????int contentLength = -1;//资源二进制数据长度
????????InputStream binaryStream = null;//资源二进制输入流

????????int jarFilesLength = jarFiles.length;//classpath中的jar包个数
????????int repositoriesLength = repositories.length;//仓库数(classpath每一段称为repository仓库)
????????int i;
????????Resource resource = null;//加载的资源实体
????????boolean fileNeedConvert = false;
????????//对每个仓库迭代,直接找到相应的entry,如果查找的资源是一个独立的文件,在这个代码块可以查找到相应资源,
????????//如果是包含在jar包中的类,这段代码并不能找出其对应的资源
????????for (i = 0; (entry == null) && (i < repositoriesLength); i++) {
????????????try {
????????????????String fullPath = repositories[i] + path;//仓库路径 加资源路径得到全路径
????????????????Object lookupResult = resources.lookup(fullPath);//从资源库中查找资源

????????????????if (lookupResult instanceof Resource) {
????????????????????resource = (Resource) lookupResult;
????????????????}
????????????????//到这里没有抛出异常,说明资源已经找到,现在构造entry对象
?????????????????if (securityManager != null) {
????????????????????PrivilegedAction dp =
????????????????????????new PrivilegedFindResource(files[i], path);
????????????????????entry = (ResourceEntry)AccessController.doPrivileged(dp);
?????????????????} else {
????????????????????entry = findResourceInternal(files[i], path);//这个方式只是构造entry并给其codebase和source赋值
?????????????????}
?????????????????//获取资源长度和最后修改时间
????????????????ResourceAttributes attributes =
????????????????????(ResourceAttributes) resources.getAttributes(fullPath);
????????????????contentLength = (int) attributes.getContentLength();
????????????????entry.lastModified = attributes.getLastModified();
????????????????//资源找到,将二进制输入流赋给binaryStream
????????????????if (resource != null) {
????????????????????try {
????????????????????????binaryStream = resource.streamContent();
????????????????????} catch (IOException e) {
????????????????????????return null;
????????????????????}
????????????????????//将资源的最后修改时间加到列表中去,代码略去,参加源码?

????????????????}

????????????} catch (NamingException e) {
????????????}
????????}
????????if ((entry == null) && (notFoundResources.containsKey(name)))
????????????return null;
????????//开始从jar包中查找
????????JarEntry jarEntry = null;
????????synchronized (jarFiles) {
????????????if (!openJARs()) {
????????????????return null;
????????????}
????????????for (i = 0; (entry == null) && (i < jarFilesLength); i++) {
????????????????jarEntry = jarFiles[i].getJarEntry(path);//根据路径从jar包中查找资源
????????????????//如果jar包中找到资源,则定义entry并将二进制流等数据赋给entry,同时将jar包解压到workdir.
????????????????if (jarEntry != null) {
????????????????????entry = new ResourceEntry();
????????????????????try {
????????????????????????entry.codeBase = getURL(jarRealFiles[i], false);
????????????????????????String jarFakeUrl = getURI(jarRealFiles[i]).toString();
????????????????????????jarFakeUrl = "jar:" + jarFakeUrl + "!/" + path;
????????????????????????entry.source = new URL(jarFakeUrl);
????????????????????????entry.lastModified = jarRealFiles[i].lastModified();
????????????????????} catch (MalformedURLException e) {
????????????????????????return null;
????????????????????}
????????????????????contentLength = (int) jarEntry.getSize();
????????????????????try {
????????????????????????entry.manifest = jarFiles[i].getManifest();
????????????????????????binaryStream = jarFiles[i].getInputStream(jarEntry);
????????????????????} catch (IOException e) {
????????????????????????return null;
????????????????????}
????????????????????if (antiJARLocking && !(path.endsWith(".class"))) {
????????????????????????//解压jar包代码,参见源码
????????????????????}
????????????????}
????????????}
????????????if (entry == null) {
????????????????synchronized (notFoundResources) {
????????????????????notFoundResources.put(name, name);
????????????????}
????????????????return null;
????????????}
????????????//从二进制流将资源内容读出
????????????if (binaryStream != null) {
????????????????byte[] binaryContent = new byte[contentLength];
????????????????//读二进制流的代码,这里省去,参见源码
????????????????entry.binaryContent = binaryContent;
????????????}
????????}
????????// 将资源加到缓存中
????????synchronized (resourceEntries) {
????????????ResourceEntry entry2 = (ResourceEntry) resourceEntries.get(name);
????????????if (entry2 == null) {
????????????????resourceEntries.put(name, entry);
????????????} else {
????????????????entry = entry2;
????????????}
????????}
????????return entry;
????}

?

?jvm 类加载器 跟 tomcat类加载器jvm 类加载器 跟 tomcat类加载器
    ?jvm 类加载器 跟 tomcat类加载器jvm 类加载器 跟 tomcat类加载器
      ?jvm 类加载器 跟 tomcat类加载器jvm 类加载器 跟 tomcat类加载器

        ?

        ?jvm 类加载器 跟 tomcat类加载器jvm 类加载器 跟 tomcat类加载器
          protected?ResourceEntry?findResourceInternal(String?name,?String?path)?{ ??????//?先根据类名从缓存中查找对应资源?,有则直接返回 ??????ResourceEntry?entry?=?(ResourceEntry)?resourceEntries.get(name); ??????if?(entry?!=?null) ??????????return?entry; ??????int?contentLength?=?-1; ??????//?资源二进制数据长度 ??????InputStream?binaryStream?=?null; ??????//?资源二进制输入流 ??????int?jarFilesLength?=?jarFiles.length; ??????//?classpath中的jar包个数 ??????int?repositoriesLength?=?repositories.length; ??????//?仓库数(classpath每一段称为repository仓库) ??????int?i; ??????Resource?resource?=?null; ??????//?加载的资源实体 ??????boolean?fileNeedConvert?=?false; ??????//?对每个仓库迭代,直接找到相应的entry,如果查找的资源是一个独立的文件,在这个代码块可以查找到相应资源, ??????//?如果是包含在jar包中的类,这段代码并不能找出其对应的资源 ??????for?(i?=?0;?(entry?==?null)?&&?(i?<?repositoriesLength);?i++)?{ ??????????try?{ ??????????????String?fullPath?=?repositories[i]?+?path; ??????????????//?仓库路径?加资源路径得到全路径 ??????????????Object?lookupResult?=?resources.lookup(fullPath); ??????????????//?从资源库中查找资源 ??????????????if?(lookupResult?instanceof?Resource)?{ ??????????????????resource?=?(Resource)?lookupResult; ??????????????} ??????????????//?到这里没有抛出异常,说明资源已经找到,现在构造entry对象 ??????????????if?(securityManager?!=?null)?{ ??????????????????PrivilegedAction?dp?=?new?PrivilegedFindResource(files[i],?path); ??????????????????entry?=?(ResourceEntry)?AccessController.doPrivileged(dp); ??????????????}?else?{ ??????????????????entry?=?findResourceInternal(files[i],?path); ??????????????????//?这个方式只是构造entry并给其codebase和source赋值 ??????????????} ??????????????//?获取资源长度和最后修改时间 ??????????????ResourceAttributes?attributes?=?(ResourceAttributes)?resources.getAttributes(fullPath); ??????????????contentLength?=?(int)?attributes.getContentLength(); ??????????????entry.lastModified?=?attributes.getLastModified(); ??????????????//?资源找到,将二进制输入流赋给binaryStream ??????????????if?(resource?!=?null)?{ ??????????????????try?{ ??????????????????????binaryStream?=?resource.streamContent(); ??????????????????}?catch?(IOException?e)?{ ??????????????????????return?null; ??????????????????} ??????????????????//?将资源的最后修改时间加到列表中去,代码略去,参加源码 ??????????????} ????????????}?catch?(NamingException?e)?{ ??????????} ??????} ????????if?((entry?==?null)?&&?(notFoundResources.containsKey(name))) ??????????return?null; ??????//?开始从jar包中查找 ??????JarEntry?jarEntry?=?null; ??????synchronized?(jarFiles)?{ ??????????if?(!openJARs())?{ ??????????????return?null; ??????????} ??????????for?(i?=?0;?(entry?==?null)?&&?(i?<?jarFilesLength);?i++)?{ ??????????????jarEntry?=?jarFiles[i].getJarEntry(path); ??????????????//?根据路径从jar包中查找资源 ??????????????//?如果jar包中找到资源,则定义entry并将二进制流等数据赋给entry,同时将jar包解压到workdir. ??????????????if?(jarEntry?!=?null)?{ ??????????????????entry?=?new?ResourceEntry(); ??????????????????try?{ ??????????????????????entry.codeBase?=?getURL(jarRealFiles[i],?false); ??????????????????????String?jarFakeUrl?=?getURI(jarRealFiles[i]).toString(); ??????????????????????jarFakeUrl?=?"jar:"?+?jarFakeUrl?+?"!/"?+?path; ??????????????????????entry.source?=?new?URL(jarFakeUrl); ??????????????????????entry.lastModified?=?jarRealFiles[i].lastModified(); ??????????????????}?catch?(MalformedURLException?e)?{ ??????????????????????return?null; ??????????????????} ??????????????????contentLength?=?(int)?jarEntry.getSize(); ??????????????????try?{ ??????????????????????entry.manifest?=?jarFiles[i].getManifest(); ??????????????????????binaryStream?=?jarFiles[i].getInputStream(jarEntry); ??????????????????}?catch?(IOException?e)?{ ??????????????????????return?null; ??????????????????} ??????????????????if?(antiJARLocking?&&?!(path.endsWith(".class")))?{ ??????????????????????//?解压jar包代码,参见源码 ??????????????????} ????????????????} ????????????????if?(entry?==?null)?{ ??????????????????synchronized?(notFoundResources)?{ ??????????????????????notFoundResources.put(name,?name); ??????????????????} ??????????????????return?null; ??????????????} ??????????????//?从二进制流将资源内容读出 ??????????????if?(binaryStream?!=?null)?{ ??????????????????byte[]?binaryContent?=?new?byte[contentLength]; ??????????????????//?读二进制流的代码,这里省去,参见源码 ??????????????????entry.binaryContent?=?binaryContent; ??????????????} ??????????} ??????????//?将资源加到缓存中 ??????????synchronized?(resourceEntries)?{ ??????????????ResourceEntry?entry2?=?(ResourceEntry)?resourceEntries.get(name); ??????????????if?(entry2?==?null)?{ ??????????????????resourceEntries.put(name,?entry); ??????????????}?else?{ ??????????????????entry?=?entry2; ??????????????} ??????????} ??????????return?entry; ??????} ??}??

        ?

热点排行