接口是多层架构中明确职责边界、切断硬依赖的关键工具:Controller 仅依赖 Service 接口,Service 仅依赖 Dao 接口,配合 Spring IOC/DI 实现松耦合,严禁跨层调用与手动 new 实例。

接口在多层架构中不是“用来写代码的装饰”,而是明确职责边界、切断硬依赖的关键设计工具。核心在于:上层只依赖下层的接口,不关心具体实现类是谁,也不直接 new 实例。
Controller 层只面向 Service 接口编程
Controller 不该知道业务逻辑怎么算、事务怎么管,它只调用 Service 定义好的契约方法。
- 定义
UserService接口(比如有getUserById(Long id)方法),不写实现 - Controller 中用
@Autowired private UserService userService;注入——注入的是接口类型,Spring 自动找匹配的 Bean - 即使后续把用户查询从 MySQL 换成 Redis 或远程 HTTP 调用,只要新实现类也实现了
UserService,Controller 一行代码都不用改
Service 层只面向 Dao 接口编程
业务逻辑不该掺杂 SQL 或 JDBC 细节,它只说“我要查用户”,不指定怎么查。
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 定义
UserMapper或UserRepository接口(如selectById(Long id)) - Service 实现类里通过
@Autowired private UserMapper userMapper;获取数据能力 - DAO 的具体实现(比如 MyBatis 的 XML 映射、JPA 的
@Repository类)对 Service 是透明的;测试时还能轻松 mock 掉 DAO,专注验证业务规则
接口 + 实现分离,让每层真正“松绑”
光有接口没用,必须配合 Spring 的 IOC 和 DI 才能落地解耦效果。
- 所有 Service 和 Dao 的实现类都用
@Service/@Mapper/@Repository标注,交给 Spring 管理 - 避免在代码里写
new UserServiceImpl()或new JdbcUserDao()—— 这种 new 操作等于手动绑定,彻底破坏解耦 - 接口方法签名要稳定:比如参数用 DTO 或 VO,返回用统一 Result 包装,不暴露 Entity 给 Controller,进一步隔离变化
额外但关键的一点:别跨层调用
Controller 直接调 Dao、Service 手动 new Controller,这类操作会让分层形同虚设。
- Controller → 只能调 Service
- Service → 只能调 Dao(或其它 Service,但需是接口)
- Dao → 不得调用 Service 或 Controller,它只做数据动作,不碰业务和协议
- 如果某处需要“Controller 传参给 Dao”,说明中间缺了 Service 做转换——参数校验、字段映射、权限判断这些事,就该在 Service 层完成
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










