【MyBatis Plus】@Service标签应该放在ServiceImpl上(接口不可以实例化)

@Component****及其衍生注解(@Service/@Controller/@Repository)都不应该标注在接口上! @Service 注解要标注在 ServiceImpl(实现类)上而非 Service(接口)上,核心原因是 Spring 容器只能实例化 "具体类",无法实例化接口,且这是 Spring 依赖注入(DI)和面向接口编程的核心设计逻辑,我从「底层原理、实战意义、避坑点」三个维度讲透:

一、核心原理:Spring 容器的 "实例化规则"

  1. 接口无法被实例化Service 接口(如 UserService)只是方法定义,没有具体实现,JVM 本身就无法创建接口的对象;@Service 的本质是告诉 Spring:"把这个类实例化成 Bean,放到容器中"------ 接口连对象都创建不了,标注 @Service 毫无意义。

  2. 实现类是 "可实例化的具体类"ServiceImpl(如 UserServiceImpl)是接口的具体实现,包含方法的完整逻辑,Spring 能通过反射创建它的实例,并将实例注册到 IoC 容器中。

    举个反例(错误写法):

    复制代码
    // ❌ 错误:接口加@Service,Spring无法实例化
    @Service
    public interface UserService {
        boolean login(String username, String password);
    }
    
    // ✅ 正确:实现类加@Service,Spring能创建实例
    public class UserServiceImpl implements UserService {
        @Override
        public boolean login(String username, String password) {
            // 业务逻辑
            return true;
        }
    }

    这种写法启动时会报错:No qualifying bean of type 'UserService' available(找不到 UserService 类型的 Bean)。

二、实战意义:面向接口编程 + 依赖注入

Spring 推荐 "面向接口编程",核心流程是:

  1. 定义接口UserService 定义业务方法(规范);

  2. 实现类加 @ServiceUserServiceImpl 实现接口,加 @Service 让 Spring 实例化;

  3. 控制器注入接口

    java

    运行

    复制代码
    @RestController
    public class LoginController {
        // 注入接口(而非实现类),解耦
        @Autowired
        private UserService userService; 
    }
    • Spring 会自动找到 UserService 接口的实现类(UserServiceImpl),把容器中的实例注入到控制器;
    • 如果后续替换实现类(如 UserServiceV2Impl),只需修改实现类的 @Service,控制器代码无需改动(解耦核心)。

三、补充:为什么不能给接口加 @Service?

除了 "无法实例化",还有两个关键问题:

  1. 多实现类冲突 :如果一个接口有多个实现类(如 UserServiceImplAdminUserServiceImpl),若给接口加 @Service,Spring 无法判断该实例化哪个实现类,会报 NoUniqueBeanDefinitionException
  2. 违背设计原则 :接口是 "契约",标注 @Service 这种 "容器相关注解" 会污染接口,接口应只关注业务方法定义,和容器解耦。
相关推荐
计算机学姐19 小时前
基于SpringBoot的高校餐饮档口管理系统
java·vue.js·spring boot·后端·spring·intellij-idea·mybatis
身如柳絮随风扬21 小时前
MyBatis-Plus与PageHelper分页方案对比
mybatis
罗山仔21 小时前
【Vertx构建异步响应式reactive mybatis,mybatis-vertx-adaptor】
mybatis·orm·异步·reactive·响应式·webflux·vertx
java1234_小锋1 天前
Java高频面试题:如何编写一个MyBatis插件?
java·开发语言·mybatis
fe7tQnVan1 天前
MyBatis-动态sql与高级映射
数据库·sql·mybatis
qq12_8115175151 天前
Java Web 影城会员管理系统系统源码-SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0【含文档】
java·前端·mybatis
Java成神之路-2 天前
MyBatis 开发模式演进:原生、Spring 与 Spring Boot 整合实战(MyBatis系列2)
spring boot·spring·mybatis
taWSw5OjU2 天前
MyBatis-plus进阶之映射与条件构造器
数据库·oracle·mybatis
身如柳絮随风扬2 天前
Mybatis分页实现原理与PageHelper插件深度解析
mybatis
希望永不加班2 天前
SpringBoot 缓存注解:@Cacheable/@CacheEvict 使用
java·spring boot·spring·缓存·mybatis