Spring MVC框架:第十五章:多IOC容器整合

多IOC容器整合
SSM整合方式
Spring、SpringMVC、MyBatis

SpringMVC的核心Servlet會(huì)啟動(dòng)一個(gè)IOC容器,而ContextLoaderListener也會(huì)啟動(dòng)一個(gè)IOC容器。

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    
    <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:spring-mvc.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>
    
    <!-- 在Servlet的上下文參數(shù)中指定Spring配置文件的配置 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-tx.xml</param-value>
    </context-param>
    
    <listener>
        <!-- 配置ContextLoaderListener監(jiān)聽(tīng)器,初始化WebApplicationContext這個(gè)類(lèi)型的IOC容器 -->
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
</web-app>

對(duì)象重復(fù)創(chuàng)建為問(wèn)題
兩個(gè)IOC容器分別掃描不同的包時(shí)不會(huì)有重復(fù)創(chuàng)建對(duì)象問(wèn)題[推薦]
SpringMVC掃描:com.ioc.component.handler
Spring掃描:
com.ioc.component.service
com.ioc.component.dao
特定情況下兩個(gè)IOC容器都掃描同一個(gè)包
com.ioc.component
不做特殊處理會(huì)存在對(duì)象重復(fù)創(chuàng)建問(wèn)題

在實(shí)際開(kāi)發(fā)中我們通常還是需要將二者分開(kāi)。
1.同時(shí)配置兩個(gè)IOC容器

為了實(shí)現(xiàn)更好的解耦,我們?cè)趯?shí)際開(kāi)發(fā)中往往還是需要將數(shù)據(jù)源、Service、Dao等組件配置到傳統(tǒng)的Spring配置文件中,并通過(guò)ContextLoaderListener啟動(dòng)這個(gè)IOC容器。 而在表述層負(fù)責(zé)處理請(qǐng)求的handler組件則使用SpringMVC自己來(lái)啟動(dòng)。 這會(huì)導(dǎo)致一個(gè)問(wèn)題:同樣的組件會(huì)被創(chuàng)建兩次。
2.兩個(gè)IOC容器的各自配置

Spring的IOC容器 將標(biāo)記了@Controller注解的bean排除
Spring配置文件:spring-tx.xml

<context:component-scan base-package="com.ioc.component.*">
    <!-- 將@Controller注解標(biāo)記的類(lèi)從自動(dòng)掃描的包中排除 -->
    <!-- 效果:當(dāng)前IOC容器不會(huì)創(chuàng)建@Controller注解標(biāo)記的類(lèi)的bean -->
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

  

僅包含標(biāo)記了@Controller等注解的bean
SpringMVC配置文件:spring-mvc.xml

<!-- 關(guān)鍵:僅 -->
<!-- 配置use-default-filters="false"將默認(rèn)的掃描包規(guī)則取消,參考include-filter僅創(chuàng)建@Controller注解標(biāo)記的類(lèi)的bean -->
<context:component-scan base-package="com.ioc.component.*" use-default-filters="false">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

 

這兩個(gè)IOC容器中,先啟動(dòng)的那個(gè)將成為后啟動(dòng)的IOC容器的父容器。
小結(jié):
DispatcherServlet讀取spring-mvc.xml配置文件
ContextLoaderListener讀取spring-tx.xml配置文件
過(guò)濾規(guī)則
exclude-filter
include-filter

異常映射
SpringMVC配置文件

<!-- 配置異常映射關(guān)系 -->
<bean id="simpleMappingExceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            <!-- 將異常類(lèi)型和視圖名稱關(guān)聯(lián)起來(lái) -->
            <!-- 這個(gè)機(jī)制工作后會(huì)自動(dòng)將捕獲到的異常對(duì)象存入請(qǐng)求域,默認(rèn)屬性名是exception -->
            <prop key="java.lang.RuntimeException">error</prop>
        </props>
    </property>
    
    <!-- 指定將異常對(duì)象存入請(qǐng)求域時(shí)使用的屬性名 -->
    <property name="exceptionAttribute" value="exception"></property>
</bean>

   

頁(yè)面上:
exception:${requestScope.exception}