JAVA面试题分享三百九十八:@AutoConfigurationPackage 和 @ComponentScan 有何区别?

目录

@AutoConfigurationPackage 和 @ComponentScan 有何区别?

1. 注解简介

2. 实际问题场景介绍

3. 解决方案

3.1 使用@ComponentScan

          3.2 使用@AutoConfigurationPackage

4.补充说明


@AutoConfigurationPackage 和 @ComponentScan 有何区别?

在Spring框架中,自动化配置(Auto-Configuration)是一项强大的功能,允许我们通过少量的配置就能够快速搭建和运行Spring应用,减少我们进行复杂的配置。在自动化配置的背后,有一些关键的注解和配置元素,其中包括@AutoConfigurationPackage和@ComponentScan。这两者在扫描和注册组件时起到了关键的作用,但它们之间有着一些重要的区别

今日内容介绍,大约花费6分钟

图片

1. 注解简介

首先,我们来看一下这两个注解的简单介绍:

  • @AutoConfigurationPackage: 该注解用于扫描指定包下的类,并将其作为自动配置包,以便系统能够扫描到包内的Bean

  • @ComponentScan: 用于组件扫描,扫描指定包下的所有Spring组件,包括@Controller、@Service、@Repository等。默认情况下,Spring Boot会扫描启动类所在包及其子包下的所有组件

思考:@AutoConfigurationPackage 和 @ComponentScan有什么区别?

2. 实际问题场景介绍

在我们使用SpringBoot开发项目时,99.99%会使用到数据持久化框架,比如MyBtais-plus,当在项目中使用时Mybatis-plus时,就需要在Mapper接口添加@Mapper注解:

@Mapper
public interface TutorialMapper extends BaseMapper<Tutorial> {

}

或者在启动类上添加Mapper扫描注解,进行统一扫描Mapper接口

@MapperScan("com.zbbmeta.mapper")
@SpringBootApplication
public class AutoApplication {
    public static void main(String[] args) {
        SpringApplication.run(AutoApplication.class,args);
    }
}

这样配置有一个前提,AutoApplication启动类在所有类的最外层

图片

现在,考虑以下的项目结构:

├── main
│   ├── java
│   │   └── com
│   │       └── zbbmeta
│   │               ├── controller
│   │               │   ├── AutoApplication.java
│   │               │   └── TutorialController.java
│   │               ├── mapper
│   │               │   └── TutorialMapper.java
│   │               └── service
│   │                   └── TutorialService.java

AutoApplication启动类和TutorialController放在一个单独的包后,TutorialServiceTutorialMapper单独存放在一个包,将TutorialService注册到TutorialController。然后将项目启动,那么这个项目就会报错,报错如下:

图片

报错原因:这是因为默认情况下,系统扫描的 Bean 是启动类所在的包以及子包下的所有 Bean,这是由于启动类上@SpringBootApplication注解 ,所以将AutoApplication启动类和TutorialController放在一个单独的包后,可以扫描到TutorialController,但是扫描不到TutorialService

3. 解决方案

3.1 使用@ComponentScan

为了解决上述问题,我们可以重新配置包扫描范围,让Spring Boot能够找到所有的Bean。在启动类上加上@ComponentScan注解,重新指定扫描的包,示例代码如下:

@ComponentScan(basePackages = "com.zbbmeta")
@SpringBootApplication
public class AutoApplication {
    public static void main(String[] args) {
        SpringApplication.run(AutoApplication.class,args);
    }
}


但是这样做可能会导致另一个问题:@ComponentScan注解主要用于扫描Spring家族的Bean,对于一些第三方的Bean,比如MyBatis的@Mapper、@MapperScan,JPA的@Entity等,@ComponentScan是扫描不到的。

我们再次启动,发现又报错了,如下:没有TutorialMapper

图片

3.2 使用@AutoConfigurationPackage

为了解决上述问题,我们引入了@AutoConfigurationPackage注解。这个注解专门用于扫描第三方的各种Bean,例如MyBatis的@Mapper注解。修改启动类如下

@AutoConfigurationPackage(basePackages = "com.zbbmeta")
@ComponentScan(basePackages = "com.zbbmeta")
@SpringBootApplication
public class AutoApplication {
    public static void main(String[] args) {
        SpringApplication.run(AutoApplication.class,args);
    }
}

TutorialMapper类上添加@Mapper注解

@Mapper
public interface TutorialMapper extends BaseMapper<Tutorial> {

}


通过这样的配置发现,@AutoConfigurationPackage注解能够扫描到@Mapper注解,而@ComponentScan则用于扫描Spring家族的Bean

4.补充说明

在实际项目中,多数情况下不需要额外添加@AutoConfigurationPackage注解,因为默认情况下,Spring Boot项目的启动注解中已经包含了@AutoConfigurationPackage注解。默认情况下,@AutoConfigurationPackage使用启动类所在的包作为根包,扫描该包下的所有第三方Bean。

图片

@SpringBootApplication注解实际上包含三个注解:

  • @SpringBootConfiguration

  • @AutoConfigurationPackage

  • @ComponentScan

  • 23
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

之乎者也·

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值