2012-08-27 51 views
0

對於Spring/MVC,我經常努力確定我應該定義bean的上下文,可以是root-context.xmlservlet-context.xml。造成混淆的原因是我沒有看到關於該在哪裏放置什麼的任何文檔,在春季示例代碼中,我經常會看到樣本之間不同環境中定義的相同內容。如何確定使用哪個彈簧環境?

正如我目前定義的東西,這是一個服務或根上下文中的組件,並保留網絡控制器,攔截器和任何唯一的真正關係到網站的servlet上下文經驗法則。

但是安全呢?我目前已將其定義爲包含根環境,但這是否正確?

我的理解是,web上下文實際上是應用程序根上下文的子上下文嗎?

爲什麼我們需要Web上下文分開?

幾年前我已經閱讀了3.0的spring文檔,但不記得任何具體的東西,我也讀過Spring in Action,Third Edition。我會喜歡圍繞這個話題的任何材料。

回答

1

可以,通常是有區別的。

基本上你applicationContext.xml是你的根上下文,是你的服務和數據層bean所在的地方。

*-servlet.xmlwebmvc-config.xml是特殊的,因爲它們:

  • 有一個DispatcherServlet相關
  • 時總是WebApplicationContext bean工廠
  • 是根上下文的孩子(也可以是WebApplicationContext

但人們這樣做的最大原因是單元測試,解耦前端從後端,以及單獨的視圖解析器和/或多個調度器servlet。

這對單元測試很好,因爲您正在加載更少的bean來測試您的服務層。正如我在註釋中規定下面我通常加載我真正applicationContext.xml像:

@ContextConfiguration(locations = "classpath:/META-INF/spring/applicationContext.xml") 

而且因爲servlet上下文需要調度的servlet,你需要將其註冊爲喜歡的servlet:所以,當你

<servlet> 
    <servlet-name>my-web</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <init-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>/WEB-INF/spring/webmvc-config.xml</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
</servlet> 

也許能夠使用根環境加載我們的MVC控制器bean,除非調度器servlet控制該環境,否則它們並未真正註冊。雖然理論上我認爲DispatcherServlet可以加載類路徑中的配置,但注意contextConfigLocation值不在類路徑中。

還有些人需要多個調度程序servlet,因爲您通常只能擁有一個解析程序鏈(視圖,區域設置,主題等...)。

+0

有趣的是,我認爲你需要用'@ ContextConfiguration'爲spring創建一個測試環境?我想我可以在我的測試環境中包含通常是'applicationContext.xml'的東西?我通常只將「」放在我的上下文中,並與專用配置中的特定實現相關,這隻允許在測試環境中包含我需要的組件。所以你說這是歷史?這是否意味着我不再需要servlet上下文了?我是否還需要配置,但將其保留爲空?沒有這種背景有沒有好處? –

+0

是的我實際上使用我真正的'applicationContext.xml'進行單元測試,並依靠我的'PropertyPlaceholderConfigurer'將基於環境的正確變量(即,dev vs staging vs production)放入正確的變量中。 –

1

默認情況下它會檢查<servlet-name>.context.xml當你只是在web.xml中指定的DispatcherServlet。 如果指定了contextConfigLocation,那麼默認情況下檢查applicationContext.xml如果指定了param值,那麼它會檢查特定文件。

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 
<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>/WEB-INF/classes/applicationContext.xml</param-value> 
</context-param> 

你必須先指定以指定除<servlet-name>.context.xml然後它檢查的applicationContext其他文件的聽衆,如果你如果指定的contextConfigLocation然後它會檢查自定義配置文件中沒有指定任何東西。

+0

我想你錯誤地理解了我的問題。我知道web上下文的位置以及如何覆蓋配置文件。我所要求的是有關spring/mvc應用程序中存在的兩種不同上下文的信息。 –

+0

我不知道這一點,但要確定你的意思是兩個不同的文件或兩個不同的applicationContext?因爲它是一個非常重的對象,您不希望在應用程序中出現多個對象。或者我不確定如何擁有兩個應用程序上下文? –

+0

在您的示例中,您已經爲ContextLoaderListener定義了一個上下文配置,您還需要爲DispatcherServlet定義一個上下文配置。 ContextLoaderListener是根上下文,而DispatcherServlet是Web上下文。 –

1

爲什麼我們需要在網絡方面是分開的?

你不知道。事實上,有幾個正式的Spring例子會把所有的東西都混在一起。

還有,你可能要他們分開的幾個原因。也許最有效的是可維護性:源文件越小(配置文件是源文件),就越容易理解。另一個原因是,給定的後端可能會被多個前端使用。

就個人而言,我喜歡通過分離前端和後端,並簡單地導入情境的後端的,我使用組成應用程序上下文的想法。這留下了一個「servlet」上下文文件。