Spring boot : Sự khác biệt giữa @ComponentScan và @EnableAutoConfiguration

Bài viết này được dịch bài : Trần Anh Tuấn - Học viện lớp java07
Email liên hệ : tanhtuan093@gmail.com
Bài viết gốc : https://www.baeldung.com/spring-componentscan-vs-enableautoconfiguration

1. Giới thiệu

Trong hướng dẫn nhanh này, chúng ta sẽ tìm hiểu về sự khác biệt giữa @ComponentScan và @EnableAutoConfiguration trong Spring Framework

2. Spring Annotations

Annotation giúp bạn dễ dàng định cấu hình chèn phụ thuộc trong Spring. Thay vì sử dụng các tệp cấu hình XML, chúng ta có thể sử dụng các annotation của Spring Bean trên các lớp và phương thức để định nghĩa các bean. Sau đó, vùng chứa Spring IoC định cấu hình và quản lý các bean.

Dưới đây là tổng quan về các annotation mà chúng ta sẽ thảo luận trong bài viết này:

  • @ComponentScan quét các thành phần Spring được chú thích
  • @EnableAutoConfiguration được sử dụng để kích hoạt cấu hình tự động

Bây giờ chúng ta hãy xem xét sự khác biệt giữa hai annotation này.

3. Chúng khác nhau như thế nào

Sự khác biệt chính giữa các annotation này là @ComponentScan quét các thành phần Spring trong khi @EnableAutoConfiguration được sử dụng để tự động cấu hình các bean có trong classpath trong các ứng dụng Spring Boot.

3.1. @ComponentScan

Trong khi phát triển một ứng dụng, chúng ta cần yêu cầu Spring framework tìm kiếm các thành phần do Spring quản lý. @ComponentScan cho phép Spring quét những thứ như cấu hình, bộ điều khiển, dịch vụ và các thành phần khác mà chúng tôi xác định.

Đặc biệt, chú thích @ComponentScan được sử dụng với chú thích @Configuration để chỉ định gói cho Spring quét các thành phần:

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

Ngoài ra, Spring cũng có thể bắt đầu quét từ gói được chỉ định, mà chúng ta có thể xác định bằng cách sử dụng basePackageClasses() hoặc basePackages(). Nếu không có gói nào được chỉ định, thì nó coi gói của lớp khai báo chú thích @ComponentScan là gói bắt đầu:

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);
        // ...
    }
}

Trong ví dụ, Spring sẽ quét các packages healthcareemployee và class Teacher để tìm các thành phần.

Spring tìm kiếm các gói được chỉ định cùng với tất cả các gói con của nó cho các class được chú thích bằng @Configuration. Ngoài ra, các class Configuration có thể chứa các chú thích @Bean, các chú thích này đăng ký các phương thức dưới dạng bean trong ngữ cảnh ứng dụng Spring. Sau đó, chú thích @ComponentScan có thể tự động phát hiện các bean như vậy:

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

Hơn nữa, chú thích @ComponentScan cũng có thể quét, phát hiện và đăng ký các bean cho các class được chú thích bằng @Component, @Controller, @Service và @Repository.

Ví dụ: chúng ta có thể tạo class Employee làm thành phần có thể được quét bởi chú thích @ComponentScan:

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

3.2. @EnableAutoConfiguration

@EnableAutoConfiguration cho phép Spring Boot tự động cấu hình ngữ cảnh ứng dụng. Do đó, nó tự động tạo và đăng ký các bean dựa trên cả các tệp jar được bao gồm trong classpath và các bean do chúng ta xác định.

Ví dụ: khi chúng tôi xác định sự phụ thuộc của spring-boot-starter-web trong classpath của chúng tôi, Spring boot sẽ tự động cấu hình Tomcat và Spring MVC. Tuy nhiên, cấu hình tự động này ít được ưu tiên hơn trong trường hợp chúng tôi xác định cấu hình của riêng mình.

Gói của lớp khai báo @EnableAutoConfiguration được coi là package mặc định. Do đó, chúng ta nên luôn áp dụng @EnableAutoConfiguration trong package gốc để mọi package con và class đều có thể được kiểm tra:

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

Hơn nữa, @EnableAutoConfiguration cung cấp hai tham số để loại trừ bất kỳ tham số nào theo cách thủ công:
Chúng ta có thể sử dụng loại trừ để vô hiệu hóa danh sách các class mà chúng ta không muốn tự động cấu hình:

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

Chúng ta có thể sử dụng excludeName để xác định danh sách tên class đủ điều kiện mà chúng ta muốn loại trừ khỏi cấu hình tự động:

@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);
        // ...
    }
}

Kể từ Spring Boot 1.2.0, chúng ta có thể sử dụng @SpringBootApplication, là sự kết hợp của ba annotations @Configuration, @EnableAutoConfiguration và @ ComponentScan với các thuộc tính mặc định của chúng:

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

4. Kết luận

Trong bài viết này, chúng ta đã tìm hiểu về sự khác biệt giữa @ComponentScan và @EnableAutoConfiguration trong Spring Boot.