Spring的@Order注解和Ordered接口

Spring的 @Order 注解和 Ordered 接口

 

 

1、简介

     Spring的 @Order 注解或者 Ordered 接口大家都知道是控制顺序的,那么它们到底是控制什么顺序的?是控制Bean的注入顺序,还是Bean的实例化顺序,还是Bean的执行顺序呢?
结论:Spring的@Order注解或者Ordered接口,不决定Bean的加载顺序和实例化顺序,只决定Bean的执行顺序。order越小的值,优先级越高,越大的值优先级越低。

2、那么Spring是如何在依赖注入时完成根据@Order注解或Ordered接口控制Bean执行顺序?
原理分析:
      spring 源码中使用了大量的 AnnotationAwareOrderComparator 来进行排序。例如:SpringFactoriesLoader 类的 loadFactories()方法中会调用AnnotationAwareOrderComparator.sort(listA)帮我们去完成根据@Order或者Ordered接口序值排序。例如:

public static <T> List<T> loadFactories(Class<T> factoryClass, @Nullable ClassLoader classLoader) {
        Assert.notNull(factoryClass, "'factoryClass' must not be null");
        ClassLoader classLoaderToUse = classLoader;
        if (classLoaderToUse == null) {
            classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
        }
        List<String> factoryNames = loadFactoryNames(factoryClass, classLoaderToUse);
        if (logger.isTraceEnabled()) {
            logger.trace("Loaded [" + factoryClass.getName() + "] names: " + factoryNames);
        }
        List<T> result = new ArrayList<>(factoryNames.size());
        for (String factoryName : factoryNames) {
            result.add(instantiateFactory(factoryName, factoryClass, classLoaderToUse));
        }
        AnnotationAwareOrderComparator.sort(result);
        return result;
    }

 

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

public class OrderComparator implements Comparator<Object> {

    /**
     * Shared default instance of {@code OrderComparator}.
     */
    public static final OrderComparator INSTANCE = new OrderComparator();


    /**
     * Build an adapted order comparator with the given source provider.
     * @param sourceProvider the order source provider to use
     * @return the adapted comparator
     * @since 4.1
     */
    public Comparator<Object> withSourceProvider(final OrderSourceProvider sourceProvider) {
        return (o1, o2) -> doCompare(o1, o2, sourceProvider);
    }

    @Override
    public int compare(@Nullable Object o1, @Nullable Object o2) {
        return doCompare(o1, o2, null);
    }

    private int doCompare(@Nullable Object o1, @Nullable Object o2, @Nullable OrderSourceProvider sourceProvider) {
        boolean p1 = (o1 instanceof PriorityOrdered);
        boolean p2 = (o2 instanceof PriorityOrdered);
        if (p1 && !p2) {
            return -1;
        }
        else if (p2 && !p1) {
            return 1;
        }

        // Direct evaluation instead of Integer.compareTo to avoid unnecessary object creation.
        int i1 = getOrder(o1, sourceProvider);
        int i2 = getOrder(o2, sourceProvider);
        return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
    }
// .....省略 }

OrderComparator比较器进行排序的时候,若2个对象中有一个对象实现了PriorityOrdered接口,那么这个对象的优先级更高。
若2个对象都是PriorityOrdered或Ordered接口的实现类,那么比较Ordered接口的getOrder方法得到order值,值越低,优先级越高。

 

posted @ 2023-07-10 21:14  邓维-java  阅读(1096)  评论(0)    收藏  举报