1. 概述
本文将深入讲解 Spring 框架中的 @Order
注解。✅ 它的核心作用是定义被注解组件或 Bean 的排序优先级。
该注解有一个可选的 value
参数,用于指定顺序值,默认值为 Ordered.LOWEST_PRECEDENCE
,表示该组件在所有有序组件中优先级最低。
相对地,Ordered.HIGHEST_PRECEDENCE
则代表最高优先级,常用于需要优先执行的场景。
⚠️ 注意:这里的“顺序”不等于“加载顺序”或“初始化顺序”,它主要影响的是集合注入时 Bean 的排列顺序,这点后面会重点说明。
2. 何时使用 @Order
在 Spring 4.0 之前,@Order
主要用于控制 AspectJ 切面的执行顺序 —— 数值越小,切面越早执行。
✅ 从 Spring 4.0 开始,@Order
被扩展支持到集合类型的依赖注入场景。也就是说,当你通过 List<SomeService>
自动注入多个同类型 Bean 时,Spring 会根据 @Order
的值对它们进行排序。
举个实际场景:
- 多个实现类实现同一个接口
- 通过
List<Filter>
注入一组过滤器 - 需要按特定顺序执行这些组件
这时候 @Order
就非常有用。否则 Spring 默认的注入顺序是不确定的(取决于类路径扫描顺序),容易踩坑 ❌。
3. 如何使用 @Order
我们通过一个简单例子来演示其用法。
3.1. 定义接口
首先定义一个 Rating
接口,用于表示商品评分等级:
public interface Rating {
int getRating();
}
3.2. 创建带顺序的组件
接下来创建三个实现类,并通过 @Order
指定它们的优先级:
@Component
@Order(1)
public class Excellent implements Rating {
@Override
public int getRating() {
return 1;
}
}
@Component
@Order(2)
public class Good implements Rating {
@Override
public int getRating() {
return 2;
}
}
@Component
@Order(Ordered.LOWEST_PRECEDENCE)
public class Average implements Rating {
@Override
public int getRating() {
return 3;
}
}
📌 关键点:
Excellent
的 order 值为 1,优先级最高Good
为 2,次之Average
使用LOWEST_PRECEDENCE
,排在最后
⚠️ 注意:@Order
的值越小,优先级越高(排序越靠前)。
4. 测试验证
现在我们编写单元测试,验证注入后的列表是否按预期顺序排列:
public class RatingRetrieverUnitTest {
@Autowired
private List<Rating> ratings;
@Test
public void givenOrder_whenInjected_thenByOrderValue() {
assertThat(ratings.get(0).getRating(), is(equalTo(1))); // Excellent
assertThat(ratings.get(1).getRating(), is(equalTo(2))); // Good
assertThat(ratings.get(2).getRating(), is(equalTo(3))); // Average
}
}
✅ 测试通过说明:Spring 确实按照 @Order
的值对 List<Rating>
中的 Bean 进行了排序。
💡 小贴士:这种机制在实现责任链模式、拦截器链、过滤器链时特别实用。
5. 总结与注意事项
我们已经掌握了 @Order
的基本用法和典型场景。再强调几个关键点:
✅ 适用场景:
- 注入
List<XXX>
或Set<XXX>
类型的 Bean 集合 - 控制切面(Aspect)执行顺序
- 自定义组件链式处理流程(如校验链、处理器链)
❌ 不适用场景:
- 控制 Bean 的初始化顺序 ❌
Bean 的启动顺序由依赖关系(@DependsOn
)决定,而不是@Order
。别搞混了!
📌 常见误区:
“我加了
@Order(1)
,这个 Bean 就会最先初始化?”
❌ 错!@Order
不影响单例 Bean 的创建顺序,只影响集合注入时的排序。
所有示例代码均可在 GitHub 获取:https://github.com/eugenp/tutorials/tree/master/spring-di-3