为啥Spring和Spring MVC包扫描要分开?

背景:

      最近在搭建新工程的时候发现有些Spring的配置不是很了解,比如Spring 配置里面明明配置了component-scan,为啥Spring MVC配置文件还需要配置一下,这样岂不是多此一举?由于以前基本是在现有的工程上直接开发或者别的工程的配置文件直接拷贝过来,所以也没太关注这个问题。出于好奇,谷歌了一下发现原来这个里面大有学问呢,详情请见下文。正常代码如下:

Xml代码  

  1. <!-- spring 配置文件-->
  2. <context:component-scan base-package="com.xxx.xxx.account.front">
  3. <context:exclude-filter type="annotation"
  4. expression="org.springframework.stereotype.Controller" />
  5. </context:component-scan>
  6. <!-- spring mvc -->
  7. <context:component-scan base-package="com.xxx.xxx.account.front.web" use-default-filters="false">
  8. <context:include-filter type="annotation"
  9. expression="org.springframework.stereotype.Controller" />
  10. </context:component-scan>

测试bean

Java代码  

  1. @Service
  2. public class TestService implements InitializingBean {
  3. @Autowired
  4. private PersonalAddressAjaxController personalAddressAjaxController;
  5. @Override
  6. public void afterPropertiesSet() throws Exception {
  7. System.out.println("--------------------------------");
  8. }
  9. }

原理:   

      原来Spring 是父容器, Spring MVC是子容器, 子容器可以访问父容器的bean,父容器不能访问子容器的bean。

具体参照:

Spring和SpringMVC父子容器关系初窥

Spring为什么不做全局包扫描

Spring与SpringMVC的容器关系分析

测试一: Spring加载全部bean,MVC加载Controller

Xml代码  

  1. <!-- spring 配置文件-->
  2. <context:component-scan base-package="com.xxx.xxx.account.front">
  3. </context:component-scan>
  4. <!-- spring mvc -->
  5. <context:component-scan base-package="com.xxx.xxx.account.front.web" use-default-filters="false">
  6. <context:include-filter type="annotation"
  7. expression="org.springframework.stereotype.Controller" />
  8. </context:component-scan>

    

    测试结果:TestService通过,界面显示正常。

原因:父容器加载了全部bean,所以Service 能访问到Controller。MVC容器默认查找当前容器,能查到有转发的Controller规则所以界面正常跳转。

测试二:Spring加载全部Bean,MVC容器啥也不加载

Xml代码  

  1. <!-- spring 配置文件-->
  2. <context:component-scan base-package="com.xxx.xxx.account.front">
  3. </context:component-scan>
  4. <!-- spring mvc -->

测试结果:TestService通过,界面显示404。

原因:父容器加载了全部bean,所以Service 能访问到Controller。MVC容器默认查找当前容器的Controller,找不到所以界面出现404。

测试三:Spring加载所有除了Controller的bean,MVC只加载Controller

Xml代码  

  1. <!-- spring 配置文件-->
  2. <context:component-scan base-package="com.xxx.xxx.account.front">
  3. <context:exclude-filter type="annotation"
  4. expression="org.springframework.stereotype.Controller" />
  5. </context:component-scan>
  6. <!-- spring mvc -->
  7. <context:component-scan base-package="com.xxx.xxx.account.front.web" use-default-filters="false">
  8. <context:include-filter type="annotation"
  9. expression="org.springframework.stereotype.Controller" />
  10. </context:component-scan>

测试结果:TestService初始化失败,如果注释掉该bean,界面正常。

原因:父容器不能访问子容器的bean。

测试四:Spring不加载bean,MVC加载所有的bean

Xml代码  

  1. <!-- spring 配置文件-->
  2. <!-- spring mvc -->
  3. <context:component-scan base-package="com.xxx.xxx.account.front.web" use-default-filters="true">
  4. </context:component-scan>

    测试结果:TestService通过,界面正常。

原因:因为所有的bean都在子容器中,也能查到当前容器中的Controller,所以没啥问题。

疑问一: 单例的bean在父子容器中存在一个实例还是两个实例?

    答:初始化两次,Spring 容器先初始化bean,MVC容器再初始化bean,所以应该是两个bean。

疑问二:为啥不把所有bean 都在子容器中扫描?

