Spring Boot中通过继承实现基类控制器的核心是抽取通用逻辑到BaseController(如统一返回、日志、用户获取),业务抽象类(如UserBaseController)添加路径前缀和领域共用方法,具体控制器(如MemberController)加@RestController并注入业务Service复用父类能力。

在 Java 的 Spring Boot 项目中,用继承实现不同业务的基类控制器,核心思路是:**抽取通用逻辑到父类控制器,子类控制器按业务继承并扩展特有功能**。关键在于合理划分层级、避免过度抽象,同时保证 REST 接口语义清晰、参数校验和异常处理统一。
定义通用基类控制器(BaseController)
基类不直接映射请求路径,只提供共享能力,比如:
- 统一返回封装(如
Result<T>) - 通用日志记录(使用
@Slf4j或手动注入 logger) - 基础工具方法(如获取当前登录用户、生成 traceId)
- 默认分页参数解析(
@RequestParam(defaultValue = "1") int page等) - 共用的
@ExceptionHandler(放在@ControllerAdvice更推荐,但基类里放简单兜底也可)
示例:
@Slf4j
public class BaseController {
protected Result success(Object data) {
return Result.success(data);
}
protected Result fail(String msg) {
return Result.fail(msg);
}
protected Long getCurrentUserId() {
// 从 SecurityContext 或 ThreadLocal 获取
return Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication())
.map(auth -> (Long) auth.getPrincipal())
.orElse(0L);
}
}
按业务域定义抽象子控制器(如 UserController、OrderController)
这些类继承 BaseController,并添加本业务的公共路径前缀与共用逻辑,但仍保持抽象(不加 @RestController),方便进一步细化:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 用
@RequestMapping("/users")统一路径前缀 - 声明泛型 Service(如
protected UserService userService),由子类注入 - 提供本领域通用操作(如
listByStatus()、checkPermission())
示例:
public abstract class UserBaseController extends BaseController {
@Autowired
protected UserService userService;
@GetMapping("/profile")
public Result profile() {
return success(userService.getProfile(getCurrentUserId()));
}
}
具体业务控制器继承并完成实现
最终的控制器加上 @RestController 和具体路径,并注入对应 Service:
- 复用父类通用方法(如
success()、getCurrentUserId()) - 覆盖或新增业务接口(如
@PostMapping("/register")) - 可选择性重写父类方法(如对某个接口做特殊权限校验)
示例:
@RestController
@RequestMapping("/api/v1")
public class MemberController extends UserBaseController {
@Autowired
private MemberService memberService;
@PostMapping("/register")
public Result register(@Valid @RequestBody RegisterDTO dto) {
memberService.register(dto);
return success("注册成功");
}
// 复用父类的 /profile 接口,无需重复写
}
注意事项与避坑点
继承方式简洁,但容易引发耦合或误用:
-
不要在基类里写具体业务接口(如
/users/delete),应保留在具体控制器中 - Service 注入建议用 protected + @Autowired 字段注入,或构造器注入(需子类传参,稍繁琐)
-
路径前缀优先用
@RequestMapping在抽象类上声明,避免每个子类重复写/api/v1/users - 若各业务差异大,考虑用组合(如引入
CommonResponseHelper)替代深度继承 - 全局异常、参数校验、登录拦截等,更推荐用
@ControllerAdvice+@Valid+SecurityFilterChain实现,而非塞进基类

















