自从Spring2.5版本以后就引入了很多典型化注解(stereotype annotation),例如:@Component以及其子注解@Service、@Controller、@Repository。这些注解和context:component-scan标签搭配使用使bean被加载进spring容器变得极其方便,因为我们不用在xml中一个个配置了。@Component以及其子注解使用起来非常简单,不用再多说,这里分享下context:component-scan标签的用法。

        context:component-scan标签的作用是可以使spring扫面一个基目录,这个目录及其子目录下的类如果被@Component以及其子注解标记的话那么spring就可以将其加载进spring容器,例如:

        如果这样的配置的话表明com.zws这个包(目录)及其子包下的标记了@Component以及其子注释的类在spring容器初始化的时候都会被加载进spring容器。这样配置是很方便,一股脑把所有的标记了注解的类都加载进去了,但是这样配置粒度有大,有时候我们并不希望加载所有的bean,或者是我们希望在不同的spring容器加载不同的bean,例如,在使用SpringMVC的时候我们希望父容器加载业务逻辑bean和数据库持久bean,而子容器加载视图控制层的bean。这样我们就要对扫描的粒度加以控制。  

         context:component-scan标签还有一个属性:use-default-filters,此属性接受一个boolean类型的值(true/false),默认情况下为true。例如:

         此属性值为true时表示使用默认的注解过滤器,即@Component以及其子注解都会被扫描(加载进spring容器)进来,这也是在此属性在不设置的情况下会扫描所有被注解的bean的原因。

 此属性值为false的时候表示不使用默认注解过滤器,那么不使用默认注解过滤器的时候应该扫描那些bean呢?context:component-scan标签下还有两个子标签,这两个子标签是:context:include-filter和

context:exclude-filter。这两个标签都有两个属性:type和expression,这两个属性结合在一起可以指定一类特定的bean,例如:


    

         这就表示使用默认注解过滤器扫描com.zws基目录下除了@Controller注解的所有@Component以及其子注解标记的类。也就是说com.zws及其子目录下除了被@Controller注解的类以外的所有@Component以及其子注解标记的类都会被加载进spring容器。这也说明context:exclude-filter标签只有在context:component-scan标签的use-default-filters属性的值为true时才起作用。而context:include-filter标签则相反,例如:


	

        这表示不使用默认注解过滤器扫描com.zws基目录下的bean,但是只扫面基目录下被@Controller注解标记的bean。context:include-filter标签只有在context:component-sca标签的use-default-filters属性的值为false时才起作用。所以context:component-scan标签下如果同时出现context:include-filter和context:exclude-filter是不正确的,schema校验就过不去。

        context:include-filter标签和context:exclude-filter标签的属性type值不只是有annotation一种,其实他有5中不同的类型及其不同的expression的写法,如下所示:

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.typ