探索《How Tomcat Work》 心得(六) 加载器 下 Java中URL、tomcat加载器WebappLoader和WebappClassLoader
来源:互联网 发布:php获取对象的属性值 编辑:程序博客网 时间:2024/06/03 17:43
在上一篇文章中,主要介绍了jvm中类加载器的工作原理和小demo,在这篇文章中,介绍下Tomcat封装后的加载器。
Tomcat封装后的加载器,只能够加载指定库中的文件,这里,还拿第二章的程序中的加载器做个例子。
URLClassLoader loader = null;try{URL[] urls = new URL[1]; URLStreamHandler streamHandler = null; File classPath = new File(Constants.WEB_ROOT); String repository = (new URL("file", null, classPath.getAbsolutePath() + File.separator)).toString(); urls[0] = new URL(null, repository, streamHandler); loader = new URLClassLoader(urls);} catch (MalformedURLException e){e.printStackTrace();}介绍下上面用到的URL的构造器, URL(URL context, String spec, URLStreamHandler handler),第一个参数,context,上下文,官方的注释:the context in which to parse the specification,从构造器中的代码的条件(((context != null) && ((newProtocol == null) || newProtocol.equalsIgnoreCase(context.protocol))))可以知道,当传入的上下文中的协议与传入参数中spec中的url协议一致的时候,构造器会使用我们传入的上下文(context)。下面介绍第二个参数,spec,官方的注释:the String to parse as a URL,它就表示一个URL,通过上面的代码片段,这个参数使用URL的另一个构造器URL(String protocol, String host, String file),这个构造器我之后再说,这个参数所表示的url就是我们的类加载器所加载的类的路径。最后一个参数streamHandler,官方解释:the stream handler for the URL。如果这个参数不为空的话,Check for permission to specify a handler,在构造器中就会检查处理程序的权限。这个处理中的代表类的实际路径的spec参数是非空的,其他两个参数是可以为空的,这个构造器被Tomcat看中的点,就在于那两个参数,可以添加上下文和权限控制。
下面介绍先刚刚提到的构造器URL(String protocol, String host, String file),第一个参数protocol,官方解释:the name of the protocol to use.第二个参数:the name of the host.,第三个参数:the file on the host.当我们使用这个构造器的时候,他会调取该对象内的另一构造器:代码片段如下
public URL(String protocol, String host, String file) throws MalformedURLException { this(protocol, host, -1, file); }它又搞出来一个新的构造器URL(String protocol, String host, int port, String file),这个构造器比刚才的构造器多了一个端口的参数,当调用上面的构造器的方法的时候,他会使用传入的主机host在默认端口-1,中查找文件file。但是当我看这个构造器的源码的时候,这里并没有结束,它描述路径的方法:String file = (new File(Constants.WEB_ROOT)).getAbsolutePath() + File.separator ; 描述项目下的web_root文件夹的路径
public URL(String protocol, String host, int port, String file) throws MalformedURLException { this(protocol, host, port, file, null); }
这里的构造器URL(String protocol, String host, int port, String file,URLStreamHandler handler),这是一个最终的构造器。看了这个构造器,我就好奇了,这个东西已经很全了,这个方法不能给构造器添加上下文,其余的添加权限控制类似的东西,这里都可以搞定。通过最开始的demo可以看出,它使用两个url构造器构造一个url实例,为了后面的内容做铺垫呢,为url添加权限,和上下文。
在Tomcat中,加载器都需要实现Loader接口,回顾一下tomcat加载器的UML结构图:
从结构图中,可以看出,在Tomcat的加载器中生活在最底层的是WebappClassLoader,下面,介绍下WebappClassLoader对象与WebappLoader对象,WebappLoader可以控制WebAppClassLoader的生死。从上面的结构图中可以知道,它还继承了URLClassLoader类,从WebappLoader的start()方法的开始,Start this component, initializing our associated class loader.在开始的时候,日志组件和Lifecycle接口中做的事情就不累述了,我在后面的会把前面讲到的几个组件联合起来讲一遍,这里只说loader的事情了,看下面代码块:
1、为JNDI协议注册一个流管理工厂
if (container.getResources() == null) return; // Register a stream handler factory for the JNDI protocol URLStreamHandlerFactory streamHandlerFactory = new DirContextURLStreamHandlerFactory(); try { URL.setURLStreamHandlerFactory(streamHandlerFactory); } catch (Throwable t) { // Ignore the error here. }2、创建classloader加载器,运用java中的反射创建classloader加载器,其中在下面代码块中的变量 loaderClass,是定义好了的常量,Tomcat默认加载器的类名:“org.apache.catalina.loader.WebappClassLoader”
Class clazz = Class.forName(loaderClass); WebappClassLoader classLoader = null; if (parentClassLoader == null) { // Will cause a ClassCast is the class does not extend WCL, but // this is on purpose (the exception will be caught and rethrown) classLoader = (WebappClassLoader) clazz.newInstance(); } else { Class[] argTypes = { ClassLoader.class }; Object[] args = { parentClassLoader }; Constructor constr = clazz.getConstructor(argTypes); classLoader = (WebappClassLoader) constr.newInstance(args); }3、装载有特色的classLoader,下面的各种设置中最主要的就是设置类库列表 addRepository,为classloader指定库,不仅如此,在设置完库之后,他又设置权限相关内容,使classLoader加载各种url中,按照与url匹配的协议加载,这样设置之后,对于首先的classLoader,用起来是安全的。
classLoader.setResources(container.getResources()); classLoader.setDebug(this.debug); classLoader.setDelegate(this.delegate); for (int i = 0; i < repositories.length; i++) { classLoader.addRepository(repositories[i]); } // Configure our repositories setRepositories(); setClassPath(); setPermissions();
4、组件一旦启动起来,下面这个方法可能会经常调用,重载。WebappLoader 支持自动重载,如果 WEB-INF/classes 或者 WEB-INF/lib 目录被重新编译过,在不重启 Tomcat 的情况下必须自动重新载入这些类。为了实现这个目的,WebappLoader 有一个单独的线程每个 x 秒会检查源的时间戳。x 的值由checkInterval 变量定义,它的默认值是 15,也就是每隔 15 秒会进行一次检查是否需要自动重载。
if (reloadable) { log(sm.getString("webappLoader.reloading")); try { threadStart(); } catch (IllegalStateException e) { throw new LifecycleException(e); }}5、重载,下面就是重载线程所做的事情:检查classloader是否发生改变,如果发生改变了,这里会通知上下文,上下文会唤醒一个线程 WebappContextNotifier,这个线程运行,就是让容器重载: ((Context) container).reload();
try { // Perform our modification check if (!classLoader.modified()) continue; } catch (Exception e) { log(sm.getString("webappLoader.failModifiedCheck"), e); continue; } // Handle a need for reloading notifyContext();6、缓存。
每一个可以被加载的类(放在 WEB-INF/classes 目录下的类文件或者 JAR 文件)都被当做一个源。一个源被 org.apache.catalina.loader.ResourceEntry 类表示。一个 ResourceEntry 实例保存一个 byte 类型的数组表示该类、最后修改的数据或者副本等等。所有缓存的源被存放在一个叫做 resourceEntries 的 HashMap 中(在WabappClassLoader中的元素),键值为源名,所有找不到的源都被放在一个名为 notFoundResources 的 HashMap 中。要注意,Tomcat没加载一个类,都会把它放到缓存中,加载器加载类的时候,也是首先在缓存中查找,找不到才会到库中去查找。
- 探索《How Tomcat Work》 心得(六) 加载器 下 Java中URL、tomcat加载器WebappLoader和WebappClassLoader
- 探索《How Tomcat Works》 心得(六) 加载器 上
- Tomcat类加载原理(WebappClassLoader)
- Tomcat的WebappClassLoader(web应用类加载器)详解(一)
- 理解Tomcat的WebappClassLoader(web应用类加载器)
- Tomcat的WebappClassLoader(web应用类加载器)详解(一)
- 理解Tomcat的WebappClassLoader(web应用类加载器)
- Tomcat WebappClassLoader 类加载机制源码分析
- Tomcat源码学习--WebAppClassLoader类加载机制
- Tomcat类加载器机制(Tomcat源码解析六)
- Tomcat类加载器机制(Tomcat源码解析六)
- 探索《How Tomcat Works》心得(一)
- 探索《How Tomcat Works》心得(二)
- JAVA类加载器和tomcat类加载体系
- (tomcat中级)应用Tomcat的WebappClassLoader加载指定目录的jar文件
- (tomcat中级)应用Tomcat的WebappClassLoader加载指定目录的jar文件
- Tomcat源码阅读系列(六)类加载器
- Tomcat源码解析(六):类加载器
- ch340 win7 64位驱动下载 win10也可以用
- iOS开发,json解析
- Java Ant 学习总结
- 【VS开发】字符串进制等转换关系及方法
- 4.Your test database is running in NOARCHIVELOG mode. Which statement is true regarding the type of
- 探索《How Tomcat Work》 心得(六) 加载器 下 Java中URL、tomcat加载器WebappLoader和WebappClassLoader
- android前端与后端服务器URL地址栏传输中文字符出现乱码问题
- Matlab- 路径添加
- HTML网页开发学习笔记(燕十八)-12 margin首页实战
- Android实现应用的增量更新\升级---其一
- Spring配置加事物加扫描dao层 加增强的AOP切面方法
- netbeans xdebug调试过程
- fileupload实现多文件批量上传
- nginx服务器,访问目录下php文档会直接下载,而不是转到页面