为啥Spring和Spring MVC包扫描要分开?
背景:
最近在搭建新工程的时候发现有些Spring的配置不是很了解,比如Spring 配置里面明明配置了component-scan,为啥Spring MVC配置文件还需要配置一下,这样岂不是多此一举?由于以前基本是在现有的工程上直接开发或者别的工程的配置文件直接拷贝过来,所以也没太关注这个问题。出于好奇,谷歌了一下发现原来这个里面大有学问呢,详情请见下文。正常代码如下:
- <!-- spring 配置文件-->
- <context:component-scan base-package="com.xxx.xxx.account.front">
- <context:exclude-filter type="annotation"
- expression="org.springframework.stereotype.Controller" />
- </context:component-scan>
- <!-- spring mvc -->
- <context:component-scan base-package="com.xxx.xxx.account.front.web" use-default-filters="false">
- <context:include-filter type="annotation"
- expression="org.springframework.stereotype.Controller" />
- </context:component-scan>
测试bean
- @Service
- public class TestService implements InitializingBean {
- @Autowired
- private PersonalAddressAjaxController personalAddressAjaxController;
- @Override
- public void afterPropertiesSet() throws Exception {
- System.out.println("--------------------------------");
- }
- }
原理:
原来Spring 是父容器, Spring MVC是子容器, 子容器可以访问父容器的bean,父容器不能访问子容器的bean。
具体参照:
测试一: Spring加载全部bean,MVC加载Controller
- <!-- spring 配置文件-->
- <context:component-scan base-package="com.xxx.xxx.account.front">
- </context:component-scan>
- <!-- spring mvc -->
- <context:component-scan base-package="com.xxx.xxx.account.front.web" use-default-filters="false">
- <context:include-filter type="annotation"
- expression="org.springframework.stereotype.Controller" />
- </context:component-scan>
测试结果:TestService通过,界面显示正常。
原因:父容器加载了全部bean,所以Service 能访问到Controller。MVC容器默认查找当前容器,能查到有转发的Controller规则所以界面正常跳转。
测试二:Spring加载全部Bean,MVC容器啥也不加载
- <!-- spring 配置文件-->
- <context:component-scan base-package="com.xxx.xxx.account.front">
- </context:component-scan>
- <!-- spring mvc -->
- 无
测试结果:TestService通过,界面显示404。
原因:父容器加载了全部bean,所以Service 能访问到Controller。MVC容器默认查找当前容器的Controller,找不到所以界面出现404。
测试三:Spring加载所有除了Controller的bean,MVC只加载Controller
- <!-- spring 配置文件-->
- <context:component-scan base-package="com.xxx.xxx.account.front">
- <context:exclude-filter type="annotation"
- expression="org.springframework.stereotype.Controller" />
- </context:component-scan>
- <!-- spring mvc -->
- <context:component-scan base-package="com.xxx.xxx.account.front.web" use-default-filters="false">
- <context:include-filter type="annotation"
- expression="org.springframework.stereotype.Controller" />
- </context:component-scan>
测试结果:TestService初始化失败,如果注释掉该bean,界面正常。
原因:父容器不能访问子容器的bean。
测试四:Spring不加载bean,MVC加载所有的bean
- <!-- spring 配置文件-->
- 无
- <!-- spring mvc -->
- <context:component-scan base-package="com.xxx.xxx.account.front.web" use-default-filters="true">
- </context:component-scan>
测试结果:TestService通过,界面正常。
原因:因为所有的bean都在子容器中,也能查到当前容器中的Controller,所以没啥问题。
疑问一: 单例的bean在父子容器中存在一个实例还是两个实例?
答:初始化两次,Spring 容器先初始化bean,MVC容器再初始化bean,所以应该是两个bean。
疑问二:为啥不把所有bean 都在子容器中扫描?
答: 网上很多文章说子容器不支持AOP,其实这是不对的。因为正常会有AOP的相关配置都在Spring容器中配置,如果都迁移到MVC配置文件,则所有bean都在子容器中,相当于只有一个容器了,所以也就实现了AOP。缺点是不利于扩展。
为啥Spring和Spring MVC包扫描要分开?的更多相关文章
- 为啥Spring和Spring MVC包扫描要分开
开始学习springmvc各种小白问题 根据例子配置了spring扫描包,但是一直提示404错误,经过大量搜索,发现,扫描包的配置应该写在springmvc的配置文件中,而不是springmvc 配置 ...
- Spring和Spring MVC包扫描
在Spring整体框架的核心概念中,容器是核心思想,就是用来管理Bean的整个生命周期的,而在一个项目中,容器不一定只有一个,Spring中可以包括多个容器,而且容器有上下层关系,目前最常见的一种场景 ...
- spring和springmvc包扫描问题
写这篇博客之前,橘子松必须感慨下!!找了我一下午加一晚上(md),问了几个朋友也没找到.凉了啊 在搭建ssm之前,我把controller service mapper包扫描用基本包扫描 都写在a ...
- spring 排除指定的类或者包扫描
<!-- 排除Controller注解的扫描 --> <context:component-scan base-package="exampleBean"> ...
- Spring IoC 源码分析 (基于注解) 之 包扫描
在上篇文章Spring IoC 源码分析 (基于注解) 一我们分析到,我们通过AnnotationConfigApplicationContext类传入一个包路径启动Spring之后,会首先初始化包扫 ...
- 整合Spring时Service层为什么不做全局包扫描详解
合Spring时Service层为什么不做全局包扫描详解 一.Spring和SpringMVC的父子容器关系 1.讲问题之前要先明白一个关系 一般来说,我们在整合Spring和SpringMVC这两个 ...
- 不会吧,有人用了两年Spring, 居然不知道包扫描是怎么实现的
全栈的自我修养: 0004 Java 包扫描实现和应用(File篇) I may not be able to change the past, but I can learn from it. 我也 ...
- Spring源码分析-从@ComponentScan注解配置包扫描路径到IoC容器中的BeanDefinition,经历了什么(一)?
阅前提醒 全文较长,建议沉下心来慢慢阅读,最好是打开Idea,点开Spring源码,跟着下文一步一步阅读,更加便于理解.由于笔者水平优先,编写时间仓促,文中难免会出现一些错误或者不准确的地方,恳请各位 ...
- spring盒springMVC整合父子容器问题:整合Spring时Service层为什么不做全局包扫描详解
整合Spring时Service层为什么不做全局包扫描详解 一.Spring和SpringMVC的父子容器关系 1.讲问题之前要先明白一个关系 一般来说,我们在整合Spring和SpringMVC这两 ...
随机推荐
- Android 中的菜单 OptionsMenu的简单应用
OptionsMenu就是安卓手机中的菜单选项 首先 要实现对菜单的操作就要先重写OnCreateOptionsMenu(Menu menu)方法 通常有两种方法来实现对菜单中选项的添加 第一种是动态 ...
- windows平台下用C#访问HBase
Hadoop中的HBase有多种数据访问方式,ubuntu里可以用hbase shell查看操作hbase数据库,但windows平台下需要用thrift对它进行访问. 例如hadoop安装在/usr ...
- Entity Framework Tutorial Basics(19):Change Tracking
Change Tracking in Entity Framework: Here, you will learn how entity framework tracks changes on ent ...
- Netty中的Future
先看下Future的整个继承体系,还有一个ChannelFuture不在里面: 在并发编程中,我们通常会用到一组非阻塞的模型:Promise,Future 和 Callback.其中的 Fut ...
- C# 中窗口AutoScaleMode属性
C# 窗体中有一个AutoScaleMode 这个属性,我们大家可能用的比较少. 它的作用是:当屏幕分辨率或字体发生改变时,窗体和控件是如何发生变化的.
- Java数据结构与算法分析-第一章(引论)-Java中的范型<T,E>构件
一.为什么需要使用范型? 官方的说法是:Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型. 泛型的本质 ...
- 多线程学习-基础(五)sleep()和yield()的区别(理论)
一.sleep()和yield()的区别 (1)sleep()使当前线程进入停滞状态(即阻塞状态),所以执行sleep()的线程在指定的时间内不会被执行: (2)yield()只是使当前线程从运行状态 ...
- [译]Javascipt中的Strings
本文翻译youtube上的up主kudvenkat的javascript tutorial播放单 源地址在此: https://www.youtube.com/watch?v=PMsVM7rjupU& ...
- Mybitis+springMVC 套路
springMVC:确保能够扫描到所有注解 <!-- 使用Annotation自动注册Bean,只扫描@Controller --> <context:component-scan ...
- Vue v-if ToolList
可根据v-if="IsOk",动态判断标签是否展示 <template> <div id="app"> <input type=& ...