javascript
使用Spring MVC时的常见错误
當我大約10年前開始我的職業生涯時,Struts MVC就是市場上的常態。 但是,多年來,我觀察到Spring MVC逐漸流行起來。 鑒于Spring MVC與Spring容器的無縫集成以及它提供的靈活性和可擴展性,這對我來說并不奇怪。
從到目前為止的Spring旅程中,我通常會看到人們在配置Spring框架時犯了一些常見的錯誤。 與人們仍然使用Struts框架的時間相比,這種情況發生的頻率更高。 我想這是靈活性和可用性之間的權衡。 另外,Spring文檔中有很多示例,但缺乏解釋。 為了填補這一空白,本文將嘗試闡述和解釋我經常看到的3個常見問題。
在Servlet上下文定義文件中聲明bean
因此,我們每個人都知道Spring使用ContextLoaderListener加載Spring應用程序上下文。 不過,當宣布
DispatcherServlet ,我們需要創建名稱為“ $ {servlet.name} -context.xml”的servlet上下文定義文件。 有沒有想過為什么?
應用程序上下文層次結構
并非所有開發人員都知道Spring應用程序上下文具有層次結構。 讓我們看一下這種方法:
org.springframework.context.ApplicationContext.getParent()
它告訴我們Spring Application Context具有父級。 那么,這個父母干什么呢?
如果下載源代碼并進行快速引用搜索,則應該發現Spring Application Context將parent作為其擴展名。 如果您不介意閱讀代碼,請讓我向您展示方法BeanFactoryUtils.beansOfTypeIn includedAncestors()中的用法示例:
if (lbf instanceof HierarchicalBeanFactory) {HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {Map parentResult = beansOfTypeIncludingAncestors((ListableBeanFactory) hbf.getParentBeanFactory(), type);...} } return result; }如果遍歷整個方法,您將發現在搜索父上下文之前,Spring Application Context會掃描以在內部上下文中查找bean。 通過這種策略,Spring Application Context將有效地進行反向廣度優先搜索以查找bean。
ContextLoaderListener
這是每個開發人員都應該知道的眾所周知的類。 它有助于從預定義的上下文定義文件中加載Spring應用程序上下文。 由于實現了ServletContextListener ,因此將在加載Web應用程序后立即加載Spring應用程序上下文。 當加載包含帶有@PostContruct批注或批處理作業的bean的Spring容器時,這帶來了無可爭議的好處。
相反,在初始化servlet之前,不會構造servlet上下文定義文件中的任何bean定義。 何時初始化Servlet? 這是不確定的。 在最壞的情況下,您可能需要等到用戶對servlet映射URL進行第一次點擊才能加載spring上下文。
根據以上信息,您應該在哪里聲明所有珍貴的豆子? 我覺得這樣做的最佳位置是ContextLoaderListener加載的上下文定義文件,而沒有其他地方。 這里的竅門是將ApplicationContext作為servlet屬性存儲在鍵org.springframework.web.context.WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE下
稍后, DispatcherServlet將從ServletContext加載此上下文,并將其分配為父應用程序上下文。
由于這種行為,強烈建議創建一個空的servlet應用程序上下文定義文件,并在父上下文中定義您的bean。 這將有助于避免在加載Web應用程序時重復創建Bean,并確保立即執行批處理作業。
從理論上講,在servlet應用程序上下文定義文件中定義bean會使該bean唯一且僅對該servlet可見。 但是,在使用Spring的8年中,除了定義Web Service端點之外,我幾乎沒有發現此功能的任何用途。
在
這是一個小錯誤,但是如果您不注意它,它將引起您的注意。 Log4jConfigListener是我在-Dlog4j.configuration首選的解決方案,我們可以控制的log4j加載不改變服務器的引導過程。
顯然,這應該是在web.xml中聲明的第一個偵聽器。 否則,您浪費所有的時間來聲明正確的日志記錄配置。
由于對Bean的探索管理不善而復制了Bean
在Spring的早期,開發人員在xml文件上打字的時間比Java類花費的時間更多。 對于每個新bean,我們需要自己聲明和連接依賴項,這是干凈,整潔但非常痛苦的。 毫無疑問,Spring框架的更高版本向更高的可用性發展。 如今,開發人員可能只需要聲明事務管理器,數據源,屬性源,Web服務端點,其余的就可以進行組件掃描和自動裝配。
我喜歡這些新功能,但是這種強大的力量需要承擔巨大的責任。 否則,事情會很快變得混亂。 XML文件中的組件掃描和bean聲明是完全獨立的。 因此,如果對bean進行注釋以進行組件掃描并手動進行聲明,則在bean容器中完全可能具有相同類的相同bean。 幸運的是,這種錯誤應該只發生在初學者身上。
當我們需要將一些嵌入式組件集成到最終產品中時,情況變得更加復雜。 然后,我們確實需要一種策略來避免重復的bean聲明。
上圖顯示了我們日常生活中遇到的種種現實問題。 大多數情況下,系統是由多個組件組成的,通常,一個組件可為多個產品提供服務。 每個應用程序和組件都有自己的bean。 在這種情況下,最好的聲明方式是避免重復的bean聲明?
這是我建議的策略:
- 確保每個組件都必須以專用的軟件包名稱開頭。 當我們需要進行組件掃描時,它使我們的工作變得更輕松。
- 不要指示開發組件的團隊采用在組件本身中聲明Bean的方法(注釋與xml聲明)。 開發人員負責將組件打包到最終產品中,以確保沒有重復的bean聲明。
- 如果組件中包含上下文定義文件,請給它一個包,而不是放在classpath的根目錄中。 最好給它起一個特定的名字。 例如, src / main / resources / spring-core / spring-core-context.xml比src / main / resource / application-context.xml更好。 想象一下,如果在相同的程序包中打包幾個包含相同文件application-context.xml的組件,那該怎么辦!
- 如果您已經在一個上下文文件中聲明了Bean,則不要為組件掃描提供任何注釋( @ Component, @ Service或@Repository )。
- 將特定于環境的bean(例如data-source , property-source)拆分到一個單獨的文件中并重用。
- 不要在常規包裝上進行組件掃描。 例如,與掃描org.springframework包相比,如果我們掃描幾個子包(例如org.springframework.core , org.springframework.context , org.springframework.ui ,…), 則更易于管理。
結論
希望以上技巧對日常使用很有幫助。 如有任何疑問或任何其他想法,請發送反饋以提供幫助。
翻譯自: https://www.javacodegeeks.com/2014/07/common-mistakes-when-using-spring-mvc.html
總結
以上是生活随笔為你收集整理的使用Spring MVC时的常见错误的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 苹果手机总是耳机模式取消不了怎么办
- 下一篇: 如何从JSF获取JSON响应?