Spring Boot Service 层常用注解详解
在 Spring Boot 的三层架构中:
Controller → Service → Dao
Service 层主要负责业务逻辑处理,它通常承担以下职责:
- 业务逻辑处理
- 调用 Dao 层访问数据库
- 事务管理
- 业务组合
为了简化开发,Spring 提供了一系列用于 Service 层的注解。
本文将系统讲解:
@Service
@Transactional
@Autowired
@Resource
@Qualifier
ServiceImpl(MyBatis-Plus)
并分析 使用方式、使用场景和常见易错点。
一、@Service(Service层核心注解)
1 概念
@Service 用于标识一个类是 业务逻辑层组件。
Spring 在启动时会:
扫描 @Service
↓
创建 Bean
↓
交给 Spring 容器管理
2 使用示例
java
@Service
public class UserService {
public User getUser(Long id){
return userMapper.selectById(id);
}
}
Controller 中调用:
java
@RestController
public class UserController {
@Autowired
private UserService userService;
}
3 使用场景
用于:
业务逻辑处理类
例如:
UserService
OrderService
ProductService
4 易错点
❌ 忘记加 @Service
如果没有:
java
@Service
Spring 不会创建 Bean。
结果:
@Autowired 注入失败
报错:
NoSuchBeanDefinitionException
二、@Transactional(事务管理)
@Transactional 是 Service 层最重要的注解之一。
1 概念
@Transactional 用于 声明事务管理。
作用:
保证一组数据库操作要么全部成功,要么全部失败
2 使用示例
java
@Service
public class AccountService {
@Transactional
public void transfer(Long fromId, Long toId, int money){
accountMapper.decrease(fromId, money);
accountMapper.increase(toId, money);
}
}
如果出现异常:
自动回滚
3 常见属性
rollbackFor
默认:
只回滚 RuntimeException
推荐写法:
java
@Transactional(rollbackFor = Exception.class)
propagation(事务传播)
常见类型:
| 类型 | 说明 |
|---|---|
| REQUIRED | 默认,加入当前事务 |
| REQUIRES_NEW | 新建事务 |
示例:
java
@Transactional(propagation = Propagation.REQUIRES_NEW)
isolation(隔离级别)
用于解决并发问题。
常见:
READ_COMMITTED
REPEATABLE_READ(MySQL默认)
4 使用场景
适用于:
数据库写操作
批量操作
转账
订单创建
5 常见易错点
❌ 方法内部调用事务失效
例如:
java
public void methodA(){
methodB();
}
@Transactional
public void methodB(){}
原因:
Spring事务基于代理
内部调用不会经过代理
❌ private 方法事务失效
java
@Transactional
private void test(){}
原因:
代理无法拦截 private 方法
❌ 异常被捕获
java
@Transactional
public void test(){
try{
int a = 1/0;
}catch(Exception e){
}
}
结果:
事务不会回滚
三、@Autowired(依赖注入)
1 概念
@Autowired 用于 自动注入 Spring Bean。
例如:
java
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
}
Spring 会自动:
查找 UserMapper Bean
↓
注入到 userMapper
2 使用场景
适用于:
Service 调用 Dao
Service 调用其他 Service
3 易错点
❌ 存在多个实现类
例如:
UserServiceImpl
UserServiceImpl2
Spring 不知道注入哪个。
会报:
NoUniqueBeanDefinitionException
解决方案:
@Qualifier
四、@Qualifier(指定注入Bean)
当存在多个实现类时,需要使用:
@Qualifier
使用示例
java
@Autowired
@Qualifier("userServiceImpl")
private UserService userService;
指定:
Bean名称
五、@Resource(另一种依赖注入方式)
@Resource 是 Java 提供的注解(JSR-250)。
使用示例
java
@Resource
private UserMapper userMapper;
@Resource vs @Autowired
| 特性 | @Autowired | @Resource |
|---|---|---|
| 来源 | Spring | Java |
| 默认方式 | 按类型 | 按名称 |
| 推荐度 | 高 | 一般 |
在 Spring Boot 中:
@Autowired 使用最多
六、ServiceImpl(MyBatis-Plus)
如果项目使用 MyBatis-Plus,Service 层通常会继承:
ServiceImpl
1 概念
ServiceImpl 是 MyBatis-Plus 提供的 基础 Service 实现类。
作用:
封装通用 CRUD 方法
2 使用示例
Service 接口:
java
public interface UserService extends IService<User> {
}
Service 实现类:
java
@Service
public class UserServiceImpl
extends ServiceImpl<UserMapper, User>
implements UserService {
}
3 自动获得方法
继承后可以直接使用:
save()
getById()
list()
removeById()
updateById()
例如:
java
userService.getById(1);
4 优点
减少大量代码:
不用自己写 CRUD
七、Service层最佳实践
常见写法:
Controller
↓
Service接口
↓
ServiceImpl
↓
Mapper
示例:
UserController
UserService
UserServiceImpl
UserMapper
八、Service层注解总结
常见注解分类:
组件注解
@Service
事务管理
@Transactional
依赖注入
@Autowired
@Resource
@Qualifier
MyBatis-Plus
ServiceImpl
九、面试常见问题
1 @Service 和 @Component 区别?
答案:
@Service 是 @Component 的语义化扩展
功能一样。
2 Spring事务是如何实现的?
答案:
AOP + 动态代理
3 @Autowired 和 @Resource 区别?
@Autowired → 按类型
@Resource → 按名称
4 为什么事务一般写在Service层?
原因:
业务逻辑通常涉及多个数据库操作
例如:
创建订单
扣库存
记录日志
必须放在同一个事务中。
总结
Service 层最核心的注解包括:
@Service
@Transactional
@Autowired
@Resource
@Qualifier
如果使用 MyBatis-Plus:
ServiceImpl
这些注解主要用于:
业务组件管理
事务控制
依赖注入
数据库操作封装
也是 Spring Boot 三层架构开发中最核心的一组注解。