@AutoConfigurationPackage 和 @ComponentSc···

发布时间:2025-05-21 18:33:11 作者:益华网络 来源:undefined 浏览量(2) 点赞(3)
摘要:来源:江南一点雨 面试真是越来越卷了,最近又有小伙伴在微信上问到松哥这样一个面试题,想到这两个的区别其实还有点意思,因为整一篇文章和小伙伴们捋一捋。 首先,从名字上看,这两个注解意义特别接近,@AutoConfigura

来源:江南一点雨

面试真是越来越卷了,最近又有小伙伴在微信上问到松哥这样一个面试题,想到这两个的区别其实还有点意思,因为整一篇文章和小伙伴们捋一捋。

首先,从名字上看,这两个注解意义特别接近,@AutoConfigurationPackage 就是自动配置包,自动配置包的目的是能让系统扫描到包内的 Bean;@ComponentScan 则是组件扫描,这个松哥在之前的教程中也多次提到过了,就不再赘述了,所以这里就有一个问题,这两个注解有啥区别?

首先大家思考这样一个问题:

现在大多数项目可能都是用的 MyBatis 或者 MyBatis-Plus 这样的数据持久化框架,当我们在 Spring Boot 中使用 MyBatis 的时候,我们一般需要在 Mapper 接口上添加一个 @Mapper 注解,类似下面这样:

@Mapperpublic interface UserMapper 

{

}

或者在启动类上加 Mapper 扫描注解去统一扫描所有的 Mapper 接口,类似下面这样:

@SpringBootApplication@MapperScan(basePackages = "org.javaboy.auto_package"

)

public class AutoPackageApplication 

{

    public static void main(String[] args) 

{

        SpringApplication.run(AutoPackageApplication.classargs)

;

    }

}

平时我们都这样写,没有任何问题,现在假设我们换一个写法,假如我的类结构如下:

├── main

│   ├── java

│   │   └── org

│   │       └── javaboy

│   │           └── auto_package

│   │               ├── config

│   │               │   ├── AutoPackageApplication.java

│   │               │   └── UserController.java

│   │               ├── mapper

│   │               │   └── UserMapper.java

│   │               └── service

│   │                   └── UserService.java

小伙伴们看到,我把启动类和 UserController 放在一个单独的包中,UserMapper 和 UserService 也分别位于不同的包中,其中在 UserController 中注入了 UserService,在 UserService 中则注入了 UserMapper,大致上就这么一个关系。

按照我们之前对 Spring Boot 的理解,这个项目启动肯定会报错,因为默认情况下,系统扫描的 Bean 是启动类所在的包以及子包下的所有 Bean(因为 @SpringBootApplication 注解在启动类上),所以上面这个项目启动的时候,能扫描到 UserController,但是扫描不到 UserService,所以启动的时候会报错,如下:

大家看下,这意思很明确,UserService 找不到,所以启动失败。

解决这个问题的办法很简单,要么将启动类放到根包下面,这样所有的 Bean 默认就都能扫描到了,要么我们重新配置包扫描,这里我采用第二种方案,我们在启动类上加 @ComponentScan 注解,重新指定扫描的包,如下:

@SpringBootApplication@ComponentScan(basePackages = "org.javaboy.auto_package"

)

public class AutoPackageApplication 

{

    public static void main(String[] args) 

{

        SpringApplication.run(AutoPackageApplication.classargs)

;

    }

}

加上之后,我们再次启动,发现又报错了,如下:

虽然再次出错,但是跟之前的错误并不一样,这次是没找到 UserMapper 这个 Bean,说明 UserService 是找到了!

从这里我们就可以看出来,@ComponentScan 注解扫描组件是不会扫描到 @Mapper 注解的!

事实上,@ComponentScan 注解主要是扫描 Spring 家族的各种 Bean,如 @Controller、@Service、@Component、@Repository 以及由此衍生出来的一些其他的 Bean,对于 Spring 家族之外的 Bean,如 MyBatis 的 @Mapper、@MapperScan,JPA 的 @Entity 等,@ComponentScan 都扫不到!

谁能扫到呢?那就是我们今天的另外一个主角 @AutoConfigurationPackage,这个注解其实就是专门用来扫这些第三方的各种 Bean 的。

现在,我们在项目启动上加上 @AutoConfigurationPackage 注解,并设置需要扫描的位置,如下:

@SpringBootApplication@AutoConfigurationPackage(basePackages = "org.javaboy.auto_package"

)

@ComponentScan(basePackages = "org.javaboy.auto_package"

)

public class AutoPackageApplication 

{

    public static void main(String[] args) 

{

        SpringApplication.run(AutoPackageApplication.classargs)

;

    }

}

此时,项目就可以成功启动了,因为 @AutoConfigurationPackage(basePackages = "org.javaboy.auto_package") 注解可以扫描到 @Mapper 注解。

当然,这里只是为了给大家演示问题,实际场景下直接在启动类上加 @MapperScan(basePackages = "org.javaboy.auto_package") 注解就可以了。因为 @MapperScan 注解是 mybatis-spring 提供的,而 @Mapper 是 MyBatis 自己提供的,两个注解的出处本身就不同。

默认情况下,Spring Boot 项目的启动注解中,实际上已经包含了 @AutoConfigurationPackage 注解,具体位置在 @SpringBootApplication->@EnableAutoConfiguration->@AutoConfigurationPackage,默认该注解没有指定 basePackages 属性,表示使用启动类所在的包作为根包,扫描该包下的所有第三方 Bean,所以我们平时在 Spring Boot 中使用 MyBatis 的时候,是不需要额外加 @AutoConfigurationPackage 注解的。

经过上面问题的演示,相信小伙伴们已经搞明白了 @AutoConfigurationPackage 和 @ComponentScan 的区别了吧?

小结

总结一下:

两者都是用来扫描 Bean 的。@ComponentScan 主要用来扫描和 Spring 容器相关的 Bean。@AutoConfigurationPackage 主要用来扫描第三方的 Bean。

仅此而已。

二维码

扫一扫,关注我们

声明:本文由【益华网络】编辑上传发布,转载此文章须经作者同意,并请附上出处【益华网络】及本页链接。如内容、图片有任何版权问题,请联系我们进行处理。

感兴趣吗?

欢迎联系我们,我们愿意为您解答任何有关网站疑难问题!

您身边的【网站建设专家】

搜索千万次不如咨询1次

主营项目:网站建设,手机网站,响应式网站,SEO优化,小程序开发,公众号系统,软件开发等

立即咨询 15368564009
在线客服
嘿,我来帮您!