how tomcat works 總結 三
第七章 日志記錄器
第 7 章包括日志,該組件是用來記錄錯誤信息和其他信息的。
這一章比較簡單,類圖如下:
vcrks/a1vb/Y1sa14yzSu7j2yuSz9rW9zsS8/qGjPGJyPgpMb2dnZXLA4NbQ09DSu7j2ss7K/Sx2ZXJib3NpdHks08PAtLHtyr7I1da+tci8tizErMjPzqpFUlJPUqGjPGJyPgogcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRkFUQUwgPSBJbnRlZ2VyLk1JTl9WQUxVRTs8YnI+CiDU2srks/bI1da+tcTKsbryLNa709C4+LaotcRtZXNzYWdltcR2ZXJib3NpdHnQodPaxKzIz7XEssW74crks/ahozxicj4KINTaQm9vdHN0cmFwxvS2r8DgyejWw0ZpbGVMb2dnZXI8YnI+CjxwcmUgY2xhc3M9"brush:java;"> Bootstrap.java
System.setProperty("catalina.base", System.getProperty("user.dir"));
FileLogger logger = new FileLogger();
logger.setPrefix("FileLog_");
logger.setSuffix(".txt");
logger.setTimestamp(true);
logger.setDirectory("webroot");
context.setLogger(logger);
在使用的時候,調用log(message)即可
private void log(String message) {
Logger logger = connector.getContainer().getLogger();
if (logger != null)
logger.log(threadName + " " + message);
}
第八章 載入器
第 8 章解釋了加載器(loader)。加載器是一個重要的 Catalina 模塊,負責加載 servlet 和一個 web 應用所需的其他類。這章還展示了如何實現應用的重新加載。
類圖如下:
為了自定義載入器是為了以下三個目標:
1在載入類中指定某些規則;
2緩存已經載入的類;
3實現類的預載入;
一個一個說:
第一條,在載入類中指定某些規則
我們設定了兩個數組變量,triggers與packageTriggers,這個兩個數組裡面放置不能訪問的類與包。當我們加載一個類的時候提前檢查類名,包名。這裡有一個問題,我們加載類的順序是:
所有加載過的類都要進行緩存,所以首先需要檢查本地緩存。
· 如果無法再本地緩存找到類,使用 java.langClassLoader 類的 findLoaderClass 方法在緩存查找類、
· 如果在兩個緩存中都無法找到該類,使用系統的類加載器避免從 J2EE 類中覆蓋來的 web 應用程序。
· 如果使用了安全管理器,檢查該類是否允許加載,如果該類不允許加載,則拋出 ClassNotFoundException 異常。
· 如果要加載的類使用了委派標志或者該類屬於 trigger 包中,使用父加載器來加載類,如果父加載器為 null,使用系統加載器加載。
· 從當前的源中加載類
· 如果在當前的源中找不到該類並且沒有使用委派標志,使用父類加載器。如果父類加載器為 null,使用系統加載器
· 如果該類仍然找不到,拋出 ClassNotFoundException 異常
就像前面幾章
http://localhost:8080/Primitive
請求的PrimitiveServlet不會被第二步的類加載器加載。為什麼?請看看類加載器的加載路徑范圍。
第二條 緩存已經裁人的類
還是說上面的那個類,它會通過
clazz = findClass(name);來加載,如果加載成功class會存儲到resouEntries裡,如果失敗就存儲到notFoundResources中。
第三條 實現類的預載入
這條看的不是很懂,DirContext也看的不是很明白。
關於動態載入:
WebLoader.java run方法(部分)
while (!threadDone) {
// Wait for our check interval
threadSleep();
if (!started)
break;
try {
if (!classLoader.modified())
continue;
} catch (Exception e) {
continue;
}
// Handle a need for reloading
notifyContext();
break;
}
modified方法會檢查已經載入的類是否被修改,是否修改的表示就是最後修改的時間是否改變!
若有類被修改,調用notifyContext,在notifyContext中會新建一個線程來調用container的reload方法()?為什麼要新啟一個線程還用說麼?
reload方法()會首先關掉子容器,loader等等,然後在重新開啟#