eclipse 使用tomcat運行JavaWeb項目,文件修改后為何不用重啟tomcat? (運行web項目的4種方式)探究


 
 
 
 
 
 
 

1.情景說明

  在eclipse中,為什么Java文件修改后,重啟tomcat class文件才能生效?

  為什么jsp修改后,不需重啟tomcat就能立即生效?

  為什么靜態資源(*.js,*.css,*.html,圖片、pdf)等文件修改后,會即時生效?

2.探究eclipse的自動構建功能(Build Automatically)

  自動構建的對象:src目錄下的所有文件;

  src目錄被指定用來存放Java源文件(*.java)及配置文件(*.xml,*.properties等),也可以存放其它格式文件。

  自動構建功能有2層含義:

  其一,Java文件;

  當Java文件有變動(Java文件被創建、修改、刪除)時,eclipse會自動調用jdk的編譯命令,

  將Java文件編譯成class文件並輸出到WEB/INF/classes目錄下。

  其二,非Java文件(如:配置文件)。

  當配置文件有變動(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目錄下該文件已經被刪除。

3.在eclipse中,項目開發階段,探究運行JavaWeb項目的常用的4種方式及區別

  方式一:選中項目-->右鍵-->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!

 

4.總結

  總的來說,文件修改后,之所以不用重啟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下配置多個項目。

 

寫在最后

  哪位大佬如若發現文章存在紕漏之處或需要補充更多內容,歡迎留言!!!

 相關推薦:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM