一、SpringMVC與Spring整合的目的
SpringMVC與Spring整合是爲了分工明確。
SpringMVC的配置文件
:配置和網站轉發邏輯、網站功能相關的。(視圖解析器、文件上傳解析器、支持ajax等)。Spring的配置文件
:配置業務相關。(事務控制、數據源等)。
可以通過在SpringMVC的配置文件中加入<import resource="spring.xml"/>
來直接完成文件配置,但是更推薦使用SpringMVC和Spring分容器來做。
二、SpringMVC和Spring分容器整合
第一步:配置監聽器
要將SpringMVC與Spring整合,除了在web.xml文件配置springDispatcherServlet前端控制器
(指定springmvc文件位置),還需要配置ContextLoaderListener監聽器
(指定spring.xml文件位置)。
springDispatcherServlet前端控制器
- 指定springmvc.xml的位置
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
ContextLoaderListener監聽器
- 指定spring.xml的位置
<!-- needed for ContextLoaderListener -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param>
<!-- Bootstraps the root web application context before servlet initialization -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
此時運行項目,可以看到加載了兩個容器:
但僅僅這樣還是不夠的,現在只是將兩個容器加載進來,此時無論Controller還是Server都在兩個容器中各自執行了一遍。
第二步:各自掃描
使Spring管理業務邏輯組件;使SpringMVC管理控制器。
springmvc只掃描Controller
- 如果有統一異常管理,還要掃描
@ControllerAdvice
<context:component-scan base-package="com.gql" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
spring中掃描Controller之外的
- 如果有統一異常管理,還要屏蔽
@ControllerAdvice
<context:component-scan base-package="com.gql">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
三、父子容器問題
spring掃描所有業務邏輯組件(除了Controller),springmvc掃描Controller。兩者整合後,spring中的默認行爲是:
- 兩個容器同時存在情況下,spring容器作爲父容器,springmvc容器作爲子容器。
這樣的話,子容器中的Controller要裝配父容器中的Service,是可以的;但是如果父容器要裝配子容器就炸了。