@Order详解 | Spring
@Order注解详解
先说结论:
在@Order注解中,值越小优先级越高,越先执行。
默认值Integer.MAX_VALUE
一、基本用法
// 值小的先执行
@Order(1)
public class FirstFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {System.out.println("First Filter");chain.doFilter(request, response);}
}@Order(2)
public class SecondFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {System.out.println("Second Filter");chain.doFilter(request, response);}
}// 执行顺序:
// 1. First Filter
// 2. Second Filter
二. 常见使用场景:
1、过滤器排序
@Configuration
public class FilterConfig {@Bean@Order(1)public FilterRegistrationBean<SecurityFilter> securityFilter() {// 安全过滤器最先执行return new FilterRegistrationBean<>(new SecurityFilter());}@Bean@Order(2)public FilterRegistrationBean<LoggingFilter> loggingFilter() {// 日志过滤器第二个执行return new FilterRegistrationBean<>(new LoggingFilter());}@Bean@Order(3)public FilterRegistrationBean<EncodingFilter> encodingFilter() {// 编码过滤器最后执行return new FilterRegistrationBean<>(new EncodingFilter());}
}
2、切面排序
@Aspect
@Order(1)
@Component
public class LoggingAspect {// 日志切面先执行
}@Aspect
@Order(2)
@Component
public class TransactionAspect {// 事务切面后执行
}
3、事件监听器排序:
@Component
@Order(1)
public class EmailNotificationListener implements ApplicationListener<UserRegisteredEvent> {// 邮件通知优先处理
}@Component
@Order(2)
public class SmsNotificationListener implements ApplicationListener<UserRegisteredEvent> {// 短信通知后处理
}
三、特殊值
@Component
@Order(1)
public class EmailNotificationListener implements ApplicationListener<UserRegisteredEvent> {// 邮件通知优先处理
}@Component
@Order(2)
public class SmsNotificationListener implements ApplicationListener<UserRegisteredEvent> {// 短信通知后处理
}
四、注意事项
1、默认值
@Order // 默认值是 Ordered.LOWEST_PRECEDENCE
public class DefaultOrderFilter implements Filter {// 没有指定顺序时,默认最后执行
}
2、相同顺序
@Order(1)
public class FilterA implements Filter {// 相同顺序的执行顺序不确定
}@Order(1)
public class FilterB implements Filter {// 相同顺序的执行顺序不确定
}
3、组合使用
@Configuration
@Order(1) // 配置类的加载顺序
public class SecurityConfig {@Bean@Order(1) // Bean的初始化顺序public SecurityFilter securityFilter() {return new SecurityFilter();}
}
五、最佳实践
1、使用常量定义顺序
public class OrderConstants {public static final int SECURITY_FILTER_ORDER = 100;public static final int LOGGING_FILTER_ORDER = 200;public static final int ENCODING_FILTER_ORDER = 300;
}@Order(OrderConstants.SECURITY_FILTER_ORDER)
public class SecurityFilter implements Filter {// 使用常量便于维护
}
2、预留空间
// 预留足够的间隔,方便后续插入新的顺序
@Order(100) // 安全过滤
@Order(200) // 日志过滤
@Order(300) // 编码过滤
3、文档化
/*** 安全过滤器* 执行顺序:1* 职责:处理安全相关的请求过滤*/
@Order(1)
public class SecurityFilter implements Filter {// 添加清晰的文档说明
}
六、总结:
值越小,优先级越高
相同值的执行顺序不确定
建议使用常量管理顺序值
预留足够的顺序间隔
添加必要的文档说明
使用建议:
安全相关的组件优先级设置高一些
使用有意义的顺序值
避免使用相同的顺序值
合理规划执行顺序