問:實際上SpringMVC就運行在Spring環境之下,還有必要整合麼?SpringMVC和Spring都有IOC容器,是否是都須要保留呢?java
答案是:一般狀況下,相似於數據源,事務,整合其餘框架都是放在spring的配置文件中(而不是放在SpringMVC的配置文件中),實際上放入Spring配置文件對應的IOC容器中的還有Service和Dao.而SpringMVC也搞本身的一個IOC容器,在SpringMVC的容器中只配置本身的Handler(Controller)信息。因此,二者的整合是十分有必要的,SpringMVC負責接受頁面發送來的請求,Spring框架則負責整理中間需求邏輯,對數據庫發送操做請求,對數據庫的操做目前則先使用Spring框架中的JdbcTemplate進行處理。mysql
c3p0-0.9.1.2.jarweb
com.springsource.net.sf.cglib-2.2.0.jarspring
com.springsource.org.aopalliance-1.0.0.jarsql
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar數據庫
commons-logging-1.1.3.jarexpress
mysql-connector-java-5.1.37-bin.jarmvc
spring-aop-4.0.0.RELEASE.jarapp
spring-aspects-4.0.0.RELEASE.jar框架
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
spring-jdbc-4.0.0.RELEASE.jar
spring-orm-4.0.0.RELEASE.jar
spring-tx-4.0.0.RELEASE.jar
spring-web-4.0.0.RELEASE.jar
spring-webmvc-4.0.0.RELEASE.jar
<!-- ContextLoaderListener 加載IOC容器,Spring框架的底層是listener --> <context-param> <param-name>contextConfigLocation</param-name> <!-- 指定Spring的配置文件的路徑和名稱 --> <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> <!-- SpringMVC 配置文件 SpringMVC底層是servlet --> <servlet> <servlet-name>springDispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <!-- 指定SpringMVC框架的配置文件的路徑和名稱 --> <param-value>classpath:SpringMVC.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <!-- Map all requests to the DispatcherServlet for handling --> <servlet-mapping> <servlet-name>springDispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 設置編碼,處理post請求亂碼 --> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- post請求轉化爲put和delete --> <filter> <filter-name>HiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>HiddenHttpMethodFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
<!-- 配置掃描的包 --> <context:component-scan base-package="com.neuedu"></context:component-scan> <!-- 加載properties文件中 信息 --> <context:property-placeholder location="classpath:jdbc.properties"/> <!-- 配置數據源 --> <bean id="comboPooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="user" value="${jdbc.user}"></property> <property name="password" value="${jdbc.passowrd}"></property> <property name="jdbcUrl" value="${jdbc.url}"></property> <property name="driverClass" value="${jdbc.driver}"></property> </bean> <!-- 配置JdbcTemplate對應的bean, 並裝配dataSource數據源屬性--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="comboPooledDataSource"></property> </bean> <!-- 爲了執行帶有具名參數的SQL語句,須要配置NamedParameterJdbcTemplate --> <!-- 該NamedParameterJdbcTemplate類沒有無參構造器,須要傳入JdbcTemplate對象或者數據源對象[DataSource] --> <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate"> <!-- 不能使用property標籤配置哦 --> <constructor-arg ref="jdbcTemplate"></constructor-arg> </bean>
<!-- 配置掃描的包 --> <context:component-scan base-package="com.neuedu"></context:component-scan> <!-- 配置視圖解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"></property> <property name="suffix" value=".jsp"></property> </bean> <!-- 能夠處理靜態資源 --> <mvc:default-servlet-handler/> <!-- 能夠從一個頁面直接經過請求到達另外一個頁面,不用經過controller --> <!-- <mvc:view-controller path="/" view-name="/" /> --> <!-- 若只有mvc:default沒有mvc:annotation-driven,正常的requestMapping不能被訪問,因此它倆是標配 --> <mvc:annotation-driven></mvc:annotation-driven>
jdbc.user=root
jdbc.passowrd=123456
jdbc.url=jdbc:mysql://localhost:3306/jdbc_template
jdbc.driver=com.mysql.jdbc.Driver
問題:若Spring的IOC容器和SpringMVC的IOC容器掃描的包有重合的部分,就會致使有的bean會被建立2次!
解決:
1.使Spring的IOC容器掃描的包和SpringMVC的IOC容器掃描的包沒有重合的部分!
controller層都在controller包,service層都在service包
2.可是有的時候開發的時候是分模塊開發的,這樣不太容易作到,因此:
能夠在component-scan標籤下面中使用以下子標籤來規定只能掃描的註解:
<context:component-scan base-package="com.neuedu"> <context:exclude-filter type="annotation" expression=""/> <context:include-filter type="annotation" expression=""/> </context:component-scan>
因此在springMVC的配置文件中咱們能夠按着以下配置,只掃描controller及ControllerAdvice註解:
<context:component-scan base-package="com.neuedu" use-default-filters="false"> <!-- 掃描註解爲@Controller的類 --> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> <!-- ControllerAdvice註解用來處理全局異常,能夠標記在類上,故此處爲掃描註解爲@ControllerAdvice的類 --> <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/> </context:component-scan>
而在spring的配置文件中:
<context:component-scan base-package="com.neuedu"> <!-- 掃描除了註解爲@Controller的類 --> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> <!-- 掃描除了註解爲@ControllerAdvice的類 --> <context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/> </context:component-scan>
此時再從新啓動項目就會發現spring和springmvc的對象都建立了一份!
外邊beans.xml爲Spring的配置文件,黃色方格Spring-mvc.xml爲SpringMVC的配置文件
1.SpringMVC容器中的bean能夠引用Spring容器中的bean,也就是在Controller中咱們能夠注入service層對象【能夠在controller層的requestMapping方法中打印service對象試一下】!
2.反之則不行,就是說:在spring掃描的service層不能引用springmvc的handler(Controller)對象【註解一個小例子,啓動項目就會出錯】
3.實際上Spring的容器和Spring容器有父子間關係,【參考圖片】就像兒子能夠繼承父親的基因同樣,父親無法繼承兒子的基因!
並且從另外一個角度也說明了Handler(Controller)是能夠依賴Service層的,可是Service層卻不能夠依賴Handler(Controller)層!