欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

深入理解Spring的@Order注解和Ordered接口

程序员文章站 2024-01-02 23:45:22
前言  Spring的@Order注解或者Ordered接口大家都知道是控制顺序的,那么它们到底是控制什么顺序的?是控制Bean的注入顺序,还是Bean的实例化顺序,还是Bean的执行顺序呢?那么我们先直接给出结论再来验证结论。结论:Spring的@Order注解或者Ordered接口,不决定Bean的加载顺序和实例化顺序,只决定Bean的执行顺序。实例论证:@Order不决定Bean的加载和实例化顺序步骤一:创建DemoService接口和三个实现类,分别打上注解@Order(0)-DemoSer...

前言

  Spring的@Order注解或者Ordered接口大家都知道是控制顺序的,那么它们到底是控制什么顺序的?是控制Bean的注入顺序,还是Bean的实例化顺序,还是Bean的执行顺序呢?那么我们先直接给出结论再来验证结论。
结论:Spring的@Order注解或者Ordered接口,不决定Bean的加载顺序和实例化顺序,只决定Bean的执行顺序。

实例论证:@Order不决定Bean的加载和实例化顺序

步骤一:创建DemoService接口和三个实现类,分别打上注解@Order(0)-DemoServiceImpl01、@Order(1)-DemoServiceImpl02、@Order(2)-DemoServiceImpl03,观察实例化顺序。

@Service
@Order(0)
public class DemoServiceImpl01 implements DemoService {

    public DemoServiceImpl01() {
        System.out.println("DemoServiceImpl01被实例化了");
    }
}

@Service
@Order(1)
public class DemoServiceImpl02 implements DemoService {

    public DemoServiceImpl02() {
        System.out.println("DemoServiceImpl02被实例化了");
    }

}

@Service
@Order(2)
public class DemoServiceImpl03 implements DemoService {

    public DemoServiceImpl03() {
        System.out.println("DemoServiceImpl03被实例化了");
    }

}

// 运行结果如下
DemoServiceImpl01被实例化了
DemoServiceImpl02被实例化了
DemoServiceImpl03被实例化了

步骤二:改变DemoService接口三个实现类的注解序值,@Order(2)-DemoServiceImpl01、@Order(1)-DemoServiceImpl02、@Order(0)-DemoServiceImpl03,观察实例化顺序

@Service
@Order(2)
public class DemoServiceImpl01 implements DemoService {

    public DemoServiceImpl01() {
        System.out.println("DemoServiceImpl01被实例化了");
    }
}

@Service
@Order(1)
public class DemoServiceImpl02 implements DemoService {

    public DemoServiceImpl02() {
        System.out.println("DemoServiceImpl02被实例化了");
    }

}

@Service
@Order(0)
public class DemoServiceImpl03 implements DemoService {

    public DemoServiceImpl03() {
        System.out.println("DemoServiceImpl03被实例化了");
    }

}

// 运行结果如下
DemoServiceImpl01被实例化了
DemoServiceImpl02被实例化了
DemoServiceImpl03被实例化了

结果:当改变DemoService接口的三个实现类注解序值时,类的加载和实例化顺序根本没有变化,即@Order注解不决定Bean的加载和实例化顺序。

实例论证:@Order决定Bean的执行顺序

步骤一:创建RunServiceImpl类,并通过构造函数依赖注入DemoService的三个实现类,且循序依次执行三个实现类方法,观察Bean的执行顺序。

@Service
public class RunServiceImpl implements RunService {

    public RunServiceImpl(List<DemoService> demoServices) {
        demoServices.forEach(demoService -> demoService.say());
    }

}

@Service
@Order(0)
public class DemoServiceImpl01 implements DemoService {

    public DemoServiceImpl01() {
        System.out.println("DemoServiceImpl01被实例化了");
    }

    @Override
    public void say() {
        System.out.println("DemoServiceImpl01被执行了");
    }
}

@Service
@Order(1)
public class DemoServiceImpl02 implements DemoService {

    public DemoServiceImpl02() {
        System.out.println("DemoServiceImpl02被实例化了");
    }

    @Override
    public void say() {
        System.out.println("DemoServiceImpl02被执行了");
    }

}

@Service
@Order(2)
public class DemoServiceImpl03 implements DemoService {

    public DemoServiceImpl03() {
        System.out.println("DemoServiceImpl03被实例化了");
    }

    @Override
    public void say() {
        System.out.println("DemoServiceImpl03被执行了");
    }

}

// 运行结果如下
DemoServiceImpl01被执行了
DemoServiceImpl02被执行了
DemoServiceImpl03被执行了

步骤二:改变DemoService接口三个实现类的注解序值,@Order(2)-DemoServiceImpl01、@Order(1)-DemoServiceImpl02、@Order(0)-DemoServiceImpl03,观察Bean的执行顺序。

@Service
public class RunServiceImpl implements RunService {

    public RunServiceImpl(List<DemoService> demoServices) {
        demoServices.forEach(demoService -> demoService.say());
    }

}

@Service
@Order(2)
public class DemoServiceImpl01 implements DemoService {

    public DemoServiceImpl01() {
        System.out.println("DemoServiceImpl01被实例化了");
    }

    @Override
    public void say() {
        System.out.println("DemoServiceImpl01被执行了");
    }
}

@Service
@Order(1)
public class DemoServiceImpl02 implements DemoService {

    public DemoServiceImpl02() {
        System.out.println("DemoServiceImpl02被实例化了");
    }

    @Override
    public void say() {
        System.out.println("DemoServiceImpl02被执行了");
    }

}

@Service
@Order(0)
public class DemoServiceImpl03 implements DemoService {

    public DemoServiceImpl03() {
        System.out.println("DemoServiceImpl03被实例化了");
    }

    @Override
    public void say() {
        System.out.println("DemoServiceImpl03被执行了");
    }

}

// 运行结果如下
DemoServiceImpl03被执行了
DemoServiceImpl02被执行了
DemoServiceImpl01被执行了

结果:当改变DemoService接口的三个实现类注解序值时,类的执行顺序也随之发生变化,即@Order决定Bean的执行顺序。

@Order注解或Ordered接口决定Bean的执行顺序原理分析

通过上面实例论证,大家应该清楚@Order注解或Ordered接口只是决定了Bean的执行顺序,那么Spring是如何在依赖注入时完成根据@Order注解或Ordered接口控制Bean执行顺序?
原理分析:
当通过构造函数或者方法参数注入进某个List<组件实现类>时,Spring的DefaultListableBeanFactory类会在注入时调用AnnotationAwareOrderComparator.sort(listA)帮我们去完成根据@Order或者Ordered接口序值排序。

备注:
AnnotationAwareOrderComparator是OrderComparator的子类,而OrderComparator实现比较器Comparator接口,AnnotationAwareOrderComparator.sort(listA)会调用父类sort方法,会根据@Order或者Ordered接口设置的int序值重写sort方法进行排序,值越小优先级越高。


我的专栏

  1. 设计模式
  2. 认证授权框架实战
  3. java进阶知识
  4. maven进阶知
  5. spring进阶知识

本文地址:https://blog.csdn.net/zkc7441976/article/details/112548075

上一篇:

下一篇: