【Spring】Service层常用注解详解

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 三层架构开发中最核心的一组注解。

相关推荐
Rain的Java大神之路18 分钟前
100 亿条数据如何快速写入 MySQL?从 231 天到 3.5 小时,我把面试官问懵了
java·后端·面试
程序猿乐锅21 分钟前
面向对象练习:图书借阅系统里的封装、抽象类与多态
开发语言·前端·数据库·后端·python·学习·1024程序员节
xyouyuweizhu26 分钟前
Java IO 流详解:流的作用、流的划分与标准输入输出流
java·python·php
利威尔xu1 小时前
Go IM 源码实战(7):断线三天重连,水位算错就漏消息
redis·后端·微服务·面试·golang
我的xiaodoujiao1 小时前
Django 权限系统项目实战详细图文教程 4--系统登录功能实现 2
后端·python·django
范同学~1 小时前
项目添加水印
java·前端·javascript
月夏1 小时前
前端第一次接自己的后端:mock 切真接口踩了 2 个坑,组件只改了一行 import
前端·后端·node.js
快乐的韭菜根根1 小时前
Slurm 指定 GPU 卡:`File=/dev/nvidiaX` 映射的坑与修复
java·服务器·网络
IT_陈寒1 小时前
React实战技巧总结:如何优雅处理复杂列表的渲染卡顿问题?
前端·人工智能·后端