关于SpingMVC的<context:component-scan>包扫描踩坑记录

目录
  • <context:component-scan>包扫描的坑
    • 改动前
    • 改动后
  • <context:component-scan>的使用说明
    • <context:annotation-config/>提供了两个子标签

<context:component-scan>包扫描的坑

公司项目配置的Spring项目的包扫描有点问题,出现了一个被Spring容器管理的Bean被创建了2次的现象。在此记录下解决的过程,方便后续查阅。

改动前

容器启动监听器中会扫描全部包,创建实例

SpringMVC配置文件也会扫描全部包,创建实例

产生的问题:加了注解的类的实例都创建了2个

改动后

容器启动监听器里面负责非Controller层bean的创建

SpingMVC配置文件里只负责Controller层bean的创建

<context:component-scan>的使用说明

在xml配置了这个标签后,spring可以自动去扫描base-package下面或者子包下面的java文件,如果扫描到有@Component @Controller@Service等这些注解的类,则把这些类注册为bean

注意:如果配置了<context:component-scan>那么<context:annotation-config/>标签就可以不用再xml中配置了,因为前者包含了后者。

<context:annotation-config/>提供了两个子标签

<context:include-filter>
<context:exclude-filter>

再说明这两个子标签前,先说一下<context:component-scan>有一个use-default-filters属性,改属性默认为true,这就意味着会扫描指定包下的全部的标有@Component的类,并注册成bean.也就是@Component的子注解@Service,@Reposity等。所以如果仅仅是在配置文件中这么写

<context:component-scan base-package="tv.huan.weisp.web"/>

use-default-filter此时为true那么会对base-package包或者子包下的所有的进行java类进行扫描,并把匹配的java类注册成bean。

可以发现这种扫描的粒度有点太大,如果你只想扫描指定包下面的Controller,该怎么办?此时子标签context:incluce-filter就起到了用武之地。

如下所示

<context:component-scan base-package="tv.huan.weisp.web .controller">  
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>   
</context:component-scan>  

这样就会只扫描base-package指定下的有@Controller下的java类,并注册成bean

但是因为use-dafault-filter在上面并没有指定,默认就为true,所以当把上面的配置改成如下所示的时候,就会产生与你期望相悖的结果(注意base-package包值得变化)

<context:component-scan base-package="tv.huan.weisp.web ">  
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>   
</context:component-scan>  

此时,spring不仅扫描了@Controller,还扫描了指定包所在的子包service包下注解@Service的java类

此时指定的include-filter没有起到作用,只要把use-default-filter设置成false就可以了。这样就可以避免在base-packeage配置多个包名这种不是很优雅的方法来解决这个问题了。

另外在我参与的项目中可以发现在base-package指定的包中有的子包是不含有注解了,所以不用扫描,此时可以指定<context:exclude-filter>来进行过滤,说明此包不需要被扫描。综合以上说明

use-dafault-filters=”false”的情况下:

<context:exclude-filter>指定的不扫描,<context:include-filter>指定的扫描

