Spring Boot 中 @ComponentScan 与 @EnableAutoConfiguration 的区别

1、简介

本文将带你了解 Spring Boot@ComponentScan@EnableAutoConfiguration 注解的作用以及它们之间的区别。

2、Spring 注解

注解使 Spring 中依赖注入的配置变得更容易。可以在类和方法上使用 Spring Bean 注解来定义 Bean,而不是使用 XML 配置文件。之后,Spring IoC 容器会配置和管理 Bean。

本文主要关注如下注解:

  • @ComponentScan:用于扫描带有注解的 Spring 组件。
  • @EnableAutoConfiguration:用于启用自动配置。

3、它们的区别

这俩注解的主要区别在于 @ComponentScan 会扫描 Spring 组件,而 @EnableAutoConfiguration 则用于自动配置 Spring Boot 应用中存在于 classpath 中的 Bean。

3.1、@ComponentScan

在开发应用时,需要告诉 Spring 框架如何查找受 Spring 管理的组件。@ComponentScan 使 Spring 能够扫描配置、Controller、Service 和我们定义的其他组件。

其中,@ComponentScan 注解与 @Configuration 注解一起使用,用于指定 Spring 扫描组件的包:

@Configuration
@ComponentScan
public class EmployeeApplication {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(EmployeeApplication.class, args);
        // ...
    }
}

也可以使用 basePackageClasses()basePackages() 属性来指定要扫描的包。如果没有指定包,Spring 会将声明 @ComponentScan 注解的类的包作为起始包:

package com.baeldung.annotations.componentscanautoconfigure;

// ...

@Configuration
@ComponentScan(basePackages = {"com.baeldung.annotations.componentscanautoconfigure.healthcare",
  "com.baeldung.annotations.componentscanautoconfigure.employee"},
  basePackageClasses = Teacher.class)
public class EmployeeApplication {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(EmployeeApplication.class, args);
        // ...
    }
}

在本例中,Spring 将扫描 healthcare 包、employee 包和 Teacher 类所在的包以查找组件。

Spring 会在指定的包及其所有子包中搜索带有 @Configuration 注解的配置类,配置类还可以包含 @Bean 注解,该注解将方法返回值注册为 Spring Application Context 中的 Bean。之后,@ComponentScan 注解就能自动检测这些 Bean:

@Configuration
public class Hospital {
    @Bean
    public Doctor getDoctor() {
        return new Doctor();
    }
}

此外,@ComponentScan 注解还可以扫描、检测和注册带有 @Component@Controller@Service@Repository 注解的类的 Bean。

例如,创建一个 Employee 类作为组件,通过 @ComponentScan 注解对其进行扫描:

@Component("employee")
public class Employee {
    // ...
}

3.2、@EnableAutoConfiguration

@EnableAutoConfiguration 注解使 Spring Boot 能够自动配置 Application Context。因此,它会根据 classpath 中包含的 Jar 文件和我们定义的 Bean 自动创建和注册 Bean。

例如,当 classpath 中存在 spring-boot-starter-web 依赖时,Spring boot 会自动配置 Tomcat 和 Spring MVC。但是,如果我们定义了自己的配置,这种自动配置的优先级就会降低。

声明 @EnableAutoConfiguration 注解的类的包被视为默认包。因此,应始终在 root 包中使用 @EnableAutoConfiguration 注解,以便检查每个子包和类:

@Configuration
@EnableAutoConfiguration
public class EmployeeApplication {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(EmployeeApplication.class, args);
        // ...
    }
}

此外,@EnableAutoConfiguration 注解还提供了两个属性,用于手动排除任何参数:

可以使用 exclude 属性来禁用不想自动配置的类列表:

@Configuration
@EnableAutoConfiguration(exclude={JdbcTemplateAutoConfiguration.class})
public class EmployeeApplication {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(EmployeeApplication.class, args);
        // ...
    }
}

使用 excludeName 定义要从自动配置中排除的类的全路径名称列表:

@Configuration
@EnableAutoConfiguration(excludeName = {"org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration"})
public class EmployeeApplication {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(EmployeeApplication.class, args);
        // ...
    }
}

在 Spring Boot 中,可以直接使用 @SpringBootApplication 注解,它是 @Configuration@EnableAutoConfiguration@ComponentScan 三个注的组合(均使用默认属性):

@SpringBootApplication
public class EmployeeApplication {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(EmployeeApplication.class, args);
        // ...
    }
}

4、总结

本文介绍了 Spring Boot 中 @ComponentScan@EnableAutoConfiguration 注解的作用,以及它们之间的区别。


Ref:https://www.baeldung.com/spring-componentscan-vs-enableautoconfiguration