答: 网上很多文章说子容器不支持AOP,其实这是不对的。因为正常会有AOP的相关配置都在Spring容器中配置,如果都迁移到MVC配置文件,则所有bean都在子容器中,相当于只有一个容器了,所以也就实现了AOP。缺点是不利于扩展。

原文地址:https://www.cnblogs.com/moxiaotao/p/9246668.html

时间: 2024-08-01 00:22:13

为啥Spring和Spring MVC包扫描要分开?的相关文章

为啥Spring和Spring MVC包扫描要分开

开始学习springmvc各种小白问题 根据例子配置了spring扫描包,但是一直提示404错误,经过大量搜索,发现,扫描包的配置应该写在springmvc的配置文件中,而不是springmvc 配置成功的applicationContext 即 spring配置 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/sche

spring包扫描问题

最近做项目时发现一个spring包扫描问题,项目中使用spring.springMVC.mybatis框架,因为整个项目是按模块来分布式开发,最终将各个模块整合在一起,但是整合时发现有些模块的service层和controller层包没有扫描到. 举个例子:A模块的service层包为 com.project.A.service,B模块的service层的包为com.project.base.B.service:在spring的配置文件里包扫描器的配置为: <context:component-

整合Spring时Service层为什么不做全局包扫描详解

转载:http://blog.csdn.net/s740556472/article/details/54879954 一.Spring和SpringMVC的父子容器关系 1.讲问题之前要先明白一个关系 一般来说,我们在整合Spring和SpringMVC这两个框架中,web.xml会这样写到: <!-- 加载spring容器 --> <!-- 初始化加载application.xml的各种配置文件 --> <context-param> <param-name&

Spring整合MyBatis (使用扫描包配置mapper代理)

Spring整合MyBatis (使用扫描包配置mapper代理) pojo是根据表生成的实体类,属性名要跟字段名相同,不相同sql语句查询时用别名. 首先导jar包 实体类 public class User { private Integer id; private String username;// 用户姓名 private String sex;// 性别 private Date birthday;// 生日 private String address;// 地址 } 1 2 3

spring 排除指定的类或者包扫描

<!-- 排除Controller注解的扫描 --> <context:component-scan base-package="exampleBean"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan&

Spring IoC 源码分析 (基于注解) 之 包扫描

在上篇文章Spring IoC 源码分析 (基于注解) 一我们分析到,我们通过AnnotationConfigApplicationContext类传入一个包路径启动Spring之后,会首先初始化包扫描的过滤规则.那我们今天就来看下包扫描的具体过程. 还是先看下面的代码: AnnotationConfigApplicationContext类 //该构造函数会自动扫描以给定的包及其子包下的所有类,并自动识别所有的Spring Bean,将其注册到容器中 public AnnotationConf

Spring、Spring MVC、MyBatis

Spring.Spring MVC.MyBatis整合文件配置详解 使用SSM框架做了几个小项目了,感觉还不错是时候总结一下了.先总结一下SSM整合的文件配置.其实具体的用法最好还是看官方文档. Spring:http://spring.io/docs MyBatis:http://mybatis.github.io/mybatis-3/ 基本的组织结构和用法就不说了,前面的博客和官方文档上都非常的全面.jar包可以使用Maven来组织管理.来看配置文件. web.xml的配置         

IDEA下创建Maven项目,并整合使用Spring、Spring MVC、Mybatis框架

项目创建 本项目使用的是IDEA 2016创建.项目使用Spring 4.2.6,Mybatis3.4.0,Tomcat使用的是Tomcat8,数据库为MySQL. 首先电脑安装Maven,接着打开IDEA新建一个project,选择Maven,选择图中所选项,下一步. 填写好GroupId和ArtifactId,GroupId在公司中一般都是域名的逆序,ArtifactId用来标明该项目是用来做什么的,接着下一步. 添加一个archetypeCatalog,值为internal可以加速项目的创

spring、spring mvc、mybatis框架整合基本知识

学习了一个多月的框架知识了,这两天很想将它整合一下.网上看了很多整合案例,基本都是基于Eclipse的,但现在外面公司基本都在用Intellij IDEA了,所以结合所学知识,自己做了个总结,有不足之处欢迎指正. 首先,我是参考了http://blog.csdn.net/zhshulin/article/details/37956105这篇做的Intellij IDEA翻版.Intellij IDEA的许多操作方式与习惯与eclipse区别很大,所以很容易走入误区.直接上操作吧. 1.基本概念