Spring Boot - Một số Annotation - Phần 2
Ở phần trước chúng ta đã tìm hiểu sơ lượt một vài annotation quan trọng trong Spring Boot. Nhưng xui rủi thay mấy ông tay to và các bậc tiền bối đã tạo ra hằng hà sa số các annotation khác nhau.
Học không biết bao giờ mới hết. Chi bằng dành chút thời gian xem qua và và vấp các dự án thực tế một chút sẽ nhớ dai hơn.
Nàooo ! chuẩn bị một ít bim-bim để bắt đầu đọc tiếp thoaiii :D
9. @Bean
@Bean được dùng để định nghĩa một bean trong Spring. Mỗi khi bạn cần Spring quản lý vòng đời của một đối tượng nào đó mà không muốn dùng @Component, bạn có thể khai báo nó thông qua @Bean trong một class cấu hình.
1
2
3
4
5
6
7
8
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}
Hãy tưởng tượng @Bean giống như một đầu bếp trong nhà hàng. Bạn có thể tự định nghĩa công thức và nói với Spring: “Đây là cách tôi muốn món ăn này được chế biến!”
10. @Qualifier
Khi có nhiều hơn một bean cùng loại, Spring không biết chọn bean nào để inject vào. Đây là lúc @Qualifier phát huy tác dụng. Bạn có thể chỉ rõ bean nào cần được tiêm vào.
1
2
3
4
5
6
7
@Service
public class OrderService {
@Autowired
@Qualifier("fastDelivery")
private DeliveryService deliveryService;
}
1
2
3
4
5
6
7
8
9
10
11
@Bean
@Qualifier("fastDelivery")
public DeliveryService fastDeliveryService() {
return new FastDeliveryServiceImpl();
}
@Bean
@Qualifier("standardDelivery")
public DeliveryService standardDeliveryService() {
return new StandardDeliveryServiceImpl();
}
@Qualifier giống như khi bạn gọi taxi và có đến hai chiếc xuất hiện cùng lúc. Bạn chỉ vào chiếc có màu bạn thích và bảo: “Tôi muốn đi chiếc này!”
11. @Primary
Nếu bạn có nhiều bean cùng loại nhưng lại không muốn dùng @Qualifier mọi lúc, bạn có thể sử dụng @Primary để đánh dấu bean nào nên được chọn mặc định khi không chỉ định cụ thể.
1
2
3
4
5
6
7
8
9
10
@Bean
@Primary
public DeliveryService fastDeliveryService() {
return new FastDeliveryServiceImpl();
}
@Bean
public DeliveryService standardDeliveryService() {
return new StandardDeliveryServiceImpl();
}
Hãy tưởng tượng bạn có hai bộ quần áo, và mỗi sáng bạn phải chọn một bộ để mặc. @Primary giống như việc bạn nói với tủ quần áo: “Nếu tôi không nói gì, cứ mặc bộ này cho tôi.”
12. @Scope
Annotation @Scope được sử dụng để xác định phạm vi (scope) của một bean, nghĩa là Spring sẽ tạo ra một instance duy nhất hay nhiều instance cho mỗi yêu cầu. Các giá trị thường dùng là:
singleton: (mặc định) Một bean sẽ chỉ có một instance duy nhất trong toàn bộ ứng dụng.prototype: Mỗi lần yêu cầu, một instance mới sẽ được tạo.
1
2
3
4
5
@Bean
@Scope("prototype")
public MyService myService() {
return new MyServiceImpl();
}
@Scope giống như bạn có một chiếc bánh pizza. Nếu bạn chọn "singleton", bạn ăn một miếng và để dành phần còn lại cho những lần sau. Còn nếu bạn chọn "prototype", mỗi lần bạn gọi pizza, một chiếc mới tinh sẽ được giao tới.
13. @Lazy
Annotation @Lazy được dùng để trì hoãn việc khởi tạo bean cho đến khi thực sự cần thiết. Mặc định, Spring sẽ khởi tạo tất cả các bean ngay khi ứng dụng khởi động, nhưng với @Lazy, bean chỉ được khởi tạo khi nó thực sự được gọi.
1
2
3
4
5
6
7
@Service
@Lazy
public class ExpensiveService {
public ExpensiveService() {
// Constructor rất tốn tài nguyên
}
}
@Lazy giống như việc bạn đang ở nhà và chưa muốn mở quà sinh nhật ngay. Bạn để quà đó đến lúc nào thật sự cần, mới mở ra xem.
14. @Value
Annotation @Value được sử dụng để inject giá trị từ các file cấu hình (như application.properties hoặc application.yml) vào trong các biến hoặc phương thức của bean.
Trong file application.properties:
1
app.name=Spring Boot Awesome
Trong code:
1
2
3
4
5
6
@Value("${app.name}")
private String appName;
public void printAppName() {
System.out.println(appName); // output: Spring Boot Awesome
}
@Value giống như việc bạn đang tham dự một bữa tiệc và đột nhiên cần số điện thoại của ai đó. Thay vì hỏi từng người, bạn chỉ cần mở danh bạ ra và lấy ngay.
15. @Profile
Annotation @Profile được dùng để kích hoạt bean hoặc cấu hình chỉ trong các môi trường (profile) cụ thể. Điều này rất hữu ích khi bạn có các cấu hình khác nhau cho môi trường phát triển, thử nghiệm, và sản xuất.
1
2
3
4
5
6
7
8
9
10
11
@Profile("dev")
@Bean
public DataSource devDataSource() {
return new H2DataSource();
}
@Profile("prod")
@Bean
public DataSource prodDataSource() {
return new MySQLDataSource();
}
Hãy tưởng tượng bạn là diễn viên và có nhiều vai diễn khác nhau. @Profile giống như việc bạn thay trang phục: nếu là vai “dev”, bạn mặc bộ đồ thoải mái; nếu là vai “prod”, bạn ăn mặc chỉn chu, chuyên nghiệp.
16. @ControllerAdvice
Annotation @ControllerAdvice cho phép bạn viết mã xử lý ngoại lệ (exception handling) một cách tập trung cho tất cả các controller trong ứng dụng.
1
2
3
4
5
6
7
8
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<String> handleResourceNotFound(ResourceNotFoundException ex) {
return new ResponseEntity<>("Resource not found", HttpStatus.NOT_FOUND);
}
}
@ControllerAdvice giống như một ông thầy thuốc. Mỗi khi có ai đó trong làng gặp rắc rối (exceptipn - ngoại lệ), ông ấy đều có cách xử lý để mọi thứ trở lại bình thường.
17. @EventListener
@EventListener được dùng để lắng nghe và xử lý các sự kiện trong Spring. Khi một sự kiện được phát ra, các phương thức có @EventListener sẽ tự động được gọi để xử lý.
1
2
3
4
5
6
7
8
@Component
public class UserRegistrationListener {
@EventListener
public void onApplicationEvent(UserRegisteredEvent event) {
System.out.println("User registered: " + event.getUser().getName());
}
}
@EventListener giống như một chiếc chuông báo. Khi có ai đó nhấn chuông (phát sự kiện), nó sẽ vang lên và thông báo cho bạn biết đã có chuyện gì đó xảy ra.
18. @Scheduled
Annotation @Scheduled được sử dụng để định kỳ thực hiện một công việc nào đó. Bạn có thể thiết lập thời gian cụ thể để nó tự động chạy theo lịch.
1
2
3
4
@Scheduled(fixedRate = 5000)
public void reportCurrentTime() {
System.out.println("Current time is: " + new Date());
}
@Scheduled giống như báo thức buổi sáng. Bạn đặt giờ, và nó sẽ tự động reo lên nhắc bạn dậy, bất kể bạn có thích hay không!
18. @Async
@Async được sử dụng để chạy một phương thức nào đó không đồng bộ (asynchronous). Điều này có nghĩa là phương thức đó sẽ được thực hiện trên một thread khác, không làm gián đoạn luồng chính của ứng dụng. Điều này rất hữu ích khi bạn muốn xử lý các tác vụ nặng mà không làm ảnh hưởng đến hiệu suất.
1
2
3
4
5
6
7
8
9
@Service
public class EmailService {
@Async
public void sendEmail(String recipient, String message) {
// Giả sử việc gửi email mất nhiều thời gian
System.out.println("Sending email to " + recipient);
}
}
Hãy tưởng tượng bạn đang ăn tối tại một nhà hàng và gọi món tráng miệng. Thay vì ngồi chờ ở bàn và để món tráng miệng làm gián đoạn bữa tối của bạn, đầu bếp sẽ chuẩn bị món đó ở một khu vực khác (thread khác), và khi xong, họ sẽ mang ra mà không làm phiền đến bữa ăn chính.
Bài cũng dài rồi phải không? Gói bim-bim của bạn chắc cũng sắp hết rồi. Thôi order thêm hộp bánh tráng trộn tóp mỡ rồi đọc tiếp phần 3 nhé.
Bài viết mang tính chất “ghi chú, lưu trữ, chia sẻ và phi lợi nhuận”.
Nếu bạn thấy hữu ích, đừng quên chia sẻ với bạn bè và đồng nghiệp của mình nhé!
Happy coding! 😎 👍🏻 🚀 🔥