Backend

99 Ngày Spring — Ngày 01: Spring là gì và vì sao ra đời?

SSite Admin
29 tháng 07, 2026 4 phút đọc 189 lượt xem
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 IoCDI 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.

Sketchnote Ngày 01: Spring là gì? IoC và DI

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 email bằ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): OrderService chỉ biết interface, không quan tâm SMTP hay SendGrid.

  • Dễ test: trong unit test, cứ truyền một mock EmailService và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ỗ new dependency 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!

S

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.

Bài viết liên quan

99 Ngày Spring — Ngày 14: Bean Validation — @Valid & bộ constraint chuẩn

Ngày 14 của 99 Ngày Spring: Bean Validation khai báo luật ngay trên DTO — @Valid kích hoạt, bộ constraint chuẩn (@NotBlank vs @NotEmpty vs @NotNull, @Size, @Email, @Min/@Max), bẫy int vs Integer, validate object lồng nhau không tự lan, và lỗi 400 gom một lượt.

10 thg 8, 20265 phút0
99 Ngày Java — Ngày 14: Kế thừa (Inheritance)

Ngày 14 của 99 Ngày Java: extends trao gia tài từ lớp cha, override với @Override và super., thứ tự khai sinh cha trước con sau qua super(...), protected trả nợ Ngày 13, và phép thử is-a vs has-a — khi nào nên composition thay vì kế thừa.

10 thg 8, 20266 phút0
99 Ngày Spring — Ngày 13: @RequestBody & DTO — đừng công khai entity ra API

Ngày 13 của 99 Ngày Spring: @RequestBody + Jackson deserialize JSON thành object, DTO là hợp đồng API — chặn lỗ hổng mass assignment chiều vào và rò rỉ dữ liệu chiều ra, request/response DTO khác nhau là bình thường, và Jackson annotations tinh chỉnh hợp đồng JSON.

9 thg 8, 20266 phút9