@Order注解通过指定整数值控制Spring中切面、过滤器等组件的执行顺序,数值越小优先级越高、越早执行;需配合容器管理(如@Component)和相关启用配置(如@EnableAspectJAutoProxy)。

在 Spring 中,@Order 是控制多个切面(@Aspect)或过滤器(Filter、HandlerInterceptor、WebMvcConfigurer 等)执行顺序的核心注解。它的本质是为组件指定一个整数优先级值:数值越小,优先级越高,越早执行。
一、@Order 在切面(@Aspect)中的使用
当项目中存在多个切面,且它们的切入点(@Pointcut)匹配同一个方法时,执行顺序由 @Order 决定(需配合 @EnableAspectJAutoProxy(proxyTargetClass = true) 或默认配置)。
注意: 仅加 @Order 不够,切面类还必须被 Spring 容器管理(如用 @Component 或 @Configuration + @Bean 注册)。
示例:
立即学习“Java免费学习笔记(深入)”;
@Component
@Order(1)
@Aspect
public class LoggingAspect {
@Before("execution(* com.example.service.*.*(..))")
public void logBefore() {
System.out.println("【日志切面】执行前");
}
}
<p>@Component
@Order(2)
@Aspect
public class TransactionAspect {
@Around("execution(<em> com.example.service.</em>.*(..))")
public Object handleTx(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("【事务切面】开启事务");
Object result = pjp.proceed();
System.out.println("【事务切面】提交事务");
return result;
}
}此时 LoggingAspect 先于 TransactionAspect 执行(因为 1
- @Before 总是在目标方法调用前执行;
- @Around 可以控制是否真正执行目标方法;
- 若两个切面都用 @Around,则 @Order 值小的会“包裹”值大的(即外层代理)。
二、@Order 在 Web 过滤器(Filter)中的使用
Spring Boot 中自定义 Filter 时,可通过 @Order 控制其在过滤器链中的位置(如在 CharacterEncodingFilter 之前或之后)。
方式一:直接在 Filter 类上标注(需确保它被扫描到)
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
@Component
@Order(Ordered.HIGHEST_PRECEDENCE + 10) // 比最高优先级低一点
public class AuthFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
System.out.println("【鉴权过滤器】开始");
chain.doFilter(req, res);
System.out.println("【鉴权过滤器】结束");
}
}方式二:通过 @Bean 配置并指定 @Order
@Configuration
public class FilterConfig {
@Bean
@Order(2)
public FilterRegistrationBean<MyCustomFilter> myFilter() {
FilterRegistrationBean<MyCustomFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new MyCustomFilter());
registration.addUrlPatterns("/api/*");
return registration;
}
}关键点:
- Filter 的执行顺序取决于 FilterRegistrationBean 的 @Order,不是 Filter 实例本身的注解;
- Spring Boot 内置过滤器(如 CharacterEncodingFilter、HiddenHttpMethodFilter)也带默认 @Order 值,可参考 org.springframework.core.Ordered 中的常量(如 HIGHEST_PRECEDENCE = Integer.MIN_VALUE,LOWEST_PRECEDENCE = Integer.MAX_VALUE)。
三、@Order 在拦截器(HandlerInterceptor)中的使用
对于实现 HandlerInterceptor 的类,@Order 本身不生效 —— 因为拦截器需显式注册到 WebMvcConfigurer 中,顺序由注册顺序或 addInterceptors() 中的添加顺序决定。
正确做法是:在 WebMvcConfigurer 中按需调用 registry.addInterceptor(...).order(...):
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthInterceptor())
.order(1)
.addPathPatterns("/api/**");
<pre class="brush:php;toolbar:false;"> registry.addInterceptor(new LoggingInterceptor())
.order(2)
.addPathPatterns("/api/**");
}}
也可以让拦截器实现 Ordered 接口:
public class AuthInterceptor implements HandlerInterceptor, Ordered {
@Override
public int getOrder() {
return 1;
}
}然后在注册时不调用 .order(...),Spring 会自动识别。
四、常见误区与建议
-
不要混用
@Order和@Priority:后者是 JSR-330 标准,Spring 也支持,但语义略有差异(@Priority仅用于@Component类型 Bean 的注入排序,不适用于Filter或Interceptor注册)。 -
避免使用相同
@Order值:可能导致执行顺序不确定(尤其在不同包、不同配置类中)。 -
切面间依赖关系复杂时,优先考虑合并逻辑,而非强行靠
@Order控制嵌套行为,否则难以调试和维护。 - 调试技巧:启用
logging.level.org.springframework.aop=DEBUG,可看到代理链构建过程和通知(advice)的包装顺序。

















