最新实战案例锦集:《Spring Boot3实战案例合集》持续更新,每天至少更新一篇文章,订阅后将赠送文章最后展示的所有MD文档(学习笔记)。
环境:SpringBoot3.2.5
1. 简介
@Order注解是Spring框架中用于定义Bean执行顺序的优先级的一个注解,它位于spring-core包下。这个注解可以应用在类、方法和字段上,其作用是影响Bean注入到集合中的顺序,但不影响Bean的加载和实例化顺序。@Order 注解接受一个整数值作为参数,数值越小表示优先级越高。需要注意的是,@Order 注解或Ordered接口不能决定Bean的加载顺序。
注意:不会影响实例化的顺序,实例化的顺序是由你注册(通过扫描时,先发现的A,那就先实例化A)。
那 @Order 注解到底能用在哪些地方呢?接下来,我们将介绍一些常用场景下使用 @Order 注解的有效方法。
2. 实战案例
2.1 注入类型为集合
当我们在注入一个集合类型时(有多个相同类型,如一个接口多个实现),我们可以通过@Order注解来控制它们在集合中的顺序。
// 定义接口
public interface DAO {
public void save() ;
}
// 下面3个实现类
@Component
public class A implements DAO {
public void save() {
System.out.println("A...") ;
}
}
@Component
public class B implements DAO {
public void save() {
System.out.println("B...") ;
}
}
@Component
public class C implements DAO {
public void save() {
System.out.println("C...") ;
}
}
// 集合注入
@Resource
private List<DAO> daos ;
public void print() {
for (DAO dao : daos) {
dao.save() ;
}
}
运行上面程序,执行结果如下:
A...
B...
C...
分别添加@Order注解
@Order(2)
public class A...
@Order(1)
public class B...
@Order(0)
public class C...
再次运行
C...
B...
A...
这里的集合还可以是Array类型。都支持排序。
除了使用@Order注解,你还可以实现Ordered接口。同时,bean的注册方式也可以是通过配置类@Bean也可以添加@Order注解。
2.2 事件监听ApplicationListener
1) (-
public class ListenerA implements ApplicationListener<PackEvent> {
public void onApplicationEvent(PackEvent event) {
System.out.println("A Listener...") ;
}
}
2) (-
public class ListenerB implements ApplicationListener<PackEvent> {
public void onApplicationEvent(PackEvent event) {
System.out.println("B Listener...") ;
}
}
当发布PackEvent事件后,打印顺序如下:
B Listener...
A Listener...
同样你可以实现Ordered接口。
2.3 Application/CommandLineRunner
*Runner接口会在整个Spring Boot启动完成最后一个阶段(Spring容器已经完成加载),如下
0) (
public class RunnerA implements CommandLineRunner {
public void run(String... args) throws Exception {
System.out.println("A Runner...") ;
}
}
1) (-
public class RunnerB implements CommandLineRunner {
public void run(String... args) throws Exception {
System.out.println("B Runner...") ;
}
}
输出结果
B Runner...
A Runner...
一样通过配置类注册或者是实现Ordered接口都可以。
2.4 BeanPostProcessor
这是个Bean处理器(实例化Bean对象前后执行回调),我们只能通过实现Ordered接口来控制顺序。
public class APostProcessor implements BeanPostProcessor, Ordered {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("A BeanPostProcessor") ;
return bean ;
}
public int getOrder() {
return -1 ;
}
}
public class BPostProcessor implements BeanPostProcessor, Ordered {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("B BeanPostProcessor") ;
return bean ;
}
public int getOrder() {
return -2 ;
}
}
执行输出结果
B BeanPostProcessor
A BeanPostProcessor
目前不支持基于 @Order 注解方式。
除了实现Ordered接口外,你还可以实现PriorityOrdered接口。
2.5 BeanFactoryPostProcessor
该接口与上面的BeanPostProcessor基本一致,你只能通过实现Ordered接口的方式控制顺序。
2.6 @Aspect切面
1) (-
public static class AspectA {
"execution(* *(..))") (
private void a() {}
"a()") (
public void before() {
System.out.println("A before...") ;
}
}
2) (-
public static class AspectB {
"execution(* *(..))") (
private void b() {}
"b()") (
public void before() {
System.out.println("B before...") ;
}
}
切面执行
B before...
A before...
Demo save...
切面除了使用@Order还可以实现Ordered接口。
以上列出了我们工作中比较常用的一些场景使用上可以应用@Order注解或实现Ordered接口。而在Spring Boot环境下还有很多其它的一些情况都是支持排序的。
2.7 其它
FailureAnalyzer、ApplicationContextInitializer、ErrorPageRegistrar、ErrorViewResolver等。
其实如果是通过如下方式获取的,都是支持排序的
// 只要是通过该方式获取对象的,都是支持排序的
SpringFactoriesLoader
以上是本篇文章的全部内容,如对你有帮助帮忙点赞+转发+收藏
推荐文章
Jackson在Spring Boot高级应用技巧【Long精度丢失, @JsonValue, 数据脱敏】
必学!Spring Boot结合MDC全方位的日志跟踪(支持跨线程)
Spring Boot REST API版本控制的方案及选择
Spring强大的@Configurable注解使用过吗?注意不是@Configuration
实战!16条SpringBoot Web服务配置指南及优化技巧