@component、@service、@repository本质均为@component特化,区别在于语义分层与附加能力:@component泛指通用组件;@service标识业务层,支持事务;@repository标识数据访问层,提供异常转换为dataaccessexception的能力。

在 Spring 中,@Component、@Service 和 @Repository 都是用于标识类为 Spring 管理的 Bean 的注解,它们本质都是 @Component 的特化形式,区别主要在于语义和默认行为(比如异常处理),而不是功能差异。
理解三者的语义分工
Spring 推荐按职责分层使用这些注解,让代码意图更清晰:
-
@Component:通用组件,适用于任何不属于其他三层的 Spring 管理类(如工具类、配置包装类、监听器等); -
@Service:标记业务逻辑层(Service 层)的类,通常包含事务控制、流程编排等; -
@Repository:标记数据访问层(DAO 或 Mapper 层)的类,Spring 会自动将该层抛出的数据访问异常(如 JDBC 异常、JPA 异常)转换为统一的DataAccessException子类,便于上层统一处理。
基本用法:加注解 + 开启组件扫描
只需两步即可让 Spring 管理这些类:
- 在类上添加对应注解(如
@Service); - 确保类所在包被
@ComponentScan扫描到(Spring Boot 默认扫描主启动类所在包及其子包)。
示例:
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User findById(Long id) {
return userRepository.findById(id);
}
}
@Repository
public class UserRepository {
public User findById(Long id) {
// 模拟数据库查询
return new User(id, "Alice");
}
}
只要 UserService 和 UserRepository 在 Spring Boot 主类同包或子包下,无需额外配置就能被自动注册为 Bean,并支持构造器注入。
@Repository 的异常翻译机制
这是 @Repository 独有的关键能力。当类标注了 @Repository,Spring 会在运行时识别它,并将其纳入异常翻译器(PersistenceExceptionTranslationPostProcessor)的处理范围。
这意味着:即使你用的是原生 JDBC 或 MyBatis,只要 DAO 类加了 @Repository,底层抛出的 SQLException 或 PersistenceException 就可能被自动转为 Spring 的 DataAccessException 层次结构(如 EmptyResultDataAccessException、DuplicateKeyException)。
注意:需确保项目中启用了异常翻译,Spring Boot 默认已配置;若手动配置,需添加 @EnableTransactionManagement 或注册 PersistenceExceptionTranslationPostProcessor Bean。
不强制但建议的命名与分层实践
虽然 Spring 不强制要求接口与实现分离,但常见规范如下:
- 定义
UserService接口 +UserServiceImpl实现类,后者加@Service; - DAO 层常用
UserMapper(MyBatis)或UserRepository(Spring Data JPA),实现类由框架生成,接口加@Mapper或继承JpaRepository即可,无需再加@Repository(Spring Data JPA 已自动处理); - 如果自己写 JDBC DAO 实现类,则必须加
@Repository才能启用异常翻译。
另外,可通过 @Component("xxx") 或 @Service("userServiceImpl") 自定义 Bean 名称,方便 @Autowired 时按名称注入。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











