นี่คือสคริปต์ที่รวมการ เช็ค Bean ชนกัน เข้ากับโครงสร้างแบบวนลูปทุก Sub-directory จะช่วยให้สคริปต์ยืดหยุ่นมาก ไม่ว่าคุณจะย้ายโปรเจกต์ไปไว้ที่ไหนก็ยังใช้งานได้
check-beans-all-repos.sh
#!/bin/bash
echo "🚀 Starting Advanced Bean Collision Check..."
echo "Location: $(pwd)"
echo "--------------------------------------------------"
for dir in */; do
dirname=${dir%/}
if [ -d "$dir" ] && [ "$dirname" != "target" ]; then
echo "📂 Processing: $dirname"
# 1. Identify Duplicate Class Names and Analyze Bean Status
find "$dir" -name "*.java" -not -path "*/target/*" | xargs basename 2>/dev/null | sort | uniq -d | while read -r fileName; do
className="${fileName%.java}"
echo " 🔍 Analyzing Duplicate Class: [$className]"
# Find all paths for this class name
find "$dir" -name "$fileName" -not -path "*/target/*" | while read -r filePath; do
# Check for Spring Annotations
annotation=$(grep -E "@Component|@Service|@RestController|@Repository|@Configuration" "$filePath")
if [ -z "$annotation" ]; then
echo " ⚪ POJO: $filePath (Not a Spring Bean)"
else
# Extract Bean Name from annotation if exists, e.g., @Component("myBean")
specificName=$(echo "$annotation" | sed -n 's/.*("\([^"]*\)").*/\1/p')
if [ -z "$specificName" ]; then
# Spring default: class name with first letter lowercase
defaultBeanId="$(tr '[:upper:]' '[:lower:]' <<< ${className:0:1})${className:1}"
echo " ✅ Spring Bean (Default Name): $defaultBeanId"
echo " Path: $filePath"
else
echo " 🆔 Spring Bean (Named): $specificName"
echo " Path: $filePath"
fi
fi
done
echo ""
done
# 2. Check for Duplicate Bean IDs in XML files (Direct Collision)
grep -r "id=" "$dir" --include="*.xml" -not -path "*/target/*" 2>/dev/null | sed -n 's/.*id="\([^"]*\)".*/\1/p' | sort | uniq -d | while read -r beanId; do
echo " ❌ FATAL: Duplicate XML Bean ID: [$beanId]"
grep -r "id=\"$beanId\"" "$dir" --include="*.xml" -not -path "*/target/*" | sed 's/^/ 📍 /'
done
fi
done
echo "--------------------------------------------------"
echo "✅ All checks completed."
วิธีนำไปใช้
- วางไฟล์: นำสคริปต์นี้ไปวางไว้ที่ root projct
check-beans-all-repos.sh - ให้สิทธิ์รัน:
chmod +x check-beans-all-repos.sh - การรัน:
./check-beans-all-repos.sh
จุดเด่นของสคริปต์นี้
- ไม่ต้องระบุ Path ตายตัว: มันจะทำงานกับทุกโฟลเดอร์ที่อยู่รอบตัวมัน
- เจาะลึก 3 ระดับ: เช็คทั้ง Class ซ้ำกันเอง, XML ซ้ำกันเอง และ Java ชนกับ XML ( ซึ่งเป็นปัญหาหลักในโปรเจกต์ )
- Context Awareness ( เข้าใจบริบท ): สคริปต์ไม่ได้หาแค่ชื่อไฟล์ที่ซ้ำกัน แต่มัน “อ่าน” เข้าไปถึง Annotation (
@Component,@Service) เพื่อประเมินสถานะความเป็น Bean - Naming Strategy Analysis: สคริปต์ตรวจสอบว่ามีการใช้ “ชื่อเฉพาะ” หรือไม่ ซึ่งเป็นจุดตัดสินว่า Application จะ “รันผ่าน” หรือ “Crash”
- Named Bean: รันผ่าน ✅
- Default Bean: มีโอกาสพัง ⚠️ ( ถ้าชื่อคลาสซ้ำกัน )
- POJO Filtering: ช่วยคัดกรอง Class ที่ซ้ำกันแต่ไม่เกี่ยวข้องกับ Spring Context ( เช่นไฟล์
.TOหรือ.DTO) ทำให้คุณไม่ต้องเสียเวลาไปไล่แก้จุดที่ไม่มีผลกระทบต่อระบบ - XML Integration: ไม่ลืมที่จะเช็คไฟล์ XML Configuration ซึ่งมักเป็น “จุดบอด” ที่ทำให้เกิด Bean ชนกันในระบบ Enterprise
- รองรับ Multi-module: เหมาะมากกับโครงสร้างโปรเจกต์ที่มีหลาย Repo แยกกันแต่อาจจะมีการใช้ชื่อคลาสหรือ Bean ID ซ้ำกันได้
สรุปการแสดงผลของสคริปต์ ( Logic Check )
| ผลลัพธ์ใน Terminal | ความหมายทางเทคนิค | สถานะความปลอดภัย |
⚪ POJO: [Path] | Class Name Collision เท่านั้น ( ไม่ใช่ Bean ) | ปลอดภัย ✅ ( แต่โค้ดอาจจะดูน่าสับสน ) |
🆔 Spring Bean (Named): [Name] | ชื่อคลาสซ้ำแต่ตั้งชื่อ Bean แยกกันไว้แล้ว | ปลอดภัย ✅ ( Spring แยกแยะได้ ) |
✅ Spring Bean (Default Name) | มีโอกาสชนกันสูงมาก ถ้ามี 2 ไฟล์ขึ้นไปที่เป็น Default เหมือนกัน | อันตราย ⚠️ ( ต้องรีบเช็ค ) |
❌ FATAL: Duplicate XML Bean ID | มีการตั้ง ID ในไฟล์ XML ซ้ำกัน | พังแน่นอน ❌ ( ต้องแก้ทันที ) |
ข้อควรระวัง: ก่อนแก้ไขไฟล์ตามที่สคริปต์ตรวจพบ อย่าลืม Backup หรือทำ Snapshot Config เพราะการเปลี่ยนชื่อ Bean ID ในที่หนึ่ง อาจส่งผลกระทบต่อ Module อื่นที่เรียกใช้งานอยู่ได้ครับ!
อ่านเพิ่มเติม