1. 程式人生 > 其它 >十二、springMVC整合spring

十二、springMVC整合spring

一、概述: 

需要進行spring 整合 springmvc 嗎?或者說還是否需要加入Spring 的IOC容器? 是否需要在web.xml檔案中配置啟動啟動Spring IOC容器的ContextLoaderListener?

  • 需要整合:通常情況下,類似於資料來源 事務 整合其他框架都是放在spring的配置檔案中,而不是放在Springmvc的配置檔案中 實際放入Spring配置檔案對應的IOC容器中的還有Service 和Dao;
  • 不需要整合:都放在Springmvc 的配置檔案中,也可以分多個Spring的配置檔案,然後使用import節點匯入其他配置檔案;

整合spring、springMVC中的問題:

若spring的IOC 容器和springMVC的IOC容器掃描的包有重合的部分,就會導致bean會被建立兩次。即tomcat啟動時,構造器分別被建立了2次;

例項驗證:

目錄結構如下圖

配置:

web.xml只配置了DispatcherServlet+配置啟動spring ioc容器的Listener ,Listener 配置如下:

1 <context-param>
2         <param-name>contextConfigLocation</param-name>
3         <param-value>classpath:beans.xml</
param-value> 4 </context-param> 5 <listener> 6 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 7 </listener>
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xmlns="http://xmlns.jcp.org/xml/ns/javaee" 4 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 5 id="WebApp_ID" version="3.1"> 6 <context-param> 7 <param-name>contextConfigLocation</param-name> 8 <param-value>classpath:beans.xml</param-value> 9 </context-param> 10 <listener> 11 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 12 </listener> 13 <servlet> 14 <servlet-name>springDispatcherServlet</servlet-name> 15 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 16 <!-- 配置DispatcherServletd 一個初始化引數:配置springmvc配置檔案的位置和名稱 --> 17 <!-- 實際上也可以不通過 contextConfigLocation 來配置Springmvc的配置檔案,而是用預設的 即預設的配置檔案為 18 /WEB-INF/<servlet-name>-servlet.xml 本專案預設位置配置檔案即為: /WEB-INF/springDispatcherServlet-servlet.xml --> 19 <init-param> 20 <param-name>contextConfigLocation</param-name> 21 <param-value>classpath:spring.xml</param-value> 22 </init-param> 23 <!-- 表示springDispatcherServlet在載入的時候被建立 --> 24 <load-on-startup>1</load-on-startup> 25 </servlet> 26 27 <!-- Map all requests to the DispatcherServlet for handling --> 28 <servlet-mapping> 29 <servlet-name>springDispatcherServlet</servlet-name> 30 <url-pattern>/</url-pattern> 31 </servlet-mapping> 32 </web-app>
View Code

spring.xml基礎配置(包掃描的配置、檢視解析器配置、<mvc:annotation-driven></mvc:annotation-driven>)

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:mvc="http://www.springframework.org/schema/mvc"
 5     xmlns:context="http://www.springframework.org/schema/context"
 6     xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
 7         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 8         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
 9 
10     <!-- 配置需要掃描的包 -->
11     <context:component-scan base-package="springandspringmvc">
12     </context:component-scan>
13     <!-- 配置檢視解析器 如何把handler 方法返回值解析為實際的物理檢視 -->
14     <bean
15         class="org.springframework.web.servlet.view.InternalResourceViewResolver">
16         <property name="prefix" value="/WEB-INF/views/"></property>
17         <property name="suffix" value=".jsp"></property>
18     </bean>
19 
20     <mvc:annotation-driven></mvc:annotation-driven>    
21 </beans>
View Code

bean.xml

1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4     xmlns:context="http://www.springframework.org/schema/context"
5     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
6         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
7         
8         <context:component-scan base-package="springandspringmvc"></context:component-scan>
9 </beans>
View Code

mvc程式碼:

