spring結合時,web.xml的配置


 

<!--
1、 web.xml配置 
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>webapp.root</param-value>
</context-param>
"webapp.root"這個字符串可以隨便寫任何字符串。如果不配置默認值是"webapp.root"。

可以用System.getProperty("webapp.root")來動態獲項目的運行路徑。
一般返回結果例如:/usr/local/tomcat6/webapps/項目名

2、解決以下報錯
部署在同一容器中的Web項目,要配置不同的<param-value>,不能重復,否則報類似下面的錯誤:
Web app root system property already set to different value: 'webapp.root' = [/home/user/tomcat/webapps/project1/] instead of [/home/user/tomcat/webapps/project2/] - Choose unique values for the 'webAppRootKey' context-param in your web.xml files! 
意思是“webapp.root”這個key已經指向了項目1,不可以再指向項目2.

3、加載方式
Spring通過org.springframework.web.util.WebAppRootListener 這個監聽器來運行時的項目路徑。
但是如果在web.xml中已經配置了 org.springframework.web.util.Log4jConfigListener這個監聽器,
則不需要配置WebAppRootListener了。因為Log4jConfigListener已經包含了WebAppRootListener的功能

4、在運行時動態的找出項目的路徑
在log4j.properties配置文件,就可以按下面的方式使用${webapp.root}:
log4j.appender.file.File=${webapp.root}/WEB-INF/logs/sample.log 
就可以在運行時動態的找出項目的路徑
-->
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>webapp.report.services</param-value>
</context-param>


<!-- 這是默認路徑和默認文件名,本來可以不用配置log4jConfigLocation。為了更清晰,配置了該參數值;否則,需要配置該參數值 -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value>
</context-param>

<!-- 容器會每6秒掃描log4j的配置文件。動態的改變記錄級別和策略,即修改log4j.properties,不需要重啟Web應用。  -->
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>6000</param-value> 
</context-param>

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-beans.xml</param-value>
</context-param>

<!-- Log4jConfigListener需要在ContextLoaderListener之前 -->
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>com.fangdd.report.basic.web.SessionListener</listener-class>
</listener>
<!--
SSH內存泄露及Spring Quartz問題

版權聲明:轉載時請以超鏈接形式標明文章原始出處和作者信息及本聲明
http://anoxia.blogbus.com/logs/34360203.html

問題的起因:

為客戶開發了一個系統權且稱他為TM吧,用的是tomcat6+myelipse6+jdk1.6環境,框架用SSH。我調試完這個系統程序后,將此程序重新COPY了一份,改名叫TMT,但是發布的Web名還是叫TM。同樣用同一個Tomcat來Run的。問題發生了,我在TMT項目里修改后,RUN起來運行的居然是TM項目中的代碼。
嘗試過刪除TOMCAT6下的WORK目錄下的緩存文件,也嘗試過在TOMCAT的BIN目錄下的Startup.bat中腳本頭部加上一句:
rd /s /q TM
rd /s /q ..\work\Catalina\localhost\TM
..\bin\catalina start
還是沒有用。
在TOMCAT6的conf目錄下server.xml中添加:
<Context path="" docBase="" debug="0" reloadable="true" />
也還是沒有用。
在Tomcat的manage里也reload過了,都無法更新程序版本,運行都是之前TM項目中的代碼,之后TMT項目里的代碼鏈接的數據庫和TM項目鏈接的數據庫是不同的,將hibernate的執行sql的語句顯示在Console界面中,發現數據庫用的是TM項目中的數據庫,可我運行的程序是 TMT項目。無語了。。。。

嘗試清除Eclipse的緩存,刪除[eclipsehome]/configuration下除.settings子目錄和config.ini文件外其它的子目錄。 還是沒有用,仍然調用是老的程序。
最后嘗試在myclipse的快捷方式啟動是加入參數 -clean啟動,還是無濟於事。

=======================================================

