99 Ngày Spring — Ngày 01: Spring là gì và vì sao ra đời?
Chào mừng bạn đến với 99 Ngày Spring — series đưa bạn từ những khái niệm nền tảng nhất đến việc xây dựng và vận hành hệ thống Spring Boot production-ready. Trước khi gõ bất kỳ dòng code nào, ngày đầu tiên chúng ta cần hiểu: Spring sinh ra để giải quyết vấn đề gì, và hai khái niệm cốt lõi IoC – DI nghĩa là gì. Hiểu đúng hai điều này, 98 ngày còn lại sẽ nhẹ nhàng hơn rất nhiều.

Trước khi có Spring: vấn đề ở đâu?
Đầu những năm 2000, viết ứng dụng doanh nghiệp bằng Java EE (J2EE) là một cực hình: hàng núi file XML, code nghi thức rườm rà, và muốn test được thì phải dựng cả application server. Nhưng vấn đề sâu xa nhất nằm ở cách chúng ta tự quản lý dependency:
public class OrderService {
// Tự tạo dependency → dính chặt vào SmtpEmailService
private final EmailService email = new SmtpEmailService();
public void place(Order order) {
// ... lưu đơn hàng
email.send(order.customerEmail(), "Đặt hàng thành công!");
}
}Đoạn code trên có gì sai? OrderService tự tay new SmtpEmailService() — nó bị dính chặt (tight coupling) vào một implementation cụ thể:
Muốn đổi sang gửi email qua SendGrid? Phải sửa code của
OrderService.Muốn viết unit test? Không thể thay
emailbằng bản giả (mock) — mỗi lần test là một email thật được gửi đi!Mỗi class tự tạo dependency của mình → cả ứng dụng thành một mạng nhện không tháo rời được.
Năm 2003, Rod Johnson phát hành Spring với một ý tưởng đơn giản: để framework quản lý object thay cho bạn.
IoC — đảo ngược quyền điều khiển
Inversion of Control nghĩa là: thay vì class của bạn tự tạo và tự nối các object với nhau, quyền đó được đảo ngược — giao cho IoC Container của Spring (chính là ApplicationContext). Container sẽ:
Tạo ra các object mà ứng dụng cần — mỗi object do Spring quản lý gọi là một bean.
Nối các bean với nhau đúng theo phụ thuộc giữa chúng.
Quản lý toàn bộ vòng đời: khởi tạo → sử dụng → hủy.
Bạn có thể hình dung container như một nhà máy trung tâm: mọi class chỉ cần khai báo mình cần gì, không cần biết làm sao để tạo ra thứ đó.
DI — tiêm phụ thuộc
Dependency Injection là cách IoC được hiện thực hóa: dependency được "tiêm" vào class từ bên ngoài, thay vì class tự tạo. Cùng viết lại OrderService theo kiểu Spring:
@Servicepublic class OrderService {
private final EmailService email;
// Spring nhìn vào constructor và tự "tiêm" một EmailService vào
public OrderService(EmailService email) {
this.email = email;
}
public void place(Order order) {
// ... lưu đơn hàng
email.send(order.customerEmail(), "Đặt hàng thành công!");
}
}Chỉ một thay đổi nhỏ — nhận EmailService qua constructor — nhưng lợi ích là khổng lồ:
Lỏng lẻo đúng kiểu (loose coupling):
OrderServicechỉ biết interface, không quan tâm SMTP hay SendGrid.Dễ test: trong unit test, cứ truyền một mock
EmailServicevào constructor là xong.Dễ thay đổi: đổi implementation không cần đụng vào code nghiệp vụ.
Annotation @Service đánh dấu class này là một bean để Spring tìm thấy và quản lý — cơ chế quét (component scan) này chúng ta sẽ học kỹ ở ngày 05.
Hệ sinh thái Spring
Spring không chỉ là IoC container. Nó là cả một hệ sinh thái phủ kín mọi nhu cầu backend:
Spring Boot — khởi động dự án trong vài phút, gần như không cần cấu hình. Series này dùng Boot 3.x trên Java 21.
Spring Data — thao tác database gọn nhẹ (JPA, JDBC, Redis, MongoDB…).
Spring Security — xác thực và phân quyền.
Spring MVC / WebFlux — xây dựng web và REST API.
Spring Cloud — bộ đồ nghề cho microservices.
Đừng choáng ngợp — tất cả sẽ được học dần trong 99 ngày, và tất cả đều đứng trên nền IoC + DI bạn vừa hiểu hôm nay.
Bài tập nhỏ
Tìm trong code Java bạn từng viết (hoặc từng thấy) một chỗ
newdependency trực tiếp — chỗ đó sẽ khó test thế nào?Tự giải thích bằng lời của bạn: IoC đảo ngược cái gì? DI tiêm cái gì, vào đâu?
Kết luận
Spring ra đời để gỡ Java khỏi sự nặng nề của J2EE bằng một ý tưởng cốt lõi: container quản lý object (IoC), dependency được tiêm từ ngoài vào (DI). Ngày 02, chúng ta sẽ bắt tay vào thực hành: tạo project Spring Boot đầu tiên với Spring Initializr và chạy nó. Hẹn gặp lại!
Site Admin
Engineer and writer. Building things with TypeScript and distributed systems.
Bình luận (0)
Bạn cần đăng nhập bằng Google để bình luận.
Hãy là người bình luận đầu tiên.


