好的,我們先看看這個(gè) WebappLoader 到底在開(kāi)始的時(shí)候做了什么,先看看他的 start() 方法。
public void start() throws LifecycleException {
// 校驗(yàn) 和 更新 當(dāng)前的組件狀態(tài)。
if (started)
throw new LifecycleException
(sm.getString("webappLoader.alreadyStarted"));
if (debug >= 1)
log(sm.getString("webappLoader.starting"));
lifecycle.fireLifecycleEvent(START_EVENT, null);
started = true;
if (container.getResources() == null)
return;
// 給JNDI protocol注冊(cè)一個(gè)stream handler factory
URLStreamHandlerFactory streamHandlerFactory =
new DirContextURLStreamHandlerFactory();
try {
URL.setURLStreamHandlerFactory(streamHandlerFactory);
} catch (Throwable t) {
// 吃掉了異常
}
//基于我們當(dāng)前的 庫(kù) 構(gòu)建一個(gè)classLoader
try {
classLoader = createClassLoader();
classLoader.setResources(container.getResources());
classLoader.setDebug(this.debug);
classLoader.setDelegate(this.delegate);
for (int i = 0; i < repositories.length; i++) {
classLoader.addRepository(repositories[i]);
}
//配置我們的 庫(kù)
setRepositories();
setClassPath();
setPermissions();
if (classLoader instanceof Lifecycle)
((Lifecycle) classLoader).start();
// 綁定webAppClassLoader的路徑
DirContextURLStreamHandler.bind
((ClassLoader) classLoader, this.container.getResources());
} catch (Throwable t) {
throw new LifecycleException("start: ", t);
}
validatePackages();
// 啟動(dòng)一個(gè)后臺(tái)線程來(lái)自動(dòng)重載
if (reloadable) {
log(sm.getString("webappLoader.reloading"));
try {
threadStart();
} catch (IllegalStateException e) {
throw new LifecycleException(e);
}
}
}
?
那么我們就來(lái)逐步分析一下。首先之前的 狀態(tài)監(jiān)測(cè) 和 JNDI 就不多做介紹了,我們來(lái)看第二個(gè) try 塊中的語(yǔ)句。首先就是classLoader = createClassLoader();這里的classLoader是定義的private WebappClassLoader;那我們就看看createClassLoader 的代碼。
private WebappClassLoader createClassLoader()
throws Exception {
Class clazz = Class.forName(loaderClass);
WebappClassLoader classLoader = null;
if (parentClassLoader == null) {
classLoader = (WebappClassLoader) clazz.newInstance();
} else {
Class[] argTypes = { ClassLoader.class };
Object[] args = { parentClassLoader };
Constructor constr = clazz.getConstructor(argTypes);
classLoader = (WebappClassLoader) constr.newInstance(args);
}
return classLoader;
}
?
private String loaderClass =
"org.apache.catalina.loader.WebappClassLoader";
?
我們可以看見(jiàn),可以通過(guò) setLoaderClass 和 getLoaderClass 這兩個(gè)方法可以更改loaderClass的值。所以也就意味著,我們可以自己定義一個(gè)繼承webappClassLoader 的類,來(lái)更換系統(tǒng)自帶的。
?
之后就是setRepositories,上回我說(shuō)過(guò)了,另外我說(shuō)的讓大家自己找的哪里設(shè)置了/lib文件夾不知大家找到了沒(méi)有,其實(shí)就是 setJarPath 方法.
?
再之后,我就說(shuō)說(shuō)這個(gè)reload,上節(jié)課,我就說(shuō)了一個(gè)大概,就是modified(),檢測(cè)這個(gè)是否被更改了就成,如果更改了。就重新載入,所以,以我們自己的思路,如果要實(shí)現(xiàn)這個(gè)東西,肯定得用一個(gè)新的線程,去檢測(cè)文件最后的修改時(shí)間,之后如果發(fā)現(xiàn)時(shí)間不一致的話,那么就重新加載。其實(shí)tomcat就是這樣實(shí)現(xiàn)的。
?
?
另外就是緩存了,緩存這個(gè)東西其實(shí)tomcat并沒(méi)有太多的實(shí)現(xiàn),java.lang.ClassLoader自己維護(hù)了一個(gè)Vector,而且也是由其管理。之后tomcat自己維護(hù)了一個(gè) 所有/classes下面的可加載類 。在hashMap中。
?
今天說(shuō)的也都結(jié)束了。
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元

