@restcontrolleradvice 默认全局生效,但可通过自定义注解(如@businessmodule)标记控制器实现精准范围控制,或使用basepackages按包路径限定作用域,兼顾灵活性与非侵入性。

Spring 的 @RestControllerAdvice 默认作用于全局所有控制器,但结合自定义注解可实现按需、精准的异常捕获范围控制,避免“一刀切”式全局处理干扰特定业务逻辑。
自定义注解定义 Scope 语义
通过声明一个标记型注解(如 @BusinessModule),赋予其明确的模块/功能边界含义,后续用它标注需要被特定异常处理器接管的 Controller 类或方法。
- 注解需声明
@Target({ElementType.TYPE, ElementType.METHOD})支持类与方法级别 - 添加
@Retention(RetentionPolicy.RUNTIME)确保运行时可反射获取 - 不强制要求属性,纯标记用途即可;若需细分类型,可加
value()字符串字段用于分组
RestControllerAdvice 按注解筛选生效范围
在 @RestControllerAdvice 上使用 @ControllerAdvice 支持的 annotations 属性,指定仅拦截被自定义注解标记的 Controller。
- 示例:@RestControllerAdvice(annotations = BusinessModule.class) —— 只处理标有
@BusinessModule的控制器抛出的异常 - 支持多个注解:annotations = {BusinessModule.class, ApiV2.class},满足复合条件时才生效
- 注意:该筛选仅作用于 Controller 类层级;若注解只打在方法上,
annotations属性无法识别,需改用assignableTypes或 AOP 配合
配合 @ExceptionHandler 实现模块级异常策略
在限定范围的 @RestControllerAdvice 内定义 @ExceptionHandler,其处理逻辑天然只对目标模块有效,无需额外判断上下文。
- 例如:订单模块专属的
OrderValidationException只在此 Advice 中被捕获并转为 400 响应,不影响用户模块的同类异常走默认流程 - 可复用同一异常类型,靠 Advice 的作用域隔离行为,避免在每个 Controller 里重复写 try-catch 或 @ExceptionHandler
- 若需更细粒度(如仅某几个接口),可在自定义注解中加 flag 字段,并在 Handler 内通过
ReflectionUtils获取当前方法上的注解做二次判断
替代方案:基于包路径的 Scope 控制
当注解方式不够灵活(如无法修改第三方 Controller 源码),可用 basePackages 属性限定包路径范围。
- @RestControllerAdvice(basePackages = "com.example.order") —— 仅拦截该包及其子包下的 Controller 异常
- 支持数组形式:basePackages = {"com.example.order", "com.example.payment"},组合多个业务域
- 比注解更粗粒度,但无需侵入代码,适合已有项目快速收敛异常处理边界
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











