@Order注解,你理解错了!

文摘   2024-11-14 08:00   新疆  

最新实战案例锦集:《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个实现类@Componentpublic class A implements DAO {  public void save() {    System.out.println("A...") ;  }}@Componentpublic class B implements DAO {  public void save() {    System.out.println("B...") ;  }}@Componentpublic class C implements DAO {  public void save() {    System.out.println("C...") ;  }}// 集合注入@Resourceprivate 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

@Component@Order(-1)public class ListenerA implements ApplicationListener<PackEvent> {
@Override public void onApplicationEvent(PackEvent event) { System.out.println("A Listener...") ; }}@Component@Order(-2)public class ListenerB implements ApplicationListener<PackEvent> {
@Override public void onApplicationEvent(PackEvent event) { System.out.println("B Listener...") ; }}

当发布PackEvent事件后,打印顺序如下:

B Listener...A Listener...

同样你可以实现Ordered接口。

2.3 Application/CommandLineRunner

*Runner接口会在整个Spring Boot启动完成最后一个阶段(Spring容器已经完成加载),如下

@Component@Order(0)public class RunnerA implements CommandLineRunner {  public void run(String... args) throws Exception {    System.out.println("A Runner...") ;  }}@Component@Order(-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 BeanPostProcessorA BeanPostProcessor

目前不支持基于 @Order 注解方式。

除了实现Ordered接口外,你还可以实现PriorityOrdered接口。

2.5 BeanFactoryPostProcessor

该接口与上面的BeanPostProcessor基本一致,你只能通过实现Ordered接口的方式控制顺序。

2.6 @Aspect切面

@Aspect@Order(-1)public static class AspectA {  @Pointcut("execution(* *(..))")  private void a() {}  @Before("a()")  public void before() {    System.out.println("A before...") ;  }}@Aspect@Order(-2)public static class AspectB {  @Pointcut("execution(* *(..))")  private void b() {}  @Before("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#load(Class type)



以上是本篇文章的全部内容,如对你有帮助帮忙点赞+转发+收藏

推荐文章

Jackson在Spring Boot高级应用技巧【Long精度丢失, @JsonValue, 数据脱敏】

干货!详解Spring Boot中各种场景下的类型转换

Controller 接口支持多达26种参数解析方式

必学!Spring Boot结合MDC全方位的日志跟踪(支持跨线程)

Spring Boot REST API版本控制的方案及选择

全面彻底掌握OpenFeign

SpringBoot线上动态调整、实时监控、告警线程池状态

掌握Spring Boot最佳途径!就该如此做

高性能缓存神器Caffeine

Spring强大的@Configurable注解使用过吗?注意不是@Configuration

实战!16条SpringBoot Web服务配置指南及优化技巧

SpringBoot3必须掌握的5个强大功能,其中JVM优化技巧太厉害了

强大!必须掌握!Spring Security这些技巧你知道吗?

Spring全家桶实战案例源码
spring, springboot, springcloud 案例开发详解
 最新文章