how tomcat works 8 Loader

servlet 容器需要自定义的类加载器,不能简单的使用系统提供的类加载器,因为它不能相信自己内部运行的servlet。

如果使用系统类加载器加载servlets和它需要的其它类,那么servlet就可以访问所有的ClassPath下面的类和库,这违背了安全原则。     每一个web程序都有它自己的来加载器。 另外一个原因就是 当WEB-INF下的类或库发生改变,Tomcat需要自己的加载器来支持自动重加载。

java的加载机制 双亲委托加载机制

Tomcat自定义类加载器的原因:

  • 使用合适的规则加载类
  • 缓存之前加载的类
  • 预加载
Listing 8.1: The Loader interface  
 
package org.apache.catalina; 
import java.beans.PropertyChangeListener; 
 
public interface Loader { 
  public ClassLoader getClassLoader(); 
  public Container getContainer(); 
  public void setContainer(Container container); 
  public DefaultContext getDefaultContext(); 
  public void setDefaultContext(DefaultContext defaultContext); 
  public boolean getDelegate(); 
  public void setDelegate(boolean delegate); 
  public String getInfo(); 
  public boolean getReloadable(); 
  public void setReloadable(boolean reloadable); 
  public void addPropertyChangeListener(PropertyChangeListener 
 
    listener); 
  public void addRepository(String repository); 
  public String[] findRepositories(); 
  public boolean modified(); 
  public void removePropertyChangeListener(PropertyChangeListener 
    listener); 
} 
 
Reloader 接口
Listing 8.2: The Reloader interface  
 
package org.apache.catalina.loader; 
public interface Reloader { 
  public void addRepository(String repository); 
  public String[] findRepositories (); 
 
  public boolean modified(); 
} 
 
Tomcat 的WebappLoader

Context来执行类的重加载,而不是classLoader,重要的方法在WebappClassLoader start方法调用后执行。

创建一个类加载器

private WebappClassLoader createClassLoader() throws Exception { 
  Class clazz = Class.forName(loaderClass); 
  WebappClassLoader classLoader = null; 
  if (parentClassLoader == null) { 
    // Will cause a ClassCast if the class does not extend 
    // WebappClassLoader, but this is on purpose (the exception will be 
    // caught and rethrown) 
    classLoader = (WebappClassLoader) clazz.newInstance(); 
    // in Tomcat 5, this if block is replaced by the following: 
    // if (parentClassLoader == null) { 
    //      parentClassLoader = 
    //          Thread.currentThread().getContextClassLoader(); 
    // } 
 
  } 
  else { 
    Class[] argTypes = { ClassLoader.class }; 
    Object[] args = { parentClassLoader }; 
    Constructor constr = clazz.getConstructor(argTypes); 
    classLoader = (WebappClassLoader) constr.newInstance(args); 
  } 
  return classLoader; 
} 

设定仓库

    调用setRepositories()添加仓库到类加载器。 

设置类路径

设置权限

启动一个reload的线程

public void run() { 
  if (debug >= 1) 
    log("BACKGROUND THREAD Starting"); 
 
  // Loop until the termination semaphore is set 
  while (!threadDone) { 
    // Wait for our check interval 
    threadSleep(); 
    if (!started) 
      break; 
    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(); 
    break; 
  } 
 
  if (debug >= 1) 
    log("BACKGROUND THREAD Stopping"); 
} 
 
 



你可能感兴趣的:(how tomcat works 8 Loader)