【spring】@ComponentScan详解&@SpringBootApplication的scanBasePackages属性

1. 作用

创建一个配置类,在配置类JavaConfig形式上添加 @ComponentScan 注解。该注解默认会扫描该类所在的包下所有的配置类,相当于之前的 <context:component-scan>

参见 《JavaConfig、@Configuration、@ComponentScan入门例子》

2. @ComponentScan源码

@ComponentScan 的作用就是根据定义的扫描路径,把符合扫描规则的类装配到spring容器中,注解定义如下:

package org.springframework.context.annotation;

@Retention(RetentionPolicy.RUNTIME)
//表示只可以声明在类上
@Target({ElementType.TYPE})
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
    @AliasFor("basePackages")
    String[] value() default {};
 
    @AliasFor("value") //表示和value等价
    String[] basePackages() default {};
 
    Class<?>[] basePackageClasses() default {};
 
    Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;


  • @Target({ElementType.TYPE}) 表示只可以声明在类上

  • value 表示用法如 @ComponentScan(value="")
    也可以简写为 @ComponentScan("") ,省略value=

  • basePackages,表示用法如@ComponentScan(basePackages=""),由于和value等价(@AliasFor("value")),也可简写为@ComponentScan("")

  • nameGenerator: bean的名称的生成器

  • useDefaultFilters: 是否开启对@Component,@Repository,@Service,@Controller的类进行检测

  • includeFilters: 包含的过滤条件

    • FilterType.ANNOTATION:按照注解过滤

    • FilterType.ASSIGNABLE_TYPE:按照给定的类型

    • FilterType.ASPECTJ:使用ASPECTJ表达式

    • FilterType.REGEX:正则

    • FilterType.CUSTOM:自定义规则

  • excludeFilters: 排除的过滤条件,用法和includeFilters一样

一个稍完整的示例:

// com.jiaobuchong.business 和 com.jiaobuchong.user.servic 下的类都不会被扫描
@ComponentScan(basePackages = {"com.jiaobuchong.order.service"},
        excludeFilters = {@ComponentScan.Filter(type = FilterType.REGEX,
                pattern = "com.jiaobuchong.business\\..*"),
                @ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.jiaobuchong.user.service\\..*")})

3. SpringBootApplicatioscan中的scanBasePackages属性

本质上,SpringBootApplicatioscan中的scanBasePackages属性底层原理正是复用了@ComponentScan,因此语法和意义基本一致

...
public @interface SpringBootApplication {
   //复用了@ComponentScan
    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackages"
    )
    String[] scanBasePackages() default {};

@AliasFor标签表示别名的意义,可以理解为等价于

因此,下面2种用法相同:

@SpringBootApplication (scanBasePackages="com.test")
public class MyClass {

package com.test;
@ComponentScan("com.test")
@SpringBootApplication
public class MyClass {

4. 注意事项

4.1 Spring Boot项目

当使用Spring Boot项目时,可以不指定加载路径,即不使用@ComponentScan或@SpringBootApplication (scanBasePackages="com.test"),默认会加载MyClass所在的包

举个例子,看下面定义的类:

package com.test;
@SpringBootApplication
public class MyClass {

MyClass 的package为com.test,这个类使用了@SpringBootApplication注解,该注解定义了Spring将自动扫描包com.test及其子包下的bean。

如果你项目中所有的类都定义在com.demo.springboot包及其子包下,那你不需要做任何事。

但假如你一个类定义在包com.test2下,则你需要将这个新包也纳入扫描的范围,有两个方案可以达到这个目的:

  • 方案1, 定义@CoponentScan(“com”)

    这么做扫描的范围扩大到整个父包com

  • 方案2, 定义分别扫描两个包
    @ComponentScan({“com.test”,”com.test2”})

4.2 非 Spring Boot项目

在非Spring Boot项目中,我们必须显式地使用@ComponentScan注解定义被扫描的包,可以通过XML文件在应用上下文中定义或在Java代码中对应用上下文定义,否则会加载不到预期的bean。


参考:
《@ComponentScan 详解》 列出了具体参数的用法

《Spring注解——使用@ComponentScan自动扫描组件》 包含讲解和例子
《Spring和SpringBoot中的@Component 和@ComponentScan注解用法介绍和注意事项》

  • 31
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
@ComponentScan是Spring框架中的注解之一,用于指定要扫描的包及其子包,以自动注册Spring容器中的Bean。它的作用是告诉Spring在指定的包中查找带有@Component注解(或其他特定注解)的类,并将其实例化为Bean,并加入到Spring容器中统一管理。 @ComponentScan可以用在@Configuration注解的类上,也可以用在普通的@Component注解的类上。当用在@Configuration注解的类上时,它会扫描指定包下的所有类并注册为Bean;当用在普通的@Component注解的类上时,它会扫描指定包下的所有类并将其作为普通Bean进行注册。 @ComponentScan可以接收一个或多个参数,常见的参数如下: - basePackages:指定要扫描的包路径,可以使用字符串数组指定多个包。例如:@ComponentScan(basePackages = {"com.example.package1", "com.example.package2"}) - basePackageClasses:指定要扫描的类所在的包,Spring会根据这些类所在的包路径进行扫描。例如:@ComponentScan(basePackageClasses = {Class1.class, Class2.class}) - includeFilters:指定要包含的过滤条件,只有符合条件的类才会被注册为Bean。例如:@ComponentScan(includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, value = MyAnnotation.class)) - excludeFilters:指定要排除的过滤条件,符合条件的类不会被注册为Bean。例如:@ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = MyExcludeClass.class)) 除了上述常见的参数外,还可以使用其他参数来进一步细化扫描的范围和条件。通过灵活配置@ComponentScan注解,我们可以方便地进行自动扫描和注册Bean,减少手动配置的工作量。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值