Site icon PlusMagi's Blog By Pitt Phunsanit

Java: error จาก bean ซ้ำ

เพื่อให้เห็นภาพรวมที่ชัดเจนก่อนจะไปลงมือเขียนสคริปต์ เราต้องเข้าใจ “กลไกการทำงาน” ของ Spring Bean และ “ลำดับการเกิดความขัดแย้ง” ในระบบที่มีความซับซ้อนสูง ( Enterprise System ) นี่คือบทความเจาะลึกทฤษฎี Bean Collision ( การชนกันของ Bean ) ใน Spring Framework ครับ


📖 เจาะลึกทฤษฎี: กลไกการจัดการ Bean และสาเหตุการเกิดข้อผิดพลาดซ้ำซ้อน

ในระบบ Spring Boot, ApplicationContext เปรียบเสมือน “ตู้เก็บของอัจฉริยะ” ที่เก็บ Object ( ซึ่งเราเรียกว่า Bean ) ไว้ให้ส่วนต่าง ๆ ของโปรแกรมเรียกใช้งาน แต่ตู้ใบนี้มีกฎเหล็กอยู่ว่า “ในหนึ่งประเภท ( Type ) หรือหนึ่งชื่อ ( ID ) ควรจะมีของเพียงชิ้นเดียวเท่านั้น”

ลำดับการสร้าง Bean ( Bean Lifecycle & Registration )

เมื่อเรา Start Application, Spring จะทำสิ่งที่เรียกว่า Component Scanning และ Configuration Parsing

  1. Scan Annotations: มองหาคลาสที่ติด @Component, @Service, @RestController
  2. Read XML Config: อ่านไฟล์ XML ( เช่น spring-jdbc-xxx.xml ที่คุณระบุใน launch.json )
  3. Process Java Config: อ่าน Method ที่ติด @Bean ในคลาส @Configuration

ทำไมถึงเกิดการ “ชนกัน” ( Conflict Scenarios )

ความผิดพลาดมักเกิดจาก 3 สถานการณ์หลัก ดังนี้


วิธีการ “ตรวจจับ” ( Identification Techniques )

ก่อนจะแก้ เราต้องรู้วิธี “บีบวง” ให้แคบลง

  1. Strict Mode ( Fail-Fast ): การตั้งค่า spring.main.allow-bean-definition-overriding=false คือการบอกระบบว่า “ถ้าเจอของซ้ำ ให้หยุดทำงานทันที” วิธีนี้ดีที่สุดในการ Debug เพราะ Log จะบอกชื่อไฟล์ทั้ง 2 จุดที่ชนกันอย่างละเอียด
  2. Context Analysis: ใช้การสแกนหาคำหลัก ( Keywords ) ในซอร์สโค้ด:
  3. หาคลาสที่ชื่อซ้ำกันในต่าง Package
  4. หา ID ที่ซ้ำกันในไฟล์ .xml
  5. หาการประกาศ @Bean ที่คืนค่า Type เดียวกัน

วิธีการ “แก้ไข” ( Resolution Strategies )

เมื่อเจอจุดที่ชนกันแล้ว เรามีกลยุทธ์การแก้ 4 ระดับ

ระดับวิธีการคำอธิบาย
1. Explicit Naming@Service("uniqueName")ระบุชื่อ Bean ให้ชัดเจน ไม่พึ่งพาระบบตั้งชื่ออัตโนมัติ
2. Primary Marking@Primaryบอกว่าถ้ามีซ้ำ ให้เลือกตัวนี้เป็นตัวหลัก ( Default )
3. Specific Wiring@Qualifier("name")ตอนเรียกใช้ ให้ระบุไปเลยว่าจะเอาตัวชื่อไหน
4. Exclusionexcludeสั่งให้ Spring ไม่ต้องสแกนใน Package หรือไฟล์ XML ที่ไม่ได้ใช้งาน

ข้อควรระวัง

ถ้าโปรเจกต์ของคุณมีการใช้ launch.json เพื่อโหลด XML หลายตัวพร้อมกัน


อ่านเพิ่มเติม

Exit mobile version