好的,我們先看看這個 WebappLoader 到底在開始的時候做了什么,先看看他的 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注冊一個stream handler factory URLStreamHandlerFactory streamHandlerFactory = new DirContextURLStreamHandlerFactory(); try { URL.setURLStreamHandlerFactory(streamHandlerFactory); } catch (Throwable t) { // 吃掉了異常 } //基于我們當(dāng)前的 庫 構(gòu)建一個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]); } //配置我們的 庫 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(); // 啟動一個后臺線程來自動重載 if (reloadable) { log(sm.getString("webappLoader.reloading")); try { threadStart(); } catch (IllegalStateException e) { throw new LifecycleException(e); } } }
?
那么我們就來逐步分析一下。首先之前的 狀態(tài)監(jiān)測 和 JNDI 就不多做介紹了,我們來看第二個 try 塊中的語句。首先就是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";
?
我們可以看見,可以通過 setLoaderClass 和 getLoaderClass 這兩個方法可以更改loaderClass的值。所以也就意味著,我們可以自己定義一個繼承webappClassLoader 的類,來更換系統(tǒng)自帶的。
?
之后就是setRepositories,上回我說過了,另外我說的讓大家自己找的哪里設(shè)置了/lib文件夾不知大家找到了沒有,其實(shí)就是 setJarPath 方法.
?
再之后,我就說說這個reload,上節(jié)課,我就說了一個大概,就是modified(),檢測這個是否被更改了就成,如果更改了。就重新載入,所以,以我們自己的思路,如果要實(shí)現(xiàn)這個東西,肯定得用一個新的線程,去檢測文件最后的修改時間,之后如果發(fā)現(xiàn)時間不一致的話,那么就重新加載。其實(shí)tomcat就是這樣實(shí)現(xiàn)的。
?
?
另外就是緩存了,緩存這個東西其實(shí)tomcat并沒有太多的實(shí)現(xiàn),java.lang.ClassLoader自己維護(hù)了一個Vector,而且也是由其管理。之后tomcat自己維護(hù)了一個 所有/classes下面的可加載類 。在hashMap中。
?
今天說的也都結(jié)束了。
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