接下來在javaeye中遍尋解決方案,無意中翻到Struts+Spring+Hibernate內存泄漏查找與處理一篇Robbin參與討論的帖子,談到使用org.springframework.web.util.IntrospectorCleanupListener監聽器處理由 JavaBeans Introspector的使用而引起的緩沖泄露的問題,和Quartz定時調度比較理想的使用方式。以下節選部分內容供今后參考學習。

=======================================================

IntrospectorCleanupListener使用:

"在服務器運行過程中,Spring不停的運行的計划任務和OpenSessionInViewFilter,使得Tomcat反復加載對象而產生框架並用時可能產生的內存泄漏,則使用IntrospectorCleanupListener作為相應的解決辦法。"

引用:

spring中的提供了一個名為org.springframework.web.util.IntrospectorCleanupListener的監聽器。它主要負責處理由 JavaBeans Introspector的使用而引起的緩沖泄露。spring中對它的描述如下:它是一個在web應用關閉的時候,清除JavaBeans Introspector的監聽器.web.xml中注冊這個listener.可以保證在web 應用關閉的時候釋放與掉這個web 應用相關的class loader 和由它管理的類如果你使用了JavaBeans Introspector來分析應用中的類,Introspector 緩沖中會保留這些類的引用.結果在你的應用關閉的時候,這些類以及web 應用相關的class loader沒有被垃圾回收.不幸的是,清除Introspector的唯一方式是刷新整個緩沖.這是因為我們沒法判斷哪些是屬於你的應用的引用.所以刪除被緩沖的introspection會導致把這台電腦上的所有應用的introspection都刪掉.需要注意的是,spring 托管的bean不需要使用這個監聽器.因為spring它自己的introspection所使用的緩沖在分析完一個類之后會被馬上從javaBeans Introspector緩沖中清除掉.應用程序中的類從來不直接使用JavaBeans Introspector.所以他們一般不會導致內部查看資源泄露.但是一些類庫和框架往往會產生這個問題.例如:Struts 和Quartz.單個的內部查看泄漏會導致整個的web應用的類加載器不能進行垃圾回收.在web應用關閉之后,你會看到此應用的所有靜態類資源(例如單例).這個錯誤當然不是由這個類自 身引起的.
用法很簡單,就是在web.xml中加入:
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>

=======================================================

Quartz問題:

引用Robbin原話:

對於Web容器來說,最忌諱應用程序私自啟動線程,自行進行線程調度,像Quartz這種在web容器內部默認就自己啟動了10線程進行異步job調度的框架本身就是很危險的事情,很容易造成servlet線程資源回收不掉。quartz還有一個問題就是不支持cluster。導致使用quartz的應用都沒有辦法做群集。

采取的辦法就是自己單獨啟動一個Job Server,來跑job,不會部署在web容器中。其他web節點當需要啟動異步任務的時候,可以通過種種方式(DB, JMS, Web Service, etc)通知Job Server,而Job Server收到這個通知之后,把異步任務加載到自己的任務隊列中去。
其實想改造當前已經集成quartz的web應用也不算困難:
例如可以使用數據庫的表來記錄和維護任務隊列和狀態,把quartz部分完全從web應用中剝離出去,自己寫一個Java Main程序把配置quartz的spring容器跑起來,這樣Job Server就啟動了(注意這個Job Server完全脫離tomcat)。此外這個Main程序應該再啟動一個子線程,定期掃描數據庫的任務隊列表:
有新的任務就加入quartz的任務調度;
把當前任務的執行狀態寫入任務表;
看到刪除任務的表字段狀態以后,刪除相應的任務。
然后web應用去掉quartz部分配置,把原來的調用quartz任務的代碼改寫為讀寫數據庫的任務表,這樣就把job部分完全從web容器剝離掉了,甚至web容器做cluster也沒有問題了,並且多個web節點在同時讀寫任務表的時候,還有數據庫的事務來確保操作的一致性,實在是很棒。
另外還可以單獨做一個job管理界面,可以通過web界面手工添加任務,查看任務狀態,刪除任務等等。
-->
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>

 


免責聲明!

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



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