Tất cả đều là chuyên biệt hóa của @Component → đều được Spring scan và tạo bean. Khác nhau ở ngữ nghĩa và tính năng bổ sung:
| Annotation | Tầng | Tính năng thêm |
|---|---|---|
@Component | Generic | Không |
@Service | Business logic | Không |
@Repository | Data access (DAO) | ✅ Exception translation |
@Controller | Web (trả về view) | ✅ Spring MVC handler |
@RestController | Web (REST API) | ✅ @ResponseBody mặc định |
@Repository
class UserRepository { // PersistenceException → DataAccessException tự động
User findById(Long id) { ... }
}
@Service
class UserService {
private final UserRepository repo;
// constructor injection
}
@RestController
@RequestMapping("/api/users")
class UserController {
private final UserService service;
}Exception translation của @Repository: Spring tự convert SQLException, HibernateException... → DataAccessException — caller không cần biết DB backend.
Best practice: dùng đúng annotation theo tầng — tăng readability và hưởng tính năng tương ứng. Đừng dùng @Component cho mọi thứ.
All are specialisations of @Component → all are component-scanned and instantiated as beans. The difference is semantics and additional features:
| Annotation | Layer | Extra feature |
|---|---|---|
@Component | Generic | None |
@Service | Business logic | None |
@Repository | Data access (DAO) | ✅ Exception translation |
@Controller | Web (returns view) | ✅ Spring MVC handler |
@RestController | Web (REST API) | ✅ @ResponseBody by default |
@Repository
class UserRepository { // PersistenceException → DataAccessException automatically
User findById(Long id) { ... }
}
@Service
class UserService {
private final UserRepository repo;
}
@RestController
@RequestMapping("/api/users")
class UserController {
private final UserService service;
}@Repository exception translation: Spring automatically converts SQLException, HibernateException… → DataAccessException — callers do not need to know the DB backend.
Best practice: use the annotation that matches the layer — improves readability and gains the corresponding features. Do not use @Component for everything.