Dùng lâu nhưng bạn có phân biệt được @Component và @Bean trong Spring không?

Một trong những lợi ích quan trọng mà Spring mang lại là Dependency Injection cho phép khởi tạo và quản lý các bean tự động. Các bean được tạo ra sẽ được quản lý bởi Spring IoC container, để sử dụng, chúng ta chỉ cần khai báo các bean với @Autowired annotation, IoC sẽ tự động tìm kiếm và tiêm chúng vào class mà chúng ta cần sử dụng.

Trong Spring, để tạo ra một bean chúng ta phải thông qua 2 annotation @Bean@Component, do vậy thông thường chúng ta sẽ gặp 2 annotation này rất nhiều khi làm việc với Spring. 

Giống nhau là vậy, tuy nhiên giữa chúng có những khác biệt khá lớn mà chúng ta sẽ tìm hiểu ngay sau đây.

@Component

Là một class-level annotation. Nó yêu cầu Spring sử dụng class này để tạo một bean nếu có nơi nào khác sử dụng class này như một dependency. Việc khởi tạo class hoàn toàn do Spring kiểm soát và chỉ một bean được tạo cho mỗi class.

@Component
class UserService {
    public void updateUser(User user) {
    …
    }
}

@Controller
class UserController {
    private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }
}

Trong ví dụ trên, UserService class được chú thích với @Component do vậy nó sẽ được Spring khởi tạo và đăng ký với Application context. Khi UserController khai báo UserService là một dependency mà nó cần sử dụng, Spring sẽ tìm kiếm và tiêm một UserService instance đã được khởi tạo từ trước vào UserController để sử dụng.

@Bean

Điều đầu tiên mình nghỉ đến đó là có @Component là có thể tạo bean ngon lành cành đào rồi, thế sao lại phải sinh ra @Bean annotation chi nữa vậy ta?

Điều đầu tiên đó @Bean được sử dụng cho các hàm thay vì class như @Component, hàm này sẽ trả về một object sẽ được đăng ký và quản lý bởi Spring IoC container.

Bạn có thể sử dụng @Bean trong trường hợp bạn đang sử dụng các class thư viện bên thứ ba, lúc này bạn không thể khai báo @Component trên những class này mà bắt buộc bạn phải tạo một method trả về các instance của chúng và được chú thích bởi @Bean annotation.

Bạn phải sử dụng @Bean trong các @Configuration class để Spring có thể quét và khởi tạo các bean được khai báo bên trong.

class UserService {
    @Autowired
    private PasswordEncoder passwordEncoder 

    public String createUser(UserCreateReq req) {
        UserEntity user = UserEntity.builder()
                            .setPassword(this.encoder.encode(req.getPassword()))
                            …
                            .build();
        repo.save(user);
    }
} 

@Configuration
class PasswordEncoderConfiguration {
    @Bean
    public PasswordEncoder passwordEncoder () {
        return new BCryptPasswordEncoder();
   

Trong ví dụ trên, mình đã sử dụng BCryptPasswordEncoder bởi thư viện bên thứ 3, chính vì thế mình phải sử dụng bCryptPasswordEncoder() để khởi tạo một bean và đăng ký nó với Spring IoC.

Kết bài

Ok, hy vọng qua bài viết này các bạn có thể được ý nghĩa sâu xa bên trong cách sử dụng của 2 annotation này.

Nguồn tham khảo

https://dev.to/htintrinh/bean-and-component-what-is-the-different-which-one-should-use-be-used-3foe

https://dev.to/htintrinh/bean-and-component-what-is-the-different-which-one-should-use-be-used-3foe

Spring Framework: @Component vs @Bean Annotations

5 3 votes
Article Rating
Subscribe
Notify of
guest
3 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
3
0
Would love your thoughts, please comment.x
()
x