Spring <context:component-scan>标签属性 use-default-filters 以及子标签 include-filter使用说明

Spring <context:component-scan>标签作用有很多,最基本就是 开启包扫描,可以使用@Component、@Service、@Component等注解;

今天要作为发现,记录该标签的属性 use-default-filters 以及子标签 include-filter使用方式 ; 

use-default-filters 默认true,默认会扫描@Component、@Controller、@Service、@Repository注解,因为这些注解都可以说是@Component注解的,后面三个注解相当于是@Component注解的子类;

<xsd:attribute name="use-default-filters" type="xsd:boolean"
                default="true">
                <xsd:annotation>
                    <xsd:documentation><![CDATA[
    Indicates whether automatic detection of classes annotated with @Component, @Repository, @Service,
    or @Controller should be enabled. Default is "true".
                    ]]></xsd:documentation>
                </xsd:annotation>
            </xsd:attribute>

通常SpringWeb项目使用Spring、SpringMvc,那就会存在两个Spring容器,父子关系的容器;我们一般在SpringWeb的配置文件里开启注解扫描,我们只希望扫描Controller形式的注解;

假如存在如下包结构:

  com.xxx
        |
        |-----controller
        |
        |-----service
        

比如我会想我只扫描Controller注解的类,

<context:component-scan base-package="com.xxx">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

一般来看,可能觉得没有什么问题,@Controller也扫描加入Spring容器了;但是仔细看会发现@Service、@Component、@Repository等标注的类也扫描出来的;

将use-default-filters设置为 false

<context:component-scan base-package="com.xxx" use-default-filters="false">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

再测试发现,果然只扫描了@Controller的注解;原因呢:

use-default-filters="false"的时候,在设置<context:include-filter/> 相当于加白名单 ,我只会扫描你允许扫描的注解,就像QQ好友聊天设置了只和好友聊天,不是好友的不能发消息给我;

或者     use-default-filters="true"的时候,在设置<context:exclude-filter/>  相当于加黑名单 ,(上面四种注解@Component、@Service、@Controller、@Repository我都会扫描,至于哪些不要了你说了算,打个比方,QQ上的黑名单,你可以和好友列表中好友聊天,但是不能和黑名单里的发消息吧,差不多这个意思,反正我好久没用过黑名单了。。。

当然了,也可以设置扫描包级别细分到com.xxx.controller,严格按照包定义来扫描,也不会任何问题;

包扫描不严格会导致的问题,Spring事务失效的问题,甚至还会有其他各种问题出现,比如Spring容器、SpringMvc容器都扫描到Service层,这时候父子容器都有Service的bean了,默认先在本容器查找,再去父亲容器查找,两个bean能一样嘛?一个AOP动态代理后的,一个原生态的bean,这时候就会出现事务失效问题,后面会模拟记录下这个问题的;

原文地址:https://www.cnblogs.com/lvbinbin2yujie/p/10308363.html