เลิกใช้ @Value พร่ำเพรื่อ จัดระเบียบ Config ให้โปรด้วย Type-safe Configuration
February 03, 2026
·
2 min read
·
3 views
หนึ่งในสิ่งที่ทำให้ Code ดู "สกปรก" และดูแลยากที่สุดใน Spring Boot คือการเห็น Annotation @Value("${...}") กระจายอยู่เต็มไปหมด
Code ที่ Dev ส่วนใหญ่คุ้นเคย:
java
@Service
public class PaymentService {
@Value("${app.payment.gateway-url}")
private String gatewayUrl;
@Value("${app.payment.timeout}")
private int timeout;
@Value("${app.payment.api-key}")
private String apiKey;
@Value("${app.payment.retry-count}")
private int retryCount;
// Logic ยืดยาว...
}
ปัญหาคืออะไร? (The Impact)
Code นี้ทำงานได้ครับ แต่มันคือ ระเบิดเวลา:
- Stringly-typed: ถ้าคุณพิมพ์ Key ผิดแม้แต่ตัวเดียว (เช่น
gateway-urll) แอปจะไม่ฟ้องตอน Compile แต่จะไป Crash ตอน Runtime - Validation ยาก: ถ้าลืมใส่ค่า
timeoutในapplication.ymlหรือใส่ค่าติดลบ Code นี้ก็รับเข้ามาดื้อๆ แล้วไปพังตอนใช้งานจริง - กระจัดกระจาย: ถ้ามี 5 Services ที่ต้องใช้
gateway-urlคุณก็ต้องก๊อปปี้@Valueไปแปะทั้ง 5 ที่ วันไหนเปลี่ยน Key ก็ตามแก้กันตาแตก
ทางออก: รวมศูนย์ด้วย @ConfigurationProperties
Spring Boot สนับสนุนให้เรา Map ค่า Config จาก application.yml เข้ามาใส่ใน Java Class (POJO) โดยตรง วิธีนี้เรียกว่า Type-safe Configuration
เปลี่ยน Code เป็นแบบนี้:
1. ใน application.yml ใส่ข้อมูลไว้ประมาณนี้
yaml
# application.yml
app:
payment:
gateway-url: https://api.stripe.com
timeout: 5000
api-key: sk_test_123456
retry-count: 3
2. สร้าง Class สำหรับเก็บ Config โดยเฉพาะ:
java
@Configuration
@ConfigurationProperties(prefix = "app.payment")
@Validated // ทีเด็ดอยู่ตรงนี้!
@Data
public class PaymentProperties {
@NotBlank // บังคับว่าห้ามว่าง
private String gatewayUrl;
@Min(1000) // บังคับว่าต้องมากกว่า 1000ms
private int timeout = 5000; // set default ได้ด้วย
@NotBlank
private String apiKey;
private int retryCount;
}
3. Inject Class นี้เข้าไปใช้ใน Service แทน:
java
@Service
@RequiredArgsConstructor
public class PaymentService {
// Inject ก้อนเดียวจบ สะอาดตา
private final PaymentProperties properties;
public void process() {
// เรียกใช้แบบ Type-safe สบายใจ
String url = properties.getGatewayUrl();
int timeout = properties.getTimeout();
}
}
ความแตกต่างของผลลัพธ์ที่ได้
- Fail-Fast (พังตั้งแต่เริ่ม): ด้วย
@Validatedถ้าคุณลืมใส่ Config หรือใส่ค่าผิด Format แอปจะ Throw Error ตั้งแต่ตอน Start ทำให้เรารู้ตัวทันที ไม่ต้องรอไปพังหน้างาน - IDE Autocomplete: นี่คือ Killer Feature! เมื่อคุณประกาศ Class นี้ปุ๊บ เวลาคุณไปพิมพ์ในไฟล์
application.ymlIDE (IntelliJ/VS Code) จะเด้ง Autocomplete ให้ทันที เพราะมันรู้โครงสร้างจาก Java Class แล้ว - Refactor ง่าย: วันหนึ่งอยากเปลี่ยนชื่อ Key จาก
api-keyเป็นtokenคุณแก้ที่ Java Class จุดเดียว มันจะ Link ไปถึงทุกที่ที่เรียกใช้ ไม่ต้อง Find & Replace ให้เสียวไส้
บทสรุป
@Value เหมาะสำหรับค่าเล็กๆ น้อยๆ ที่ใช้ที่เดียว แต่สำหรับ Config ที่เป็นเรื่องเป็นราว หรือมีการจับกลุ่มกัน (เช่น Database config, Mail config, 3rd party API) การใช้ @ConfigurationProperties คือมาตรฐานที่ทำให้โปรเจกต์ของคุณดูเป็นมืออาชีพและ Robust ขึ้นทันทีครับ
No responses yet. Be the first to respond.