《How Tomcat Works》讀書筆記(八)Loader

Loader就是一個普通的Java類加載器。

Tomcat經過實現org.apache.catalina.Loader接口來定義Loader,一個servlet容器須要制定本身的 Loader
  1. servlet容器不該該信任servlet,若是容器使用系統類加載器,那麼servlet能夠"看見"CLASSPATH中的class.
  2. 在加載類時能夠加入特定的規則
  3. 能夠換成以前加載過的類
  4. 支持自動重加載(熱部署):自定製的類加載器(S)使用另一個線程一直檢查servlet和它依賴的class(S負責加載的)的時間戳,當WEB-INF/classes或WEB-INF/lib目錄中的類被改變時,從新加載之。只需實現org.apache.catalina.loader.Reloader接口

Java類加載器 java

jvm從java1.2開始使用3個類加載器:啓動類加載器(祖父 GF)、擴展類加載器(父親 F)、系統類加載器(兒子 S)。 apache

  1. GF:由操做系統本地代碼編寫,負責加載JVM啓動所需的類庫,還負責加載Java核心類庫(如java.lang.*、java.io.*)
  2. F:負責加載在標準擴展目錄中的類(/jdk/jre/lib/ext)
  3. S:加載CLASSPATH中的類.

雙親委託模式 緩存

      當JVM要加載一個類時,S首先被調用,但S不會去直接加載這個類,他會委託給F,而F會委託給GF,若是GF沒有找到這個類就讓F去加載,若是F也沒找到,就讓S去加載。若是最後S也沒找到,就會拋出java.lang.ClassNotFoundException異常。 安全

雙親委託模式有效保證了類加載的安全性:
      有人惡意寫了一個java.lang.String類,但願可以替代java核心同名類,當String在程序某處被調用時,S委託F,F委託GF,GF會找到真正的Java核心庫中的String類並加載,而惡意的String不會得到被加載的機會。
app

Web應用在加載servlet和其餘class是要遵照規則的:
      servlet只可使用部署在WEB-INF/classes或其子目錄下的class.
放在WEB-INF/lib下的jar. jvm

一個Tomcat的Loader表明的是一個Web應用加載器而不是一個類加載器.它必須實現org.apache.catalina.Loader接口.一個Loader的實現擁有一個類加載器(org.apache.catalina.loader.WebappClassLoader)並能夠經過Loader接口中定義的getClassLoader方法得到它。 spa

Loader一般會和一個Context(表明一個Web應用,也是一個容器)綁定在一塊兒經過Loader接口中定義的getContainer和setContainer方法,得到和設置Context.
操作系統

重加載
      若是Conext中的class被改變了,Loader(若是支持的話)會調用Context接口中定義的reload方法從新加載它們,而不須要重啓Tomcat。Loader中定義了setReloadable和getReloadable來決定是否支持重加載。
      默認的org.apache.catalina.core.StandardContext是不支持重加載的,若是想要支持,咱們須要在server.xml添加一個Context元素:
      <Context path="/myApp" docBase="myApp" debug="0" reloadable="true"/>
.net

Loader接口定義
線程

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

Tomcat提供了一個Loader的實現:org.apache.catalina.loader.WebappLoader
而且提供了它的類加載器實現:org.apache.catalina.loader.WebappClassLoader(繼承了java.net.URLClassLoader類)

Reloader接口

public interface Reloader {
    public void addRepository(String repository);
    public String[] findRepositories ();
    //true:支持重加載
    public boolean modified();
}
org.apache.catalina.loader.WebappLoader
  1. 建立一個類加載器
  2. 設置repositories倉庫(能夠理解爲Loader去加載class的地方)
  3. 設置classpaht
  4. 設置權限
  5. 開啓一個新線程來實現自動重加載(循環檢查)

org.apache.catalina.loader.WebappClassLoader

緩存加載過的類

  1. local cache:WebappClassLoader實例本身來管理
  2. super cache:java.lang.ClassLoader管理了一個Vector(存以前加載過的類)來防止GC,由超類管理
加載類
  1. 檢查local cache
  2. 檢查super cache
  3. 檢查repositories倉庫 找到加載 找不到拋異常ClassNotFoundException
相關文章
相關標籤/搜索