定位问题原因* 根据原因思考问题解决方案* 实践验证方案有效性* 提交验证结果

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • @ComponentScan在spring中无效的原因分析及解决方案

    目录 @ComponentScan在spring中无效 查了大量资料之后,找到了原因 @Component和@ComponentScan常规理解 @Component和@ComponentScan的联系 @SpringBootApplication和@ComponentScan,扫描包的区别 @ComponentScan在spring中无效 在我实现第一个spring AOP程序的时候,我按照主流的推荐,采用注解@ComponentScan @Aspect @Before 来实现一个切面. 让我

  • Component-Scan 不扫描jar里面的类问题

    目录 Component-Scan 不扫描jar里面的类 关于context:component-scan等等一些列扫描包的问题记录 解决 Component-Scan 不扫描jar里面的类 今天碰到一个奇怪的问题,配置的spring的 <context:component-scan base-package="*.*"/> 部署到服务器上后发现jar包里面的类没有被扫描,但是在本地是正常的. 反复测试发现原来配置为*.*后jar里面的真不扫描了,改成com.aa.bb.*

  • SpringBoot默认包扫描机制及@ComponentScan指定扫描路径详解

    目录 SpringBoot默认包扫描机制 @ComponentScan的使用 常用参数含义 @Component与@ComponentScan SpringBoot默认包扫描机制 标注了@Component和@Component的衍生注解如@Controller,@Service,@Repository就可以把当前的Bean加入到IOC容器中.那么SpringBoot是如何知道要去扫描@Component注解的呢.@ComponentScan做的事情就是告诉Spring从哪里找到bean Spr

  • 关于SpingMVC的<context:component-scan>包扫描踩坑记录

    目录 <context:component-scan>包扫描的坑 改动前 改动后 <context:component-scan>的使用说明 <context:annotation-config/>提供了两个子标签 <context:component-scan>包扫描的坑 公司项目配置的Spring项目的包扫描有点问题,出现了一个被Spring容器管理的Bean被创建了2次的现象.在此记录下解决的过程,方便后续查阅. 改动前 容器启动监听器中会扫描全部包,

  • 关于@MapperScan包扫描的坑及解决

    目录 @MapperScan包扫描的坑 手写一个@MapperScan扫描器 @MapperScan 自己手写该注解的思路 @MapperScan包扫描的坑 在使用通用mapper执行查询时,由于不太注意顺手就导了spring的包: import org.mybatis.spring.annotation.MapperScan; 结果就异常: tk.mybatis.mapper.provider.base.BaseSelectProvider:xxxx 找了半天才发现是包的问题,应该导mybat

  • Redis中Scan命令的踩坑实录

    1.原本以为自己对redis命令还蛮熟悉的,各种数据模型各种基于redis的骚操作.但是最近在使用redis的scan的命令式却踩了一个坑,顿时发觉自己原来对redis的游标理解的很有限.所以记录下这个踩坑的过程,背景如下: 公司因为redis服务器内存吃紧,需要删除一些无用的没有设置过期时间的key.大概有500多w的key.虽然key的数目听起来挺吓人.但是自己玩redis也有年头了,这种事还不是手到擒来? 当时想了下,具体方案是通过lua脚本来过滤出500w的key.然后进行删除动作.lu

  • Spring Bean的包扫描的实现方法

    我们知道,Spring可以通过包扫描将使用@Component注解定义的Bean定义到容器中.今天就来探究下他实现的原理. 首先,找到@Component注解的处理类 注解的定义,一般都需要配套的对注解的处理才能完成注解所代表的功能.所以我们通过@Component注解的用到的地方,来查找可能的处理逻辑; 我们先进入Spring的项目,在IDEA里面用Ctrl和鼠标左键点击Component注解的名称,IDEA会显示出使用到这个类的位置,我们从弹出的列表中找到一个名称像的类,去看类上面的注释说明

  • 详解Java 包扫描实现和应用(Jar篇)

    如果你曾经使用过 Spring, 那你已经配过 包扫描路径吧,那包扫描是怎么实现的呢?让我们自己写个包扫描 上篇文章中介绍了使用 File 遍历的方式去进行包扫描,这篇主要补充一下jar包的扫描方式,在我们的项目中一般都会去依赖一些其他jar 包, 比如添加 guava 依赖 <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <ve

  • springBoot mybatis 包扫描实例

    springBoot mybatis 包扫描 @MapperScan(basePackages = {"com.zscat.*.dao","com.zscat.*.*.dao"}) @EnableTransactionManagement(proxyTargetClass = true) @SpringBootApplication @MapperScan(basePackages = {"com.zscat.*.dao","com.z

  • springboot多模块包扫描问题的解决方法

    问题描述: springboot建立多个模块,当一个模块需要使用另一个模块的服务时,需要注入另一个模块的组件,如下面图中例子: memberservice模块中的MemberServiceApiImpl类需要注入common模块中的RedisService组件,该怎么注入呢? 解决: 在memberservice模块的启动类上加上RedisService类所在包的全路径的组件扫描,就像这样: 注意启动类上方的注解@ComponentScan(basePackages={"com.whu.comm

  • vscode 安装go第三方扩展包填坑记录的详细教程

    1.vscode中安装go扩展包,不再阐述. 2.在安装好go的扩展包以后,创建GOPATH环境变量 3.PATH中会自动添加,如果没有可手动添加 4.在GOPATH目录下创建自己的工作空间(为什么一定是在GOPATH下创建,还不太清楚),我的是workspace(名称可以自定义) 5.打开VSCODE,文件-打开文件夹,选择GOPATH目录 6.在workspace下创建helloworld目录(我称为项目空间) 7.配置VSCODE中的setting.json文件 加入如下配置: 8.编写h

  • 解决golang中container/list包中的坑

    golang中list包用法可以参看这篇文章 但是list包中大部分对于e *Element进行操作的元素都可能会导致程序崩溃,其根本原因是e是一个Element类型的指针,当然其也可能为nil,但是golang中list包中函数没有对其进行是否为nil的检查,变默认其非nil进行操作,所以这种情况下,便可能出现程序崩溃. 1.举个简单例子 Remove()函数 package main import ( "container/list" "fmt" ) func

随机推荐