一文让你学会灵活的开启Spring的组件扫描

日常开发中我们经常会使用到Spring提供的各种注解来创建Bena,但是使用注解来创建有一个前提,那就是需要先开启组件扫描。这样Spring才会扫描我们配置的这些类,找到特定的注解为我们创建实例。

今天就让我们来深入了解一下,开启组件扫描的相关知识。本文将会通过xml和注解两种形式为大家介绍。

环境准备

按照三层结构,编写好了Controller、Service、Dao,添加上了对应的注解,并且为了展示创建实例的效果,在无参构造中添加了打印语句,方便查看bean实例是否创建。

// Controller
@Controller
public class PersonController {
  public PersonController() {
    System.out.println("PersonController创建了。");
  }
}

// Service
@Service
public class PersonService {
  public PersonService() {
    System.out.println("PersonService创建了。");
  }
}

// Dao
@Repository
public class PersonDao {
  public PersonDao() {
    System.out.println("PersonDao创建了。");
  }
}

项目结构图

在这里插入图片描述

之后演示的开启组件扫描都是基于这三个类来讲解的。

@Filter

讲解通过注解开启组件扫描之前我们先来了解一下@Filter注解。

@Filter注解是ComponentScan注解类中的一个内部类。

在这里插入图片描述

@Filter注解的作用就是配置过滤规则,通过设置注解的type属性来指定过滤规则,指定好之后设置注解的classes属性来配置要过滤的类,可以配置多个。

Spring提供了一个FilterType类,用于指定过滤规则。

在这里插入图片描述

ANNOTATION:按照注解过滤。
ASSIGNABLE_TYPE:按照指定的类型过滤。
CUSTOM:按照自定义的规则过滤(自定义规则类实现TypeFilter接口)。
ASPECTJ:按照ASPECTJ表达式过滤(不常用)。
REGEX:按照正则表达式过滤(不常用)。

通过伪代码演示一下@Filter的使用。

示例一:过滤添加了@Controller和@Service的类。

@Filter(type = FilterType.ANNOTATION, classes = {Controller.class, Service.class})

示例二:过滤PersonController类。

@Filter(type = FilterType.ASSIGNABLE_TYPE, classes = PersonController.class)

示例三:自定义过滤规则。

// 自定义过滤规则
public class MyTypeFilter implements TypeFilter {

  /**
   *
   * @param metadataReader 读取到的当前正在扫描的类的信息
   * @param metadataReaderFactory 获取到其他任何类的信息
   * @return 返回true为匹配成功,false为匹配失败
   */
  public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) {
    // 获取当前正在扫描的类的注解信息。
    AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
    // 获取当前正在扫描的类的相关信息。
    ClassMetadata classMetadata = metadataReader.getClassMetadata();
    // 获取当前正在扫描的类的路径。
    Resource resource = metadataReader.getResource();
    // 演示所用代码,未做任何逻辑处理,直接返回匹配成功。
    return true;
  }
}

使用自定义过滤规则。

@Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class})

通过注解形式开启组件扫描

使用@ComponentScan注解开启组件扫描。

1、@ComponentScan注解的作用是标识开启组件扫描。
2、@ComponentScan注解可以添加类上。
3、该注解是一个可重复添加注解,也就是表示该注解可以在一个类上重复使用(必须java8才可以,之前的可以使用@ComponentScans注解,这个注解里面可以配置多个@ComponentScan)
4、通过给注解的value和basePackages属性赋值来设置扫描的包。
5、通过设置注解的excludeFilters属性来排除不需要扫描的类。
6、通过设置注解的includeFilters属性来指定只扫描哪些类。
    注意:要使用includeFilters需要设置注解的useDefaultFilters属性为false(不使用默认过滤器)才管用。

excludeFilters和includeFilters属性接收的值是一个Filter[]。下面通过几个示例来讲解一下。

示例一:开启组件扫描,并通过excludeFilters属性排除添加了@Controller注解的类和PersonService类。

@Configuration
// 开启组件扫描,排除不需要的类。
@ComponentScan(basePackages = "com.springtest",
    excludeFilters = {
        @Filter(type = FilterType.ANNOTATION, classes = {Controller.class}),
        @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {PersonService.class})
    }
)
public class MainComponentScanConfig {

}

编写测试类,进行测试。

在这里插入图片描述

示例二:开启组件扫描,通过includeFilters属性指定按自定义的过滤规则配置需要扫描的类。

@Configuration
// 开启组件扫描,不使用默认过滤器,配置需要扫描的类
@ComponentScan(basePackages = "com.springtest", useDefaultFilters = false,
    includeFilters = {
        @Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class})
    }
)
public class MainComponentScanConfig {

}

注意:自定义的过滤规则类(MyTypeFilter)使用的是上面讲解@Filter注解中的示例代码。没有做任何逻辑处理,直接返回的true。

测试结果。

在这里插入图片描述

使用XML配置文件开启组件扫描

使用xml的方式开启组件扫描需要在spring的配置文件先导入context名称空间。

xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">

在这里插入图片描述

通过context:component-scan标签来开启组件扫描。

1、通过设置base-package属性的值类指定扫描的包。
2、通过设置use-default-filters属性的值(值为false或true)来确定是否使用默认过滤器。
3、设置<context:include-filter>来规定扫描哪些类。
4、设置<context:exclude-filter>配置不扫描哪些类。
    这个两个标签的type属性表示过滤规则,expression表过滤的类。跟使用@Filter注解配置type和classes属性一样。

过滤的规则也有五种。

在这里插入图片描述

下面通过代码具体演示一下如何使用xml开启组件扫描。

<!-- 开启组件扫描,配置不扫描添加了@Controller和@Service注解的类 -->
<context:component-scan base-package="com.springtest">
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
</context:component-scan>

<!-- 开启组件扫描,配置不扫描自己编写的PersonService类-->
<context:component-scan base-package="com.springtest">
    <context:exclude-filter type="assignable" expression="com.springtest.service.PersonService"/>
</context:component-scan>

<!-- 开启组件扫描,不使用默认过滤器,按自定过滤规则配置扫描哪些类-->
<context:component-scan base-package="com.springtest" use-default-filters="false">
    <context:include-filter type="custom" expression="com.springtest.condition.MyTypeFilter"/>
</context:component-scan>

测试类和测试结果就不在此展示了,毕竟现在基本上都是使用注解进行开发,感兴趣的朋友可以自己试一下。

今天的分享就到这里了,如果感觉“菜鸟”写的文章还不错,记得点赞、转发加关注呦!你们的支持就是我坚持下去的动力。文章哪里写的有问题的也希望大家可以指出,我会虚心受教。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值