Hãy nói em có một lớp UserService thế này:
public class UserService {
public User getUserById(long userId) {
// trả về user theo id
}
}
Tiếp theo chúng ta sẽ có một lớp là UserController để xử lý yêu cầu lấy thông tin người dung, Nếu bây giờ không sử dụng singleton thì mã nguồn sẽ như sau:
public class UserController {
@GetMapping("/users/{userId}")
public User getUserById(@PathVariable long userId) {
UserService service = new UserService();
return userService.getUserById(userId);
}
}
Trên thực tế trong một thời điểm UserController
có thể phải xử lý rất nhiều yêu cầu, vậy mỗi yêu cầu lại sinh ra một đối tượng UserService
, điều này làm tăng bộ nhớ cần tạo, ngoài ra gây ra tình trạng cấp, giải phóng bộ nhớ liên tục sẽ làm tiêu tốn cả tài nguyên CPU nữa.
Ngoài ra trên thực thế lớp UserService
có thể phụ thuộc vào các lớp khác như UserRepository
, như vậy thì việc khởi tạo sẽ cực kỳ phức tạp. Như vậy cần thiết phải sử dụng singleton để khởi tạo duy nhất một đối tượng cho lớp UserService
để tiết kiệm tài nguyên, đồng thời cũng dễ dàng hơn trong việc khởi tạo các lớp phụ thuộc lẫn nhau, giải phóng lập trình viên khỏi việc khởi tạo các đối tượng để xử lý.
Spring sử dụng reflection để quét các lớp trong package được chỉ định, sau đó cũng khởi tạo và inject các đối tượng phụ thuộc sử dụng reflection. Để tìm hiểu sâu vào bên trong thì chỉ có đọc source code của spring-context thôi em ạ.