在学习的时候遇到spring配置只扫描指定注解的一些问题


文章目录

  • 配置扫描指定的注解
  • 在用注解前需要了解几个常用注解的关系
  • @Component
  • 源码
  • @Controller
  • @Service
  • @Repository
  • 从以上来看,本质上都是Component注解
  • 一、使用xml配置只扫描含有某个注解的类
  • 二、使用xml配置排除扫描某个注解
  • 总结



问题:
在我配置context:exclude-filter无效的问题
我在配置中使用了以下代码,但并没有起到作用,所有的类都无法被加载到springIOC容器中.导致找不到可用的bean叫xx的异常

<context:component-scan base-package="com.hu.bean">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Component"/>
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>

配置扫描指定的注解

在spring的配置文件中使用<context:component-scan>标签进行包扫描,扫描注解.

在用注解前需要了解几个常用注解的关系

@Component

源码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
    String value() default "";
}

@Controller

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
    @AliasFor(
    	//可以看出Controller是Component的一个别名,本质上还是一个Component
        annotation = Component.class
    )
    String value() default "";
}

@Service

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
    @AliasFor(
    //Service注解也是Component注解的别名
        annotation = Component.class
    )
    String value() default "";
}

@Repository

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {
    @AliasFor(
    //Repository也是一样的
        annotation = Component.class
    )
    String value() default "";
}

从以上来看,本质上都是Component注解


一、使用xml配置只扫描含有某个注解的类

通过xml文件配置

<context:component-scan base-package="com.hu.bean" 
						use-default-filters="false">
   <!--use-default-filters属性默认值为true,一般不写-->
   <!--当为false时,表示不采用默认的过滤器,
   这样包下的含有:
   		Component
   		Service
   		Controller
   		Repository
   都不会被扫描注册加载到IOC容器中
   可以使用include-filter配置指定的注解,让其被扫描创建注册到容器中
	-->
	<context:include-filter type="annotation"
	 expression="org.springframework.stereotype.Repository"/>
	 <context:include-filter type="annotation" 
	 expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

二、使用xml配置排除扫描某个注解

使用

<context:exclude-filter type="annotation" expression="org.springframework.stereotype.某个注解">
<context:component-scan base-package="com.hu.bean">
						
   <!--use-default-filters属性默认值为true,一般不写-->
   	<context:exclude-filter type="annotation"
	 expression="org.springframework.stereotype.Component"/>
	 <context:include-filter type="annotation" 
	 expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

在使用exclude-filter的时候,构造方法没有执行.

这让我非常不理解,检查代码后发现没有问题,于是去写了测试用例,通过获取getBean()想看看有没有被加载到容器中,结果出现了异常,根本没有对应的bean对象在容器中.

我又试了其他几个注解,也是一样的情况,这让我想起来Component的注解和其他三个注解的关系,可能是这个原因,于是我将Component注解的exclude-filter注释了,发现就没有问题了.

<context:component-scan base-package="com.hu.bean">
						
   <!--use-default-filters属性默认值为true,一般不写-->
   	<!--<context:exclude-filter type="annotation"
	 expression="org.springframework.stereotype.Component"/>-->
	 <!--可以加载了-->
	 <context:include-filter type="annotation" 
	 expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

总结

在使用context:exclude-filter标签排除某个注解的时候,不可以将注解Component排除了,这会导致其他所有的被注解标注要纳入springIOC容器管理的类全部不被扫描创建并加载到容器中.