Spring -- <context:component-scan>使用说明
在xml配置了这个标签后,spring可以自动去扫描base-pack下面或者子包下面的java文件,如果扫描到有@Component @Controller@Service等这些注解的类,则把这些类注册为bean
注意:如果配置了<context:component-scan>那么<context:annotation-config/>标签就可以不用再xml中配置了,因为前者包含了后者。另外<context:component-scan>还提供了两个子标签
<context:include-filter> 和 <context:exclude-filter>,注意,两个标签不能同时使用,然会报错
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
错误信息:"发现了以元素 'context:include-filter' 开头的无效内容。应以 '{"http://www.springframework.org/schema/context":exclude-filter}' 之一开头。"
filter标签的type和表达式说明如下:
Filter Type | Examples Expression | Description |
annotation | org.example.SomeAnnotation | 符合SomeAnnoation的target class |
assignable | org.example.SomeClass | 指定class或interface的全名 |
aspectj | org.example..*Service+ | AspectJ語法 |
regex | org\.example\.Default.* | Regelar Expression |
custom | org.example.MyTypeFilter | Spring3新增自訂Type,實作org.springframework.core.type.TypeFilter |
<context:include-filter type="regex" expression="com\.only\.mate\.[^.]+(Controller|Service)"/>
在我们的示例中,将filter的type设置成了正则表达式,regex,注意在正则里面.表示所有字符,而\.才表示真正的.字符。
在说明这两个子标签前,先说一下<context:component-scan>有两个属性,base-package属性告诉spring要扫描的包,use-default-filters="true"(默认为true)表示使用默认的过滤器,此处的默认过滤器,会扫描指定包下的全部的标有@Component的类以及@Component的子注解@Service,@Repository,@Controller等的类,并注册成bean。所以如果仅仅是在配置文件中这么写
<context:component-scan base-package="com.only.mate"/>
Use-default-filter此时为true那么会对base-package包或者子包下的所有的进行java类进行扫描,并把匹配的java类注册成bean。
可以发现这种扫描的粒度有点太大,如果你只想扫描指定包下面的Controller,该怎么办?。如下所示
第一种:base-package指定到Controller类的包名下
<context:component-scan base-package="com.only.mate.controller" />
这样扫描base-package(这个包下只有Controller注释的类)下的类,并注册成bean。
第二种:如下所示
(推荐这样的方式)
<context:component-scan base-package="com.only.mate" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
这样就会只扫描base-package指定下的有@Controller下的java类,并注册成bean。
或则
<context:component-scan base-package="com.only.mate" use-default-filters="true">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
</context:component-scan>
这样就会只扫描base-package指定下的除了@Service下的java类,并注册成bean。
特别要注意的是:
如果将第二种方法的use-dafault-filter改为相反的值,就会产生与你期望相悖的结果
如下所示:
<context:component-scan base-package="com.only.mate" use-default-filters="true">
<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配置多个包名这种不是很优雅的方法来解决这个问题了。
<context:component-scan base-package="com.only.mate" use-default-filters="false">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
</context:component-scan>
“No mapping found for HTTP request with URI [/SpringMVC/user/index] in DispatcherServlet with name 'springServlet'”,没有扫描Controller注解。
为什么会出现这样的结果呢?
关键在于use-default-filters的值决定扫描的注解类型,这里又要提到这个属性的作用了。
use-default-filters="true"(默认为true)表示使用默认的过滤器,此处的默认过滤器,会扫描指定包下的全部的标有@Component的类以及@Component的子注解@Service,@Repository,@Controller等的类,并注册成bean。
具体分析如下:
<context:component-scan base-package="com.only.mate" use-default-filters="true">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
这种情况use-default-filters="true",默认会扫描包含Service,Component,Repository,Controller注解修饰的类,我们加上了<context:include-filter>标签后,也只是说增加扫描类型,再原有的基础上在增加,所以这样会扫描包含Service,Component,Repository,Controller注解修饰的类以及自己新增的类型的类。(注意:这里会重复扫描Service注解,从而导致事务失效)
<context:component-scan base-package="com.only.mate" use-default-filters="false">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
</context:component-scan>
这种情况use-default-filters="false",所以不会扫描任何类,我们加上了<context:exclude-filter>标签后,也只是说过滤扫描类型,再原有的基础上在减少,所以这样依然没有扫描任何类,所以当启动项目访问的时候会出现“No mapping found for HTTP request with URI [/SpringMVC/user/index] in DispatcherServlet with name 'springServlet'”,说明没有扫描Controller注解。
综上所述:
首先要考虑Use-dafault-filters值的设置,然后在考虑使用<context:exclude-filter>指定不扫描和<context:include-filter>指定扫描。
Spring -- <context:component-scan>使用说明的更多相关文章
- [Spring Boot] Use Component Scan to scan for Bean
Component Scan is important concept when we want to create Bean. Currently we know what, for the cla ...
- Spring <context:component-scan>标签属性 use-default-filters 以及子标签 include-filter使用说明
Spring <context:component-scan>标签作用有很多,最基本就是 开启包扫描,可以使用@Component.@Service.@Component等注解: 今天要作 ...
- Spring依赖注入 --- 简单使用说明
Spring依赖注入 --- 简单使用说明 本文将对spring依赖注入的使用做简单的说明,enjoy your time! 1.使用Spring提供的依赖注入 对spring依赖注入的实现方法感兴趣 ...
- Spring注解Component原理源码解析
在实际开发中,我们经常使用Spring的@Component.@Service.@Repository以及 @Controller等注解来实现bean托管给Spring容器管理.Spring是怎么样实 ...
- Spring context:component-scan中使用context:include-filter和context:exclude-filter
Spring context:component-scan中使用context:include-filter和context:exclude-filter XML: <?xml version= ...
- Spring context:component-scan代替context:annotation-config
Spring context:component-scan代替context:annotation-config XML: <?xml version="1.0" encod ...
- Spring <context:annotation-config> 与<context-component-scan> 的作用
<context:annotation-config> 与<context-component-scan> 的作用 <context:annotation-config& ...
- Spring 注解@Component,@Service,@Controller,@Repository
Spring 注解@Component,@Service,@Controller,@RepositorySpring 2.5 中除了提供 @Component 注释外,还定义了几个拥有特殊语义的注释, ...
- [转载]vs2012中使用Spring.NET报错:Spring.Context.Support.ContextRegistry 的类型初始值设定项引发异常
学习使用Spring.NET中的时候,写了一个Demo,在运行时报了一个错误:Spring.Context.Support.ContextRegistry 的类型初始值设定项引发异常. 重新整理思绪, ...
- 使用web.xml方式加载Spring时,获取Spring context的两种方式
使用web.xml方式加载Spring时,获取Spring context的两种方式: 1.servlet方式加载时: [web.xml] <servlet> <servlet-na ...
随机推荐
- CentOS 6.5 部署 Horizon
以root用户进行部署,python源也可以使用 http://mirrors.aliyun.com/pypi/simple/ 修改系统 更改SElinux的配置文件 /etc/selinux/con ...
- 使用Session防止表单重复提交(不考虑多服务器)
在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交. 原理: 1, ...
- 卡诺模型(KANO Model)
卡诺模型是一种研究影响顾客满意度因素的方法,在软件工程中可以用来辅助做需求分析和优化产品的质量. 作为一种方法,卡诺模型将某一种特性的存在程度作为横坐标,越大表示某个功能或特性做得越多,越小则表示做得 ...
- bat实现创建、复制、删除文件及文件夹
1 建bat文件自动执行复制,删除命令. 例1:以下是复制cd.dll文件至windows\system32的bat文件内容: copy cd.dll %windir%\system32 例2:下面一 ...
- springboot使用hibernate validator校验方式
一.参数校验 在开发中经常需要写一些字段校验的代码,比如字段非空,字段长度限制,邮箱格式验证等等,写这些与业务逻辑关系不大的代码个人感觉有两个麻烦: 验证代码繁琐,重复劳动 方法内代码显得冗长 每次要 ...
- 解决EditPlus的默认编码方式有关问题(转)
http://blog.csdn.net/hzhsan/article/details/7911660 最近在使用英文版的Editplus写代码的时候,发现中文字符在调试过程中都变成了乱码, 发现是E ...
- qing-automation简单入门介绍
1.相关文档:http://www.51testing.com/html/50/category-catid-250.html 2.进行Qing automation相关操作之前,必须安装好jdk跟a ...
- 从wiresharp看tcp三次握手
我们知道,传输层是OSI模型中用户进行数据传输的分层,目前仅有TCP和UDP两种协议可用.TCP为了进行传输控制,引入了三次握手机制,以确保通信连接的建立.道理很简单,我们跟别人打电话聊天时,对方拿起 ...
- jeecg中ajax传值的前端js和后台代码
前端js: var b=1; $.ajax({ type : "POST", --Post请求方式 url : 'orderController.do?wuliao', --路径 ...
- Log4j配置概述
一.Log4j 简介 Log4j有三个主要的组件:Loggers(记录器),Appenders (输出源)和Layouts(布局).这里可简单理解为日志类别,日志要输出的地方和日志以何种形式输出.综合 ...