Annotation @Conditional trong Spring

Khi làm việc với các ứng dụng có sử dụng Spring framework, các bạn sẽ cần biết cách khai báo và sử dụng các Bean trong Spring container. Thông thường, chúng ta chỉ cần khai báo Bean cho một class nào đó thì Spring sẽ tự động tạo Bean cho class đó trong Spring container. Nhưng trong 1 số trường hợp, chúng ta sẽ có nhu cầu là: mặc dù chúng ta có khai báo Bean cho một class, nhưng chúng ta chỉ muốn Spring tạo Bean cho class đó trong một số điều kiện cụ thể mà thôi. Để làm được điều này, các bạn có thể sử dụng annotation @Conditional. Bean được khai báo cùng với annotation @Conditional sẽ chỉ được khởi tạo nếu một điều kiện nào đó được thoả mãn, ví dụ như có một Bean khác đã được khởi tạo trong Spring container chẳng hạn… Cụ thể như thế nào? Chúng ta sẽ cùng nhau tìm hiểu về annotation @Conditional này trong bài viết này các bạn nhé!

Ví dụ mình có 2 class đơn giản như sau:

và:

Để cấu hình bean cho các class trên trong Spring container, mình sẽ định nghĩa một class được annotate với annotation @Configuration như sau:

Lúc này, nếu các bạn lấy thông tin Student được định nghĩa trong Spring container:

thì các bạn sẽ thấy kết quả như sau:

Nếu bây giờ mình muốn bean của class Student chỉ được khởi tạo trong Spring container nếu một điều kiện nào đó được thoả mãn thì mình có thể annotate method tạo bean của class Student trong class ApplicationConfiguration với annotation @Conditional.

Annotation @Conditional này có một thuộc tính là danh sách các class implement interface Condition. Để thể hiện điều kiện được thoả hay không thoả, interface Condition định nghĩa một abstract method matches với kiểu dữ liệu trả về là boolean.

Bây giờ, mình sẽ thử thêm mới một class implement interface Condition và đơn giản là return false để thể hiện là điều kiện không thoả, như sau:

Tuỳ nhu cầu, các bạn có thể implement phương thức matches() cho phù hợp nhé!

Khai báo annotation @Conditional với class ConditionalImpl này với phương thức student() trong class ApplicationConfiguration:

rồi chạy lại ví dụ, các bạn sẽ thấy lỗi “No bean named ‘student’ available” như sau:

Vì điều kiện để tạo bean Student không thoã nên bean Student không được tạo đó các bạn! Nếu các bạn đổi giá trị return của phương thức matches() trong class ConditionalImpl thành true:

thì sẽ không còn lỗi gì nữa!… Thử đi các bạn!

Nếu có nhiều điều kiện được áp dụng cho việc khởi tạo một bean trong Spring container, ví dụ mình có một class khác implement interface Condition như sau:

các bạn có thể khai báo thành danh sách các điều kiện như sau:

Trong trường hợp này, bean của class Student chỉ được khởi tạo nếu tất cả các điều kiện đều thoả. Nghĩa là, phương thức matches() trong các class này đều return true nhé các bạn!

Cho ví dụ của mình thì vì phương thức matches() trong class AnotherConditionalImpl return false nên các bạn cũng sẽ thấy lỗi không tìm thấy bean của class Student như trên.

Nếu các bạn muốn áp dụng điều kiện cho toàn bộ bean trong class được khai báo với annotation @Configuration, các bạn có thể annotate annotation @Conditional ở level class như sau:

Lúc này, các bạn sẽ thấy bean của class Clazz cũng không được khởi tạo trong Spring container luôn, vì 1 trong 2 điều kiện của chúng ta không thoả, Nếu mình chạy đoạn code lấy bean của class Clazz như sau:

các bạn sẽ thấy bị lỗi:

Add Comment