<context:component-scan base-package="com.wjx.betalot" <!-- 扫描的基本包路径 -->
annotation-config="true" <!-- 是否激活属性注入注解 -->
name-generator="org.springframework.context.annotation.AnnotationBeanNameGenerator" <!-- Bean的ID策略生成器 -->
resource-pattern="**/*.class" <!-- 对资源进行筛选的正则表达式,这边是个大的范畴,具体细分在include-filter与exclude-filter中进行 -->
scope-resolver="org.springframework.context.annotation.AnnotationScopeMetadataResolver" <!-- scope解析器 ,与scoped-proxy只能同时配置一个 -->
scoped-proxy="no" <!-- scope代理,与scope-resolver只能同时配置一个 -->
use-default-filters="false" <!-- 是否使用默认的过滤器,默认值true -->
>
<!-- 注意:若使用include-filter去定制扫描内容,要在use-default-filters="false"的情况下,不然会“失效”,被默认的过滤机制所覆盖 -->
<!-- annotation是对注解进行扫描 -->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/>
<!-- assignable是对类或接口进行扫描 -->
<context:include-filter type="assignable" expression="com.wjx.betalot.performer.Performer"/>
<context:include-filter type="assignable" expression="com.wjx.betalot.performer.impl.Sonnet"/>
<!-- 注意:在use-default-filters="false"的情况下,exclude-filter是针对include-filter里的内容进行排除 -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:exclude-filter type="assignable" expression="com.wjx.betalot.performer.impl.RainPoem"/>
<context:exclude-filter type="regex" expression=".service.*"/>
</context:component-scan>
back-package:标识了<context:component-scan>元素所扫描的包,可以使用一些通配符进行配置
annotation-config:<context:component-scan>元素也完成了<context:annotation-config>元素的工作,开关就是这个属性,false则关闭属性注入注解功能
name-generator:这个属性指定你的构造型注解,注册为Bean的ID生成策略,这个生成器基于接口BeanNameGenerator实现generateBeanName方法,你可以自己写个类去自定义策略。这边,我们可不显示配置,它是默认使用org.springframework.context.annotation.AnnotationBeanNameGenerator生成器,也就是类名首字符小写的策略,如Performer类,它注册的Bean的ID为performer.并且可以自定义ID,如@Component("Joy").这边简单贴出这个默认生成器的实现。
resource-pattern:对资源进行筛选的正则表达式,这边是个大的范畴,具体细分在include-filter与exclude-filter中进行。
scoped-proxy: scope代理,有三个值选项,no(默认值),interfaces(接口代理),targetClass(类代理),那什么时候需要用到scope代理呢,举个例子,我们知道Bean的作用域scope有singleton,prototype,request,session,那有这么一种情况,当你把一个session或者request的Bean注入到singleton的Bean中时,因为singleton的Bean在容器启动时就会创建A,而session的Bean在用户访问时才会创建B,那么当A中要注入B时,有可能B还未创建,这个时候就会出问题,那么代理的时候来了,B如果是个接口,就用interfaces代理,是个类则用targetClass代理。这个例子出处:http://www.bubuko.com/infodetail-1434289.html。
scope-resolver:这个属性跟name-generator有点类似,它是基于接口ScopeMetadataResolver的,实现resolveScopeMetadata方法,目的是为了将@Scope(value="",proxyMode=ScopedProxyMode.NO,scopeName="")的配置解析成为一个ScopeMetadata对象,Spring这里也提供了两个实现,我们一起看下。首先是org.springframework.context.annotation.AnnotationScopeMetadataResolver中,
use-default-filters=”false”表示不要使用默认的过滤器,此处的默认过滤器,会扫描包含Repository
、@Service
、@Controller、
@Component、@Configuration
注释修饰类。
配置完这个标签后,spring就会去自动扫描base-package对应的路径或者该路径的子包下面的java文件,如果扫描到文件中带有@Repository
、@Service
、@Controller、
@Component、@Configuration
等这些注解的类,则把这些类注册为bean
注:在注解后加上例如@Component(value=”abc”)时,注册的这个类的bean的id就是adc.
注:如果配置了<context:component-scan>那么<context:annotation-config/>标签就可以不用在xml中再配置了,因为前者包含了后者。另外<context:annotation-config/>还提供了两个子标签 <context:include-filter>和 <context:exclude-filter>
在特殊的情况下,比如一个项目涉及到多个数据源,我们写单元测试的时候,只希望每次扫描到其中一个数据源的关系类里的 @Repository
、@Service
、@Controller、
@Component、@Configuration。
<context:component-scan > 提供两个子标签:<context:include-filter>和<context:exclude-filter>各代表 引入和排除的过滤。
这里spring 给我们提供了5种方式排除和引入扫描的类中的@Repository
、@Service
、@Controller、
@Component、@Configuration。
类型 | 举例 | 说明 |
annotation | org.springframework.stereotype.Repository | 指定扫描中是否扫描@Repository组件 |
assignable | com.test.role.core.userDaoImpl | 指定是否扫描userDaoImpl.java这个类 |
aspectj | com.test.role.* | 通过aop方式判断所扫描的范围 |
regex | .test.* | 通过正则表达式判断所扫描范围 |
custom | 自定义过滤器 | org.springframework.core.type.TypeFilter |
context:exclude-filter
annotation:
<context:component-scan base-package="com.test.role.core" >
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
<!--含义是这里我们不扫描core包下所有的@Repository注解-->
<!--当然也可以设置为@Service、@Controller、@Component、@Configuration其中一种-->
</context:component-scan>
assignable:
<context:component-scan base-package="com.test.role.core" >
<context:exclude-filter type="assignable" expression="com.test.scan.core.UserImpl"/>
<!--含义是这里我们不扫描指定UserImpl类-->
</context:component-scan>
aspectj:
<context:component-scan base-package="com.test.role.core" >
<context:exclude-filter type="aspectj" expression="com.test.role..*"/>
<!--通过aop的方式-->
</context:component-scan>
regex:
<context:component-scan base-package="com.test.scan.core" >
<context:exclude-filter type="regex" expression="com\.sparta\.trans\.[^.]+(Controller|Service)"/>
<!--通过正则表达式的方式-->
</context:component-scan>
context:include-filter
若使用include-filter去定制扫描内容,要在use-default-filters="false"的情况下,不然会“失效”,被默认的过滤机制所覆盖
<context:component-scan base-package="com.sparta.trans" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
不使用默认的扫描,只扫描base-package指定下的有@Controller下的Java类,并注册成bean