SpringMVC 运行在 Spring 环境下,需要整合的原因:
Spring 和 SpringMVC 都有 IOC 容器,当扫描的包有重复时,就会导致有的 bean 被创建两次。
Spring 和 SpringMVC 处理的事情不同,应当将各自配置分开,方便管理。
通常情况下,类似于数据源,事务,整合其他框架都是放在 Spring 的配置文件中以及 Service 和 Dao;而在 SpringMVC 的容器中只配置自己的 Handler(Controller) 信息。
所以,两者的整合是十分有必要的,SpringMVC 负责接受页面发送来的请求,Spring 框架则负责整理中间需求逻辑,对数据库发送操作请求等。
解决 bean 被创建多次办法:
由上面可知, SpringMVC 主要负责管理属于自己的 @Controller 和 @ControllerAdvice 两个注解,而其他的注解都属于 Spring 的 IOC 容器管理。那么在 spring.xml 中扫描包时,排除 @Controller 和 @ControllerAdvice 两个注解的类,而在 springmvc.xml 中只扫描 @Controller 和 @ControllerAdvice 两个注解的类。
spring.xml:
<context:component-scan base-package="cn.edu.pzhu.cg.service">
<!-- 扫描除了 @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>
springmvc.xml:
先将 use-default-filters 属性设为 false。
<context:component-scan base-package="cn.edu.pzhu.cg.service" use-default-filters="false">
<!-- 只扫描 @Controller 注解标记的类 -->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<!-- 只扫描 @ControllerAdvice 注解标记的类 -->
<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>
经过以上配置就可以把 SpringMVC 和 Spring 隔离开来,各自负责各自的业务。
Spring IOC 容器和 SpringMVC IOC 容器的关系:
由上图可知:
SpringMVC 容器中的 bean 可以引用 Spring 容器中的 bean,反之在 SpringMVC 中的 Handler 不能应用 Spring 的 Service.
实际上Spring的容器和Spring容器有父子间关系;就像儿子可以继承父亲的基因一样,父亲没法继承儿子的基因!
这也说明了 Handler(Controller)是可以依赖 Service 层的,但是 Service 层却不可以依赖 Handler(Controller)层!