目录
@AutoConfigurationPackage 和 @ComponentScan 有何区别?
3.2 使用@AutoConfigurationPackage
@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
放在一个单独的包后,TutorialService
和TutorialMapper
单独存放在一个包,将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