Spring Boot bài 04: Kiến trúc Controller–Service–Repository và cấu hình profile
- 18-10-2026
- Toanngo92
- 0 Comments
Giáo trình Spring Boot MVC và REST API · Chương 2/12: Bean, kiến trúc và cấu hình · Bài 04/28 · Biên soạn tháng 10/2026.
Mục lục
Mục tiêu bài học
Chia trách nhiệm theo tầng, đọc cấu hình từ môi trường và dùng profile mà không đưa bí mật vào nguồn.
Một yêu cầu không nên làm mọi việc trong Controller
Controller nhận dữ liệu HTTP, gọi nghiệp vụ và quyết định trả template, redirect hay JSON. Service thực hiện quy tắc nghiệp vụ và xác định biên giao dịch. Repository truy xuất dữ liệu. Entity mô tả dữ liệu được quản lý bởi JPA; DTO mô tả dữ liệu ứng dụng muốn chuyển ra ngoài.
Trong HVC Academy, CourseWebController và CourseApiController cùng gọi CourseService. Nhờ vậy quy tắc kiểm tra danh mục tồn tại, sửa thông tin khóa học hay xóa dữ liệu không phải viết lại cho hai loại giao diện. Không có yêu cầu phải tạo interface cho mọi Service; thêm trừu tượng khi có nhu cầu thay thế thực sự, không chỉ để tăng số tệp.
Cấu hình thuộc về môi trường
Tên cơ sở dữ liệu, mật khẩu, địa chỉ dịch vụ ngoài và nơi lưu tệp có thể khác giữa máy học và máy triển khai. application.properties chứa cấu trúc và giá trị mặc định phù hợp cục bộ. Placeholder ${…} lấy giá trị môi trường; placeholder không có mặc định sẽ buộc môi trường cung cấp cấu hình đó.
AppSettings gom cấu hình hvc thành một record có kiểu cụ thể, thay vì rải nhiều chuỗi @Value trong mọi class. @ConfigurationProperties kết hợp @Validated giúp lỗi thiếu cấu hình xuất hiện ngay lúc khởi động. Đây cũng là lý do không nên xóa validation chỉ để ứng dụng chạy qua màn hình lỗi đầu tiên.
Tệp trong mã nguồn mẫu: src/main/java/com/hocvietcode/academy/AppSettings.java. Đoạn dưới được trích từ tệp này; xem bản tải về để có đủ import và phần còn lại.
package com.hocvietcode.academy;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;
import jakarta.validation.constraints.*;
import java.nio.file.Path;
import java.net.URI;
@Validated @ConfigurationProperties(prefix="hvc")
public record AppSettings(@NotBlank @Size(min=12) String demoPassword,@NotNull Path uploadDir,@NotNull URI externalBaseUrl,boolean remindersEnabled,@NotBlank String allowedOrigin) {}
Dùng profile MySQL
application-mysql.properties chỉ ghi phần khác với cấu hình chung. Khi bật profile mysql, các thuộc tính trong đó được dùng để kết nối MySQL; những phần chung như kích thước upload vẫn được kế thừa. Profile không phải biện pháp giữ bí mật: một mật khẩu viết trực tiếp trong tệp profile vẫn là mật khẩu đã nằm trong nguồn.
Tệp trong mã nguồn mẫu: src/main/resources/application-mysql.properties. Đoạn dưới được trích từ tệp này; xem bản tải về để có đủ import và phần còn lại.
spring.datasource.url=${HVC_DB_URL}
spring.datasource.username=${HVC_DB_USER}
spring.datasource.password=${HVC_DB_PASSWORD}
spring.jpa.hibernate.ddl-auto=validate
Đặt SPRING_PROFILES_ACTIVE=mysql cùng HVC_DB_URL, HVC_DB_USER, HVC_DB_PASSWORD trước khi chạy. Bài 13 hướng dẫn chuẩn bị database và kiểm tra migration. Không bật mysql nếu chưa có máy chủ tương ứng. Cấu hình test trong src/test/resources chỉ dùng khi chạy test và không được đóng gói làm cấu hình runtime.
Theo dấu luồng dữ liệu
Ví dụ POST thêm khóa học đi từ CourseForm đã bind dữ liệu đến Controller kiểm tra validation, Service tìm Category, Repository lưu Course và cuối cùng trả DTO. Với MVC, Controller redirect về danh sách; với API, nó trả 201 cùng JSON. Tầng dưới không cần biết request đến từ HTML hay Postman.
Khi debug, đặt breakpoint ở đầu Controller và đầu Service để quan sát giá trị đã bind. Log nên ghi sự kiện, mã đối tượng và nguyên nhân có ích, tránh ghi mật khẩu, cookie hay toàn bộ nội dung tệp người dùng. Không cần bật SQL debug trong mọi môi trường chỉ để xác nhận một request đã chạy.
Lỗi thường gặp và lưu ý
- Không trộn truy vấn SQL, xử lý HTTP và gửi email vào cùng một phương thức Controller.
- Profile chỉ chọn cấu hình, không tự tạo MySQL hay cấp quyền cho tài khoản DB.
Ghi nhớ
Kiến trúc giúp hai giao diện dùng chung nghiệp vụ; cấu hình có kiểu và profile giúp cùng mã nguồn chạy ở nhiều môi trường.

