0

Logic của `spring.config.import` & Thứ tự ưu tiên (AI Writing)

Phiên bản: Spring Boot 2.4+


1. Giới thiệu: Vấn đề & Giải pháp

Trong các dự án Microservices, việc quản lý file cấu hình (application.yml hoặc application.properties) thường trở nên phức tạp khi phải chia nhỏ cấu hình cho Database, Kafka, Redis, hoặc các môi trường khác nhau (Dev, Prod).

Từ phiên bản Spring Boot 2.4, tính năng spring.config.import được giới thiệu để giải quyết vấn đề này. Nó cho phép bạn nhúng (include) các file cấu hình khác vào ứng dụng một cách rõ ràng và mạch lạc, giống như lệnh import trong lập trình.

Cú pháp cơ bản

Bạn khai báo import ngay trong file application.yml chính:

spring:
  config:
    import:
      - classpath:database-config.yml       # Tải từ thư mục resources (trong file JAR)
      - optional:file:./secrets.properties  # Tải từ ổ đĩa (an toàn nếu thiếu file)

Các từ khóa quan trọng:

  • classpath:: Tìm file trong thư mục resources.
  • file:: Tìm file trên hệ thống tệp của máy chủ (bên ngoài ứng dụng).
  • optional:: Báo cho Spring biết rằng nếu không tìm thấy file thì hãy bỏ qua, không gây lỗi crash ứng dụng.

2. Quy tắc "Ai thắng?": Thứ tự ưu tiên (Priority)

Đây là phần quan trọng nhất gây nhầm lẫn cho nhiều lập trình viên. Khi có nhiều file cùng định nghĩa một thuộc tính (ví dụ server.port), Spring Boot chọn giá trị nào?

Quy tắc A: Thứ tự trong danh sách Import (Người đến sau thắng)

Khi bạn import một danh sách các file, Spring Boot tải tuần tự từ trên xuống dưới. File nằm sau cùng sẽ ghi đè các file nằm trước.

spring:
  config:
    import:
      - classpath:common-config.yml # (1) File này đặt port=8080
      - classpath:app-config.yml    # (2) File này đặt port=9090

👉 Kết quả: server.port sẽ là 9090 (vì file app-config.yml được tải sau).

Quy tắc B: Import so với File hiện tại (Import thắng - Mặc định)

Trong cấu trúc tài liệu đơn (Single Document), các giá trị được Import được coi là nguồn bổ sung và thường có độ ưu tiên cao hơn các giá trị viết trực tiếp trong file đó.

# application.yml
spring:
  config:
    import: classpath:external-config.yml  # Trong file này đặt port=9090

server:
  port: 8080 # Giá trị này sẽ bị file import GHI ĐÈ

👉 Kết quả: server.port9090 (giá trị từ file import thắng).


3. Giải pháp Ghi đè: Kỹ thuật Multi-Document

Làm thế nào để file application.yml hiện tại của bạn giữ quyền lực cao nhất và ghi đè lại mọi file import?

Bạn cần sử dụng Multi-Document (Đa tài liệu), chia file YAML làm 2 phần bằng dấu phân cách ---.

  • Document 1 (Trên): Chỉ dùng để kích hoạt lệnh import.
  • Document 2 (Dưới): Chứa các cấu hình ghi đè của bạn.

Tại sao nó hoạt động?

Spring Boot xử lý từ trên xuống. Nó tải xong toàn bộ Document 1 (bao gồm các file import). Sau đó, nó mới đọc Document 2. Vì Document 2 được đọc sau cùng, nó sẽ chiến thắng tất cả.

Ví dụ Thực tế

# --- DOCUMENT 1: Khu vực Import ---
spring:
  config:
    import:
      - classpath:base-config.yml
      - classpath:prod-config.yml

---

# --- DOCUMENT 2: Khu vực Ghi đè (Override) ---
# Bất kỳ giá trị nào viết ở đây sẽ là giá trị CUỐI CÙNG, bất chấp các file trên.
server:
  port: 8080
logging:
  level:
    root: DEBUG

👉 Kết quả: server.port sẽ là 8080.


4. Bảng Tóm tắt Chiến lược

Tình huống Cấu hình sử dụng Bên chiến thắng (Priority)
Import Danh sách [File A, File B] File B (File đứng sau thắng)
Import Đơn File Import vs File Hiện tại File Import thắng
Ghi đè Chủ động Dùng --- (Multi-doc) File Hiện tại (Document dưới) thắng

5. Cách kiểm tra (Debugging)

Để chắc chắn Spring Boot đang nhận cấu hình nào, bạn có 2 cách đơn giản:

Cách 1: Xem qua Log Console Bật log debug cho trình xử lý cấu hình trong file yaml:

logging:
  level:
    org.springframework.boot.context.config: DEBUG

Cách 2: Spring Boot Actuator Nếu dự án có cài thư viện Actuator, hãy truy cập endpoint sau để xem toàn bộ biến môi trường đã được giải quyết: http://localhost:8080/actuator/env


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí