背景:

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

  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

  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

  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容器啥也不加载

  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

  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

  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。缺点是不利于扩展。

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

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

    开始学习springmvc各种小白问题 根据例子配置了spring扫描包,但是一直提示404错误,经过大量搜索,发现,扫描包的配置应该写在springmvc的配置文件中,而不是springmvc 配置 ...

  2. Spring和Spring MVC包扫描

    在Spring整体框架的核心概念中,容器是核心思想,就是用来管理Bean的整个生命周期的,而在一个项目中,容器不一定只有一个,Spring中可以包括多个容器,而且容器有上下层关系,目前最常见的一种场景 ...

  3. spring和springmvc包扫描问题

    写这篇博客之前,橘子松必须感慨下!!找了我一下午加一晚上(md),问了几个朋友也没找到.凉了啊 在搭建ssm之前,我把controller service mapper包扫描用基本包扫描   都写在a ...

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

    <!-- 排除Controller注解的扫描 --> <context:component-scan base-package="exampleBean"> ...

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

    在上篇文章Spring IoC 源码分析 (基于注解) 一我们分析到,我们通过AnnotationConfigApplicationContext类传入一个包路径启动Spring之后,会首先初始化包扫 ...

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

    合Spring时Service层为什么不做全局包扫描详解 一.Spring和SpringMVC的父子容器关系 1.讲问题之前要先明白一个关系 一般来说,我们在整合Spring和SpringMVC这两个 ...

  7. 不会吧,有人用了两年Spring, 居然不知道包扫描是怎么实现的

    全栈的自我修养: 0004 Java 包扫描实现和应用(File篇) I may not be able to change the past, but I can learn from it. 我也 ...

  8. Spring源码分析-从@ComponentScan注解配置包扫描路径到IoC容器中的BeanDefinition,经历了什么(一)?

    阅前提醒 全文较长,建议沉下心来慢慢阅读,最好是打开Idea,点开Spring源码,跟着下文一步一步阅读,更加便于理解.由于笔者水平优先,编写时间仓促,文中难免会出现一些错误或者不准确的地方,恳请各位 ...

  9. spring盒springMVC整合父子容器问题:整合Spring时Service层为什么不做全局包扫描详解

    整合Spring时Service层为什么不做全局包扫描详解 一.Spring和SpringMVC的父子容器关系 1.讲问题之前要先明白一个关系 一般来说,我们在整合Spring和SpringMVC这两 ...

随机推荐

  1. linux环境启动django项目

    BBS部署步骤 安装python3.6(如已安装无需重复) install python3.6 把BBS项目传上来 rz 选择文件 BBS.tar 解压文件 tar -xvf BBS.tar 安装my ...

  2. 没事写写css

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx. ...

  3. Java Calendar 类的时间操作.RP

    JavaCalendar 类时间操作,这也许是创建和管理日历最简单的一个方案,示范代码很简单. 演示了获取时间,日期时间的累加和累减,以及比较. 原文地址:blog.csdn.NET/joyous/a ...

  4. C++面试笔记--宏定义

    宏定义是一个比较常考的考点,所以我归纳总结了一下近年的宏定义的题目 //宏定义面试题1.cpp//What is the output of the following code?[中国台湾某著名杀毒 ...

  5. JQuery UI Draggable插件使用说明文档

    JQuery UI Draggable插件用来使选中的元素可以通过鼠标拖动.Draggable的元素受css: ui-draggable影响, 拖动过程中的css: ui-draggable-drag ...

  6. 【转】【Android】ProgressDialog进度条对话框的使用

    Android ProgressDialog进度条对话框的使用: 转自:http://aina-hk55hk.iteye.com/blog/679134/ <?xml version=" ...

  7. AISing Programming Contest 2019C(DFS,BFS)

    #include<bits/stdc++.h>using namespace std;int n,m;long long a=0,b=0,ans=0;char s[407][407];in ...

  8. 在Python中正确使用Unicode

    正确处理文本,特别是正确处理Unicode.是个老生常谈的问题,有时甚至会难倒经验丰富的开发者.并不是因为这个问题很难,而是因为对软件中的文本,开发者没有正确理解一些关键概念及其表示方法.在Stack ...

  9. 老男孩Day2作业:购物车程序

    作业需求: 用户入口: 1.商品信息存在文件里 2.已购商品,余额记录.第一次启动程序时需要记录工资,第二次启动程序时谈出上次余额 3.允许用户根据商品编号购买商品 4.用户选择商品后,检测是否够,够 ...

  10. 各种Helper代码

    1.读取XML文件 /// <summary> /// 读取XML配置文件类 /// </summary> public class XmlHelper { private s ...