- 浏览: 80756 次
- 性别:
- 来自: 北京
最新评论
-
zhouxinwolf:
我copy你的代码,启动,用jconsole.exe能看到这个 ...
tomcat 7 源码分析-6 server初始化中的JMX(DynamicMBean)续 -
jieyuan_cg:
呃,这个不就是castor做的事情么?
tomcat 7 源码分析-3 使用Digester读取xml文件实例化server
tomcat在启动的时候使用了三个类加载器
private void initClassLoaders() { try { commonLoader = createClassLoader("common", null); if( commonLoader == null ) { // no config file, default to this loader - we might be in a 'single' env. commonLoader=this.getClass().getClassLoader(); } catalinaLoader = createClassLoader("server", commonLoader); sharedLoader = createClassLoader("shared", commonLoader); } catch (Throwable t) { log.error("Class loader creation threw exception", t); System.exit(1); } }
三个类加载器加载了catalina.properties中的jar
common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar server.loader= shared.loader=
由此可见三个类加载器加载的jar是一样的。为什么要用三个类加载器,从名称看应该是有分别的作用考虑,负载的考虑也许吧。
此外 private ClassLoader createClassLoader(String name, ClassLoader parent)中调用 ClassLoader classLoader = ClassLoaderFactory.createClassLoader
(locations, types, parent);
tomcat自定义了一个类加载器,并且定义了ClassLoaderFactory根据参数定义返回classloader。总体上ClassLoaderFactory就是根据catalina.properties中的jar的位置,做了一些字符串的处理。
public static ClassLoader createClassLoader(String locations[], Integer types[], ClassLoader parent) throws Exception { if (log.isDebugEnabled()) log.debug("Creating new class loader"); // Construct the "class path" for this class loader Set<URL> set = new LinkedHashSet<URL>(); if (locations != null && types != null && locations.length == types.length) { for (int i = 0; i < locations.length; i++) { String location = locations[i]; if ( types[i] == IS_URL ) { URL url = new URL(location); if (log.isDebugEnabled()) log.debug(" Including URL " + url); set.add(url); } else if ( types[i] == IS_DIR ) { File directory = new File(location); directory = new File(directory.getCanonicalPath()); if (!directory.exists() || !directory.isDirectory() || !directory.canRead()) continue; URL url = directory.toURI().toURL(); if (log.isDebugEnabled()) log.debug(" Including directory " + url); set.add(url); } else if ( types[i] == IS_JAR ) { File file=new File(location); file = new File(file.getCanonicalPath()); if (!file.exists() || !file.canRead()) continue; URL url = file.toURI().toURL(); if (log.isDebugEnabled()) log.debug(" Including jar file " + url); set.add(url); } else if ( types[i] == IS_GLOB ) { File directory=new File(location); if (!directory.exists() || !directory.isDirectory() || !directory.canRead()) continue; if (log.isDebugEnabled()) log.debug(" Including directory glob " + directory.getAbsolutePath()); String filenames[] = directory.list(); for (int j = 0; j < filenames.length; j++) { String filename = filenames[j].toLowerCase(Locale.ENGLISH); if (!filename.endsWith(".jar")) continue; File file = new File(directory, filenames[j]); file = new File(file.getCanonicalPath()); if (!file.exists() || !file.canRead()) continue; if (log.isDebugEnabled()) log.debug(" Including glob jar file " + file.getAbsolutePath()); URL url = file.toURI().toURL(); set.add(url); } } } } // Construct the class loader itself URL[] array = set.toArray(new URL[set.size()]); if (log.isDebugEnabled()) for (int i = 0; i < array.length; i++) { log.debug(" location " + i + " is " + array[i]); } StandardClassLoader classLoader = null; if (parent == null) classLoader = new StandardClassLoader(array); else classLoader = new StandardClassLoader(array, parent); return (classLoader); }
定义了类加载器后,在init()中加载
Class<?> startupClass = catalinaLoader.loadClass ("org.apache.catalina.startup.Catalina");
这个才是tomcat的守护进程。
Thread.currentThread().setContextClassLoader(catalinaLoader); SecurityClassLoad.securityClassLoad(catalinaLoader); // Load our startup class and call its process() method if (log.isDebugEnabled()) log.debug("Loading startup class"); Class<?> startupClass = catalinaLoader.loadClass ("org.apache.catalina.startup.Catalina"); Object startupInstance = startupClass.newInstance(); // Set the shared extensions class loader if (log.isDebugEnabled()) log.debug("Setting startup class properties"); String methodName = "setParentClassLoader"; Class<?> paramTypes[] = new Class[1]; paramTypes[0] = Class.forName("java.lang.ClassLoader"); Object paramValues[] = new Object[1]; paramValues[0] = sharedLoader; Method method = startupInstance.getClass().getMethod(methodName, paramTypes); method.invoke(startupInstance, paramValues); catalinaDaemon = startupInstance;
这里要说的是
Class.forName()和ClassLoader.loadClass()的区别?
这两个方法由给类名作为参数,动态的定位并且加载类。然而,两者行为的区别在于用哪个加载器(java.lang.ClassLoader)去加载和加载完后的类是否就已经初始化。
对于Class.forName()最常见的形式就是用一个单独的String为参数,使用当前调用者的类加载器。这个类加载器加载代码执行forName()方法。比较ClassLoader.loadClass(),它是一个实例方法,需要你去选择确定的classloader。这个类加载器可以是也可以不是当前加载器。如果选择一个特定的类加载器对你的设计尤为重要,你可以使用ClassLoader.loadClass()或者三个参数的forName()。
更进一步,Class.forName()的常见形式会初始化加载的类。这样做的就是执行了类的静态初始化方法,也就是byte代码对应的所有静态初始化表达式。这和ClassLoader.loadClass()是不同的,ClassLoader.loadClass()直到类第一次使用的时候才初始化。
发表评论
-
tomcat 7 源码分析-14 tomcat的container设计
2010-08-05 14:52 1652... -
tomcat 7 源码分析-13 处理request的Valve和Valve的链表Pipeline
2010-08-05 11:01 2222tomcat打开endpoint的监听对通过某种协议,通常下是 ... -
tomcat 7 源码分析-12 Enumeration枚举
2010-07-29 15:02 1519Enumeration枚举,就是要 ... -
tomcat 7 源码分析-11 tomcat对http协议的实现
2010-07-28 11:11 3768Implementation of InputBuffer w ... -
tomcat 7 源码分析-10 线程池ThreadPoolExecutor
2010-07-26 14:55 4487tomcat开启socket的accept线程后,其实要做的主 ... -
tomcat 7 源码分析-9 tomcat对ServerSocket的封装和使用
2010-07-26 09:48 6723tomcat中ServerSocket线程监听是否有socke ... -
tomcat 7 源码分析-8 生命周期lifecycle和监听listener
2010-07-22 14:36 3759每个应用都有生命周期lifecycle,可能包括init,st ... -
tomcat 7 源码分析-7 server初始化中的JMX(DynamicMBean)再续
2010-07-21 14:42 2076这里说下tomcat对DynamicMBean的实现和封装。利 ... -
tomcat 7 源码分析-6 server初始化中的JMX(DynamicMBean)续
2010-07-20 18:01 2129先说JMX,The JMX technology provid ... -
tomcat 7 源码分析-5 server初始化中的JMX(DynamicMBean)
2010-07-20 17:27 2219Server的中的初始化基本核心在StandardServer ... -
tomcat 7 源码分析-4 server初始化背后getServer().init()
2010-07-19 22:52 2617getServer().init()其实就是调用server的 ... -
tomcat 7 源码分析-3 使用Digester读取xml文件实例化server
2010-07-19 14:19 2673接下来tomcat要load了,看下面一些程序片段 p ... -
tomcat 7 源码分析-1 关于读取properties及注册系统properties
2010-07-16 15:32 3537Tomact的启动开始于Bootstrap.java,在其in ...
相关推荐
3-7Tomcat中自定义类加载器的使用与源码实现(1).mp4
java自定义类加载classloader文档,包括代码,以及详细的原理及过程
1. 加载(Loading):classpath,jar包,网络,磁盘位置下的类的class以二进制字节流读进来,在内存 2. 验证(Verification)
NULL 博文链接:https://yjhexy.iteye.com/blog/668334
【图解版】深入分析ClassLoader类加载工作机制,从原理到JVM的装载过程,详情分析了ClassLoader加载类以及自定义类加载器的过程,不可用于商业用途,如有版权问题,请联系删除!
java源码源码类加载器泄漏预防库 如果您想避免可怕的java.lang.OutOfMemoryError: Metaspace / PermGen space ,只需将此库包含到您的 Java EE 应用程序中,它就会处理剩下的事情! 要了解有关类加载器泄漏、其原因...
Java加壳核心代码,请调试后使用。本资源配合博客进行讲解,博客地址:http://blog.csdn.net/JavaBuilt/article/details/79522837
ClassLoader类加载机制和原理详解
LazyWorker.zip,一个智能控制进入电子邮件地址,自动检查是否存在域,如果域可以接收电子邮件。LaZyWork是一个帮助类延迟任务。例如,检查需要网络操作且不应在每次按键关闭后进行的输入。
ClassLoader类加载器讲解,理解JAVA类加载机制
类加载器是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一。它使得 Java 类可以被动态加载到 Java 虚拟机中并执行。类加载器从 JDK 1.0 就出现了,最初是为了满足 Java Applet 的需要而开发出来的。Java ...
ClassLoader的API使用和自定义
classloader 源码,自定义classloader
摘要视图订阅曹胜欢欢迎关注微信账号:java那些事:csh624366188.每天一篇java相关的文章登录 | 注册Java程序员从笨鸟到菜鸟(81)3054
Tomcat加载顺序。加载方法以及加载的顺序。
Tomcat自带的日志实现是tomcat-juli.jar,它是对默认的JDK日志java.util.logging进行...但是tomcat-juli可以针对不同的classloader来使用不同的配置文件,使得tomcat下不同的Web应用程序可以使用各自独立的日志文件。
java应用程序类加载器(ClassLoader for java Application),类似exe4j, 方便启动java程序, 配置灵活,支持多平台选择性配置
本篇文章主要介绍了详解Android类加载ClassLoader,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
classloader教程 --- from IBM