HelloController:

 1 package springandspringmvc;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.stereotype.Controller;
 5 import org.springframework.web.bind.annotation.RequestMapping;
 6 
 7 @Controller
 8 @RequestMapping("/helloworld")
 9 public class HelloController {
10     @Autowired
11     private HelloService helloService;
12 
13     @RequestMapping("list")
14     public String hello() {
15         helloService.hello();
16         System.out.println("success");
17         return "success";
18     }
19 
20     public HelloController() {
21         System.out.println("controller constructor");
22     }
23 
24 }
View Code

HelloService.java

1 package springandspringmvc;
2 
3 public interface HelloService {
4 
5     String hello();
6 
7 }
View Code

HelloServiceImpl.java

 1 package springandspringmvc;
 2 
 3 import org.springframework.stereotype.Service;
 4 
 5 @Service("helloService")
 6 public class HelloServiceImpl implements HelloService {
 7 
 8     @Override
 9     public String hello() {
10         System.out.println("hello HelloServiceImpl");
11         return null;
12     }
13 
14     public HelloServiceImpl() {
15         System.out.println("HelloServiceImpl constructor");
16         // TODO Auto-generated constructor stub
17     }
18 
19 }
View Code

success.jsp:

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <!DOCTYPE html>
 4 <html>
 5 <head>
 6 <meta charset="UTF-8">
 7 <title>Insert title here</title>
 8 </head>
 9 <body>
10 success
11 </body>
12 </html>
View Code

執行結果:

當專案啟動時,控制列印了兩遍:

controller constructor

HelloServiceImpl constructor

解決辦法:

  • 解決方法1:使spring的IOC 容器和springMVC的IOC容器掃描的包有重合的部分
  • 解決方法2:使用exclue-filter和include-filter 子節點來規定只能掃描的註解

採用exclue-filter和include-filter 子節點來規定只能掃描的註解;即spring.xml 掃描包該為只掃描Controller和service;bean.xml除了Controller和service不掃描,其他都掃描;

spring.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:mvc="http://www.springframework.org/schema/mvc"
 5     xmlns:context="http://www.springframework.org/schema/context"
 6     xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
 7         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 8         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
 9 
10     <!-- 配置需要掃描的包 -->
11     <context:component-scan base-package="restful"
12         use-default-filters="false">
13         <context:include-filter type="annotation"
14             expression="org.springframework.stereotype.Controller" />
15         <context:include-filter type="annotation"
16             expression="org.springframework.stereotype.Service" />
17     </context:component-scan>
18     <!-- 配置檢視解析器 如何把handler 方法返回值解析為實際的物理檢視 -->
19     <bean
20         class="org.springframework.web.servlet.view.InternalResourceViewResolver">
21         <property name="prefix" value="/WEB-INF/views/"></property>
22         <property name="suffix" value=".jsp"></property>
23     </bean>
24 
25     <mvc:annotation-driven></mvc:annotation-driven>
26 </beans>
View Code

bean.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:context="http://www.springframework.org/schema/context"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 6         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
 7 
 8     <context:component-scan
 9         base-package="restful.restful.springandspringmvc"
10         use-default-filters="false">
11         <context:exclude-filter type="annotation"
12             expression="org.springframework.stereotype.Controller" />
13         <context:exclude-filter type="annotation"
14             expression="org.springframework.stereotype.Service" />
15     </context:component-scan>
16 </beans>
View Code

 

此時:springMVC的IOC容器掃描的包就沒有重合的部分。且springmvc 的IOC容器中的bean可以引用spring ioc中的bean,而反過來不行,也就是說service不能通過@Autowired來獲取Controller;

即:spring ioc容器中的bean不能引用springMVC IOC容器中的bean。即完成了整合;若配置IOC,資料來源,就可以配置到bean.xml中了;

參考:

context:component-scan的一些說明的參考連結https://www.cnblogs.com/lixiuming521125/p/15401339.html#_label3_1