十二、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>
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>
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>
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 }
HelloService.java

1 package springandspringmvc; 2 3 public interface HelloService { 4 5 String hello(); 6 7 }
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 }
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>
运行结果:
当项目启动时,控制打印了两遍:
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="springandspringmvc" 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>
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="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>
此时: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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南