在eclipse中,爲何Java文件修改後,重啓tomcat class文件才能生效?css
爲何jsp修改後,不需重啓tomcat就能當即生效?html
爲何靜態資源(*.js,*.css,*.html,圖片、pdf)等文件修改後,會即時生效?前端
自動構建的對象:src目錄下的全部文件;java
src目錄被指定用來存放Java源文件(*.java)及配置文件(*.xml,*.properties等),也能夠存放其它格式文件。web
自動構建功能有2層含義:瀏覽器
其一,Java文件;tomcat
當Java文件有變更(Java文件被建立、修改、刪除)時,eclipse會自動調用jdk的編譯命令,服務器
將Java文件編譯成class文件並輸出到WEB/INF/classes目錄下。app
其二,非Java文件(如:配置文件)。eclipse
當配置文件有變更(Java文件被建立、修改、刪除)時,不論是什麼樣的文件格式,只要是存在於src目錄下,
eclipse都會自動將其複製到WEB/INF/classes目錄下。
證實:
測試一:修改LoginAction.java文件
修改前
修改後:
測試二:在src目錄下新建一個text文件
WEB-INF/classes目錄下一樣被複制了一份
關閉自動編譯功能,將致使Java文件修改後不會被從新編譯, 配置文件不會同步!
測試三:刪除配置文件txt
先關閉自動構建功能(取消勾選便可)
在eclipse中,剛纔新建的txt文件刪除
你會發現:WEB-INF/classes目錄下該文件並無被刪除。
從新勾選上 Build Automatically
WEB-INF/classes目錄下該文件已經被刪除。
方式一:選中項目-->右鍵-->Run As-->Run on Server
方式二:選中項目-->右鍵-->Debug As-->Debug on Server
方式三:將項目拷貝到tomcat的webapps目錄下,啓動tomcat;
方式四:修改tomcat的server.xml,在Host標籤內配置Context標籤,啓動tomcat。
探究一:
前提:項目發佈在tomcat的webapps目錄下;
當文件內容發生變化後,是eclipse將變化後的文件更新至tomcat,仍是tomcat自動將更新後的文件拷貝至webapps目錄下?
前兩種方式,經過eclipse自動將項目發佈至tomcat的webapps目錄下;
第三種,本身手動將項目拷貝至tomcat的webapps目錄下。
測試1:第一種發佈方式測試
打開base_login.js
打開webapps下對應的該文件
在eclipse中修改該文件
切換到notepad++,你會發現該文件一樣發生了變化
至此,咱們還分不清到底時eclipse更新了該文件仍是tomcat更新了該文件。
測試2:第三種發佈方式測試
在eclipse中修改base_login.js文件後,webapps下對應的該文件並未發生變化!
2018/11/16
測試3:關閉eclipse中負責啓動這個項目的tomcat的自動發佈功能
切換到server窗口
雙擊打開你要修改的tomcat,選擇第一個(默認爲第二個),保存,不用重啓tomcat就會生效。
對文件進行修改後,webapps目錄下該項目對應的文件並未更新!
結論:
在eclipse中,全部格式的文件發生變化後(文件新增、修改、刪除),要想實現將更新後的資源自動發佈至tomcat,須要知足2個條件:
其一:經過eclipse將項目發佈至tomcat的webapps目錄下,判斷依據:
對應的服務器下會展現已經發布的項目。
其二:須要開啓「當資源發生變化時,自動發佈至tomcat的檢測功能」(這個是默認選中的)。
第三種方式之因此不能實現實時更新,是由於不能知足第一個條件!
原生的tomcat是沒有第二個功能的;
因此說,是eclipse負責將變化後的文件更新至webapps中的對應項目下,
與原生的tomcat服務器無關,它只負責從webapps對應的項目下讀取文件!
探究二:
前提:前3種發佈方式中,
哪一種發佈方式,eclipse會自動將class格式文件更新至tomcat?
測試3:debug模式下運行項目(debug as)
打開LoginAction.java
在tomcat的webapps目錄下找到並使用Java反編譯工具打開該文件
修改該文件
使用反編譯工具從新打開對應的文件
tomcat服務器被從新啓動
訪問這個Java類對應的controller,控制檯輸出結果:
測試4:普通模式下運行項目(run as)
在eclipse中修改LoginAcion.java文件後,webapps下對應的class文件並未發生變化!
結論:
手動將項目拷貝到webaps目錄下進行發佈項目,在eclipse對文件進行修改後,並不能實時更新文件,這種方式只適合項目正式運行階段使用;
只有以Debug as方式發佈項目,eclipse纔會將class格式文件更新至tomcat。
探究三:
不論是以run as仍是debug as的形式發佈項目,
當jsp文件發生變化(文件新增、修改、刪除)時,eclipse會自動將變化後的文件更新至tomcat的webapps目錄下對應文件。
爲何?由於eclipse爲tomcat推送的是jsp文件,tomcat負責將jsp轉換成servlet,並編譯成class文件
測試5:tomcat負責jsp的編譯工做
jsp文件被編譯後會被放到tomcat的work目錄下;
只有請求時纔會對jsp文件進行編譯;
每一個目錄下都有jsp文件
由於只請求了登陸頁面,因此tomcat只對其對應的jsp進行了編譯工做
每次對該頁面進行請求時,tomcat都會檢測對應的jsp文件是否更新,若是已經更新就會對其進行從新編譯。
jsp處理流程圖
探究四:
配置Context標籤發佈項目(熱部署)的方式,直接啓動tomcat便可。
具體方法:在eclipse中修改響應的tomcat的server.xml
在Host標籤內添加Context標籤
<Context docBase="D:\workspace-eclipse\jkkywpt_pydzk\web" path="/jkkywpt_pydzk"/>
tomcat的Context標籤的docBase屬性的值指定爲web項目的發佈目錄(WebContent/WebRoot)後,啓動tomcat後,
tomcat會直接訪問將該目錄下的文件並將其加載到tomcat容器中,不會再將項目發佈到webapps目錄下;
測試6:tomcat不會再將項目發佈到webapps目錄下
啓動tomcat
webapps目錄下並未發佈該項目
所以,eclipse就省去了將更新後的資源推送到tomcat的webapps目錄下的步驟。
測試7:eclipse中tomcat服務器的 「當資源發生變化時,自動發佈至tomcat的檢測功能」會失效。
關閉tomcat的自動發佈功能
普通模式下,啓動tomcat
base_login.jsp頁面的原標題爲aaa
瀏覽器展現效果
修改標題爲測試
刷新頁面後
由此,已經證實: eclipse的服務器的自動發佈功能已經不起做用了。
測試8:只有在debug模式下運行項目,Java文件修改後會即時生效!
普通模式下,修改LoginAction.java文件
class文件已經更新
頁面請求後,控制檯並沒有輸出內容
debug模式運行該項目
修改Java文件
瀏覽器刷新後,控制檯輸出結果:
由此,能夠證實:在eclipse中,只有在debug模式下,無需重啓tomcat,Java虛擬機會即時生效。
原理說明:
對於Java類的更新:當監聽到class文件被修改後,經過動態修改內存中的字節碼,將修改過的class文件再次裝載到JVM中;
對於jsp的更新:jsp每次被調用時,tomcat容器都會經過ClassLoader從新加載相應的jsp編譯後的class文件並裝載到JVM中,
tomcat在調用jsp前,會檢測該文件是否被更新,若是被更新,會從新編譯這個jsp文件。
注意:
只有在修改方法體內的Java代碼這一種狀況,不須要重啓tomcat!
總的來講,文件修改後,之因此不用重啓tomcat是由於eclipse的自動構建功能,
自動構建,將文件更新至tomcat的webapps目錄下(class文件除外);
普通模式運行下,java文件從新編譯後,並不會被推送至webapps目錄下;
debug模式運行下,java文件從新編譯後,class文件會被推送至webapps目錄下,而且被tomcat更新至JVM;
jsp文件之因此不用重啓tomcat,也是依賴於eclipse的自動構建功能;
tomcat負責jsp的編譯工做。
發佈及運行項目,對比說明:
拷貝至webapps下發布項目:
運行方式:將項目拷貝至weapps目錄下或者將項目打成的war包再放到weapps目錄下
須要說明的是:tomcat並非從war包解讀所需文件,而是將war進行解壓,也就是說tomcat自己並識別war包,只是被賦予了一個解壓功能而已!
tomcat運行後,自動執行了解壓功能
是否指定解壓功能依賴於server.xml中Host標籤的unpackWARs屬性,默認值爲true
特色:這種方式只適合在運行階段使用;
缺點:不適用於開發階段,沒法進行代碼調試!
使用eclipse發佈項目,並以普通模式運行項目(run):
當Java文件發生變化後,不會即時生效的緣由有二:
其一,tomcat裏的對應class文件並未更新,
其二,eclipse中,只有debug模式啓動項目,Java代碼纔會即時生效。
特色:適合開發階段使用,但不建議使用;
缺點:不重啓tomcat的前提下,只適合前端調試,修改Java文件,必須重啓tomcat。
使用eclipse發佈項目,並以debug模式運行項目(debug):
當Java文件發生變化後,能夠即時生效的緣由有二:
其一,tomcat裏的對應class文件被同步更新,
其二,在eclipse中,以debug模式啓動項目,Java代碼會被更新至Java虛擬機,所以會即時生效。
特色:適合開發階段使用,大部分人會使用。
當Java文件修改後,eclipse雖然會將更新後的文件更新至tomcat,可是默認會重啓tomcat。
如何關閉tomcat重啓?見文末推薦。
(由於就算是不重啓tomcat,jvm也會即時生效)
缺點有二:
其一,Java文件修改後,會重啓tomcat,咱們必須等待項目重啓後才能操做;(經過上面的方式能夠解決);
其二,eclipse會將項目發佈至tomcat的webapps目錄下,當咱們不須要改項目時,需手動將其刪除。
配置Context標籤發佈並運行項目(熱部署):
這種方式就是咱們常說的熱部署!
運行方式:直接啓動tomcat(普通模式、debug模式);
特色:適合開發階段使用, 推崇以debug模式啓動項目。
優勢:
加載的項目會隨着的tomcat的啓動和關閉而產生或死亡,不會留下任何痕跡(work文件夾除外);
而將項目發佈到tomcat的方式,其實是將項目發佈到tomcat指定的發佈目錄webapps文件夾,須要將清理webapps文件夾才能保證只加載該項目到tomcat中;
而採用熱部署的方式不會直接從WebContent目錄下讀取項目,不會在tomcat的webapps下產生任何文件;
方便調試、Java代碼方法體內代碼修改無需重啓;
固然了,能夠在server.xml下配置多個項目。