目錄
一、SpringMVC的運行流程圖
二、Spring整合SpringMVC
Spring整合SpringMVC的原因
通常情況下,類似於數據源、事務、整合其他框架都是放在Spring的配置文件中,而不是放在SpringMVC的配置文件中。實際上放入Spring配置文件對應的IOC容器中的還有Service和Dao等。
Spring整合SpringMVC中出現的問題
我們現在創建兩個類,一個讓SpringMVC初始化,另一個用Spring初始化。
package com.cerr.springmvc;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloWorld {
@Autowired
private UserService userService;
public HelloWorld() {
System.out.println("HelloWorld");
}
@RequestMapping(value = "/helloWorld")
public String hello(){
System.out.println("success");
return "success";
}
}
package com.cerr.springmvc;
import org.springframework.stereotype.Service;
@Service
public class UserService {
public UserService() {
System.out.println("UserService");
}
}
SpringMVC的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置自動掃描的包-->
<context:component-scan base-package="com.cerr.springmvc"/>
<!-- 配置視圖解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
Spring的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置自動掃描的包 -->
<context:component-scan base-package="com.cerr.springmvc"/>
<!-- 配置數據源,整合其他框架,事務等 -->
</beans>
然後開啓Tomcat後發現,這兩個類會被初始化兩次。因爲Spring的IOC容器掃描的包和SpringMVC的IOC容器掃描的包有融合的部分,這就會導致有的bean會被創建2次。
那麼如何解決呢?有兩種解決方案
- 使Spring的IOC容器和SpringMVC的IOC容器掃描的包沒有重合部分,即合理規劃好包,使其的包明顯分開,然後就可以設置了
- 可以在自動掃描包的節點中使用
exclude-filter
和include-filter
子節點來規定只能掃描的註解。
下面我們來說明第二種解決方案:
例如在這個例子中,對於SpringMVC,我們只讓掃描Controller
和ControllerAdvice
註解的類。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置自動掃描的包-->
<context:component-scan base-package="com.cerr.springmvc" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice" />
</context:component-scan>
<!-- 配置視圖解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
對於Spring配置文件,我們讓它不掃描Controller
和ControllerAdvice
註解的類。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置自動掃描的包 -->
<context:component-scan base-package="com.cerr.springmvc" >
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
<context:exclude-filter type="annotation"
expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>
<!-- 配置數據源,整合其他框架,事務等 -->
</beans>
這樣即可解決該問題。
Spring的IOC容器與SpringMVC的IOC容器的關係
多個Spring IOC容器之間可以設置爲父子關係,以實現良好的解耦,SpringMVC WEB層容器可作爲“業務層”Spring容器的子容器。即SpringMVC的IOC容器中的bean可以引用Spring IOC容器中的bean,但是Spring IOC容器中的bean卻不能引用SpringMVC IOC容器的bean。