Tuỳ chỉnh chiến lược đặt tên Bean trong Spring bằng chú thích

Trong phát triển ứng dụng Spring, việc sử dụng các chú thích như @Controller, @Service, @Repository hay @Mapper giúp tự động đăng ký các lớp vào контainer Bean một cách thuận tiện. Tuy nhiên, khi nhiều module chứa các lớp trùng tên, hệ thống có thể gặp xung đột do Spring mặc định lấy tên lớp (viết thường chữ đầu) làm tên Bean.

Ví dụ, hai controller cùng tên ImageController nằm ở các package khác nhau:

io.renren.modules.swr.controller.ImageController
io.renren.modules.db.controller.ImageController

Khi khởi động ứng dụng, lỗi sau sẽ xảy ra:

org.springframework.context.annotation.ConflictingBeanDefinitionException: 
Annotation-specified bean name 'imageController' for bean class [io.renren.modules.swr.controller.ImageController] 
conflicts with existing, non-compatible bean definition of same name and class [io.renren.modules.db.controller.ImageController]

Lỗi này cho thấy Spring không thể phân biệt hai Bean do tên định danh bị trùng. Để giải quyết vấn đề này, ta cần thay đổi chiến lược đặt tên Bean.

Giải pháp 1: Đặt tên Bean tùy chỉnh qua tham số chú thích

Các chú thích như @Component, @Controller, @Service, @Repository đều hỗ trợ truyền vào một giá trị chuỗi để đặt tên Bean theo ý muốn:

@Controller("dbImageController")
public class ImageController { ... }

@Service("dbImageService")
public class ImageService { ... }

@Repository("dbImageDao")
public class ImageDao { ... }

Bằng cách này, mỗi Bean sẽ có tên định danh duy nhất trong context, tránh được xung đột.

Giải pháp 2: Xử lý xung đột alias trong MyBatis

Nếu các thực thể Entity cũng trùng tên, ví dụ:

io.renren.modules.swr.entity.ImageEntity
io.renren.modules.db.entity.ImageEntity

MyBatis sẽ báo lỗi do tự động tạo alias trùng:

Caused by: org.apache.ibatis.type.TypeException: 
The alias 'ImageEntity' is already mapped to the value 'io.renren.modules.swr.entity.ImageEntity'.

Để khắc phục, dùng chú thích @Alias để đặt tên rút gọn duy nhất cho từng Entity:

@Alias("SwrImageEntity")
public class ImageEntity { ... }

@Alias("DbImageEntity")
public class ImageEntity { ... }

Lưu ý rằng @Alias phải được quét đúng cách — bạn nên cấu hình package scan cho MyBatis để nhận diện các alias này. Trong file cấu hình (thường là mybatis-plus.configuration.type-aliases-package), thêm đường dẫn đến các lớp Entity.

Kết luận

Việc quản lý tên Bean và type alias là yếu tố quan trọng khi thiết kế hệ thống module hóa. Thay vì đổi tên lớp — điều có thể ảnh hưởng đến cấu trúc dự án — việc tuỳ chỉnh tên thông qua chú thích là phương pháp linh hoạt và rõ ràng hơn. Kiến thức không quá phức tạp, nhưng kinh nghiệm xử lý lỗi mới là điểm then chốt giúp kỹ sư phát triển vững vàng.

Thẻ: Spring Bean naming @Component @Service @Controller

Đăng vào ngày 20 tháng 7 lúc 19:05