欢迎光临
我们一直在努力

Springboot项目入门笔记-3(初识接口-Service 层)

  • 理解 Service 层的作用和意义
  • 编写 Service 层代码,处理 “打招呼” 的业务逻辑
  • 在 Controller 中调用 Service 层,完成完整的请求处理流程
  • 理解 “分层开发” 的核心思想 —— 把接口的请求接收和业务逻辑分开,这是企业开发的标准做法。

核心思想先讲透

层级职责类比(生活化理解)
Controller 接收前端请求、返回响应(“前台接待”) 餐厅的服务员,只负责接单、送菜
Service 处理核心业务逻辑(“后厨加工”) 餐厅的厨师,负责做菜的核心流程

简单说:Controller 只做 “传话筒”,复杂的逻辑都交给 Service 处理,这样代码更易维护、易复用。

第一步:创建 Service 层

文件层级:

1.1 创建 Service 包(遵循分层规范)

  • 右键点击根包 com.example.demo → New → Package;
  • 输入包名 service(小写,和 controller 同级)→ 回车。
  • 编写接口方法(定义业务逻辑的 “规范”):
  • package com.example.demo.service;

    // 业务接口:定义“打招呼”的业务规范
    public interface HelloService {
    // 无参数打招呼
    String sayHi();

    // 给用户打招呼(带参数)
    String sayHiToUser(String name);

    // 给客户打招呼(带参数)
    String sayHiToCustomer(String name);
    }

    1.2 创建 Service 接口

    企业开发中,通常先写接口再写实现类,便于后续扩展(比如多套业务逻辑):

  • 右键点击 service 包 → New → Java Class;
  • 输入类名 HelloService,选择 Interface(接口)→ 回车;
  • 编写接口方法(定义业务逻辑的 “规范”):
  • package com.example.demo.service;

    import org.springframework.stereotype.Service;

    // ★ 核心注解:@Service
    // 作用:告诉 Spring “这是一个业务层组件”,会被自动管理(放入 Spring 容器)
    @Service
    public class HelloServiceImpl implements HelloService {

    // 实现“无参数打招呼”的业务逻辑
    @Override
    public String sayHi() {
    // 这里可以写复杂逻辑:比如拼接时间、调用其他服务、计算等
    return "你好!这是 Service 层处理的响应 🎯";
    }

    // 实现“给用户打招呼”的业务逻辑
    @Override
    public String sayHiToUser(String name) {
    // 业务逻辑1:空值处理
    if (name == null || name.isEmpty()) {
    name = "陌生人";
    }
    // 业务逻辑2:模拟复杂处理(比如拼接业务标识)
    String businessId = "USER_" + System.currentTimeMillis();
    return "【" + businessId + "】你好," + name + "!Service 层已处理你的请求";
    }

    // 实现“给客户打招呼”的业务逻辑
    @Override
    public String sayHiToCustomer(String name) {
    // 业务逻辑:空值处理 + 客户专属文案
    if (name == null || name.isEmpty()) {
    name = "陌生的客人";
    }
    return "【客户专属】Hello," + name + "!你的请求已由 Service 层处理完成";
    }
    }

    第二步:修改 Controller 层(调用 Service)

    把 Controller 里的业务逻辑删掉,改为调用 Service 层,让 Controller 只做 “请求转发”:

    package com.example.demo.controller;

    import com.example.demo.service.HelloService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;

    @RestController
    @RequestMapping("/hello")
    public class HelloController {

    // ★ 核心步骤1:注入 Service 组件
    // @Autowired:Spring 自动从容器中找到 HelloService 实现类,赋值给这个变量
    @Autowired
    private HelloService helloService;

    // 调用 Service 处理无参数请求
    @GetMapping("/hi")
    public String sayHi() {
    // 不再写业务逻辑,直接调用 Service
    return helloService.sayHi();
    }

    // 调用 Service 处理用户请求
    @GetMapping("/user")
    public String sayHiToUser(String name) {
    return helloService.sayHiToUser(name);
    }

    // 调用 Service 处理客户请求
    @GetMapping("/customer")
    public String sayHiToCustomer(String name) {
    return helloService.sayHiToCustomer(name);
    }
    }

    核心代码解释

  • @Autowired:Spring 的 “依赖注入” 注解,不用自己 new HelloServiceImpl(),Spring 会自动创建对象并赋值,这是 Spring 的核心特性;
  • Controller 里只保留接口映射,所有业务逻辑都交给 Service,代码更简洁、职责更清晰。
  • 第三步:测试运行(验证 Service 层是否生效)

    3.1 重启项目

    修改代码后,必须重启 DemoApplication(点击 IDEA 顶部的重启按钮)。

    3.2 测试接口(查看 Service 处理结果)

    接口地址预期结果(示例)
    localhost:8081/demo/hello/hi 你好!这是 Service 层处理的响应 🎯
    localhost:8081/demo/hello/user?name=小明 【USER_1740123456789】你好,小明!Service 层已处理你的请求
    localhost:8081/demo/hello/customer?name=李总 【客户专属】Hello,李总!你的请求已由 Service 层处理完成

    tips:进阶知识点(可选,企业开发常用)

    1. 为什么要写 Service 接口?

    • 便于扩展:比如后续要加 “VIP 客户打招呼逻辑”,只需新建 VipHelloServiceImpl 实现 HelloService,不用改 Controller 代码;
    • 便于测试:单元测试时可以用 Mock 模拟 Service 接口,不依赖真实逻辑。

    2. 依赖注入的另一种写法(更规范)

    // 推荐写法:构造器注入(避免空指针,更易测试)
    @RestController
    @RequestMapping("/hello")
    public class HelloController {

    private final HelloService helloService;

    // 通过构造器注入,替代 @Autowired 字段注入
    public HelloController(HelloService helloService) {
    this.helloService = helloService;
    }

    // 接口方法不变…
    }

    在service包中为什么要用interface 而不用class

    public interface HelloService {
    // 无参数打招呼
    String sayHi();

    // 给用户打招呼(带参数)
    String sayHiToUser(String name);

    // 给客户打招呼(带参数)
    String sayHiToCustomer(String name);
    }为什么这里是interface而不是class

            这里用 interface(接口)而不是 class(类),本质是为了遵循面向接口编程的设计思想,这是 Java 开发(尤其是 Spring 生态)中最核心的最佳实践之一。用 “生活化例子 + 代码对比” 的方式,让你彻底理解背后的原因。

    先用生活化例子理解:接口 = “规范 / 合同”

    假设你开了一家餐厅,需要招聘 “厨师”:

    • 接口(interface):就是 “厨师岗位规范”—— 规定厨师必须会做 3 件事:做主食、做热菜、做汤(只定义 “要做什么”,不定义 “怎么做”);
    • 类(class):就是具体的厨师 —— 比如 “川菜厨师”“粤菜厨师”,他们都遵守 “厨师规范”,但做同一道菜的方法完全不同(实现 “怎么做”)。

    对应到我们的代码:

    • HelloService 接口:定义了 “打招呼业务” 的规范(要实现 sayHi、sayHiToUser、sayHiToCustomer 三个方法);
    • HelloServiceImpl 类:是这个规范的具体实现(定义每个方法具体返回什么内容)。

    为什么不用 class 直接写?(对比说明)

    如果直接写 class HelloService,虽然能实现功能,但会有两个致命问题:

    问题 1:代码耦合度高,无法灵活替换逻辑

    假设你后续想加 “VIP 客户专属打招呼逻辑”:

    • 用 interface:只需新建 VipHelloServiceImpl 实现 HelloService,Controller 完全不用改(因为 Controller 依赖的是 HelloService 接口,不是具体的实现类);

    // 新增VIP实现类,不改动原有代码
    @Service("vipHelloService")
    public class VipHelloServiceImpl implements HelloService {
    @Override
    public String sayHi() { return "VIP专属问候!"; }
    @Override
    public String sayHiToUser(String name) { return "VIP你好," + name; }
    @Override
    public String sayHiToCustomer(String name) { return "VIP客户你好," + name; }
    }

    • 用 class:必须修改原有 HelloService 类的代码,容易引入 bug,也违反 “开闭原则”(对扩展开放,对修改关闭)。
    问题 2:无法实现多态,不利于测试和扩展

    Java 是单继承的(一个类只能继承一个父类),但可以实现多个接口。如果 HelloService 是 class,后续想让它同时遵守 “日志规范”“权限规范” 就会受限;而接口可以让一个类同时实现多个规范,比如:

    // 一个实现类可以同时遵守多个接口规范
    public class HelloServiceImpl implements HelloService, LogService, AuthService {
    // 实现所有接口的方法
    }

    问题 3:不符合 Spring 生态的最佳实践

    Spring 框架的核心(依赖注入、AOP、事务管理)都是基于接口设计的:

    • Controller 中注入的是 HelloService 接口,Spring 可以灵活切换不同的实现类(比如开发环境用测试实现,生产环境用正式实现);
    • 如果直接用 class,Controller 会和具体实现强绑定,失去 Spring 依赖注入的灵活性。
    赞(0)
    未经允许不得转载:171主机测评 » Springboot项目入门笔记-3(初识接口-Service 层)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址