Spring | @Order 与 Ordered 控制加载顺序

@Order 与 Ordered 控制加载顺序

  • 一、@Order & Ordered
  • 二、@Order的使用方式
  • 三、Ordered的使用方式
  • 四、浅看@Order / Ordered 原理
    • 1. @Order / Ordered 控制执行顺序验证
    • 2. 浅看执行原理
  • 五、总结

一、@Order & Ordered

@Order与Ordered 是控制顺序的, 是控制执行顺序,不控制Spring初始化顺序。


@Order / Ordered顺序是从小到大 执行
@Order 默认 2147483647
Spring | @Order 与 Ordered 控制加载顺序_第1张图片


  • @Order: @Order是注解 : 配合与@Bean 与 @Compent 使用
  • Ordered: Ordered是接口

需要注意的是 在SpringBoot实现过滤器过程中使用 @WebFilter 这个时候@Order或者Ordered接口是失效的
参考过滤器实现方式: SpringBoot多种 Filter过滤器 配置方式
https://blog.csdn.net/qq825478739/article/details/125421560

二、@Order的使用方式

@Order + @Bean

@Configuration
public class OrderCreateConfig {


    @Bean
    @Order(1)
    public OrderService createOrder1Service(){
        return new Order1ServiceImpl();
    }

    @Bean
    @Order(2)
    public OrderService createOrder2Service(){
        return new Order2ServiceImpl();
    }

    @Bean
    @Order(3)
    public OrderService createOrder3Service(){
        return new Order3ServiceImpl();
    }
}

@Order + @Component

@Order(3)
@Service
public class Order1ServiceImpl implements OrderService {

    public Order1ServiceImpl() {
        System.out.println("Order1 创建了");
    }

    @Override
    public void demo() {
        System.out.println("Order1 执行了");
    }
}
@Order(3)
@Component
public class Order1ServiceImpl implements OrderService {

    public Order1ServiceImpl() {
        System.out.println("Order1 创建了");
    }

    @Override
    public void demo() {
        System.out.println("Order1 执行了");
    }
}

三、Ordered的使用方式

实现接口 Ordered

public class Order1ServiceImpl implements OrderService, Ordered {

    public Order1ServiceImpl() {
        System.out.println("Order1 创建了");
    }

    @Override
    public void demo() {
        System.out.println("Order1 执行了");
    }

    @Override
    public int getOrder() {
        return 1;
    }
}

四、浅看@Order / Ordered 原理

1. @Order / Ordered 控制执行顺序验证

创建三个OrderServce 的实现类

public interface OrderService {
    void demo();
}
@Order(3)
@Service
public class Order1ServiceImpl implements OrderService {

    public Order1ServiceImpl() {
        System.out.println("Order1 创建了");
    }

    @Override
    public void demo() {
        System.out.println("Order1 执行了");
    }
}
@Order(2)
@Service
public class Order2ServiceImpl implements OrderService {

    public Order2ServiceImpl() {
        System.out.println("Order2 创建了");
    }

    @Override
    public void demo() {
        System.out.println("Order2 执行了");
    }
}
@Order(1)
@Service
public class Order3ServiceImpl implements OrderService {

    public Order3ServiceImpl() {
        System.out.println("Order3 创建了");
    }

    @Override
    public void demo() {
        System.out.println("Order3 执行了");
    }
}

Test 执行

@SpringBootTest
class SpringDemoApplicationTests {


    @Autowired
    private List<OrderService> orderServices;

    @Test
    void contextLoads() {
        orderServices.forEach(orderService -> orderService.demo());
    }

}

执行结构
在这里插入图片描述
Ordered / @Order 只控制执行顺序, 不控制Spring初始化Bean 的顺序

2. 浅看执行原理

Spring 版本 5.3.23
各个版本的代码有差异

这个时候就需要对Spring源码有一定了解了
Spring源码解析之Bean实例化流程:https://blog.csdn.net/qq825478739/article/details/127363578?spm=1001.2014.3001.5502


创建一个servce 注入 private List orderServices;

@Component
public class OrderAutoWireDemo {

    @Autowired
    private List<OrderService> orderServices;
}

这里我们直接跳到 给 OrderAutoWireDemo 注入属性的时候,看他都干了什么。


直接从Spring DI注入属性开始 populateBean

populateBean()
AutowiredAnnotationBeanPostProcessor.postProcessProperties()
AutowiredFieldElement(内部类).inject()
AutowiredFieldElement(内部类).resolveFieldValue()
DefaultListableBeanFactory.resolveDependency()
DefaultListableBeanFactory.doResolveDepenDency()
DefaultListableBeanFactory.resolveMultipleBeans()
从这resolveMultipleBeans()方法中 就可以知道 进行排序的地方 获取到Comparator 然后 result(注入属性集合) 进行 sort()排序
  Object result = converter.convertIfNecessary(matchingBeans.values(), type);
                        if (result instanceof List && ((List)result).size() > 1) {
                            Comparator<Object> comparator = this.adaptDependencyComparator(matchingBeans);
                            if (comparator != null) {
                                ((List)result).sort(comparator);
                            }
                        }
this.adaptDependencyComparator(matchingBeans)

adaptDependencyComparator() 方法返回是 OrderComparator
OrderComparator实现比较器Comparator接口, ((List)result).sort(comparator);会根据@Order或者Ordered接口设置的int序值重写sort方法进行排序,值越小优先级越高。



通过debug我们我们可以看到注入属性的时候 做了sort排序

五、总结

  1. Ordered / @Order 不控制实例化顺序,只控制执行顺序。
  2. Ordered / @Order 只跟特定一些注解生效 如:@Compent @Service … 不生效的如: @WebFilter

最后最后 : 有帮助点个赞 收藏下吧, 有阐述错误的地方请评论指出 。 共同进步

你可能感兴趣的:(SpringBoot,Spring,spring,java,spring,boot)