首页 > 编程开发 > Java    日期:2026-09-16 / 浏览:次

一、@Autowired注入集合顺序源码分析 Spring 5.3.2

1、线程调用链

2、注入主要逻辑

//org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveMultipleBeans
@Nullable
private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName,
        @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {

    Class<?> type = descriptor.getDependencyType();

    if (descriptor instanceof StreamDependencyDescriptor) {
        Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
        if (autowiredBeanNames != null) {
            autowiredBeanNames.addAll(matchingBeans.keySet());
        }
        Stream<Object> stream = matchingBeans.keySet().stream()
                .map(name -> descriptor.resolveCandidate(name, type, this))
                .filter(bean -> !(bean instanceof NullBean));
        if (((StreamDependencyDescriptor) descriptor).isOrdered()) {
            stream = stream.sorted(adaptOrderComparator(matchingBeans));
        }
        return stream;
    }
    //支持数组
    else if (type.isArray()) {
        Class<?> componentType = type.getComponentType();
        ResolvableType resolvableType = descriptor.getResolvableType();
        Class<?> resolvedArrayType = resolvableType.resolve(type);
        if (resolvedArrayType != type) {
            componentType = resolvableType.getComponentType().resolve();
        }
        if (componentType == null) {
            return null;
        }
        //找到容器中匹配得实例<实例名,对象>
        Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType,
                new MultiElementDescriptor(descriptor));
        if (matchingBeans.isEmpty()) {
            return null;
        }
        if (autowiredBeanNames != null) {
            autowiredBeanNames.addAll(matchingBeans.keySet());
        }
        //类型转换器
        TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
        //把找到的实例转换成需要的类型
        Object result = converter.convertIfNecessary(matchingBeans.values(), resolvedArrayType);
        if (result instanceof Object[]) {
            //近似看成得到一个AnnotationAwareOrderComparator外部比较器
            /**
            * 实际是得到一个OrderComparator对象 重写了compare方法 调用AnnotationAwareOrderComparator的doCompare方法
            **/
            Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
            if (comparator != null) {
                //排序**********
                Arrays.sort((Object[]) result, comparator);
            }
        }
        return result;
    }
    //支持Collection及其子类 必须为接口
    else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
        Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric();
        if (elementType == null) {
            return null;
        }
        //找到容器中匹配得实例<实例名,对象>
        Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType,
                new MultiElementDescriptor(descriptor));
        if (matchingBeans.isEmpty()) {
            return null;
        }
        if (autowiredBeanNames != null) {
            autowiredBeanNames.addAll(matchingBeans.keySet());
        }
        //类型转换器
        TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
        //把找到的实例转换成需要的类型
        Object result = converter.convertIfNecessary(matchingBeans.values(), type);
        //只有是List集合 才会排序
        if (result instanceof List) {
            if (((List<?>) result).size() > 1) {
                //近似看成得到一个AnnotationAwareOrderComparator外部比较器
                /**
                * 实际是得到一个OrderComparator对象 重写了compare方法 调用AnnotationAwareOrderComparator的doCompare方法
                **/
                Comparator<Object> comparator = adaptDependencyComparator(matchingBeans);
                if (comparator != null) {
                    //排序**********
                    ((List<?>) result).sort(comparator);
                }
            }
        }
        return result;
    }
    //支持Map类型 只能为Map
    else if (Map.class == type) {
        ResolvableType mapType = descriptor.getResolvableType().asMap();
        Class<?> keyType = mapType.resolveGeneric(0);
        if (String.class != keyType) {
            return null;
        }
        Class<?> valueType = mapType.resolveGeneric(1);
        if (valueType == null) {
            return null;
        }
        //找到容器中匹配得实例<实例名,对象>
        Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType,
                new MultiElementDescriptor(descriptor));
        if (matchingBeans.isEmpty()) {
            return null;
        }
        if (autowiredBeanNames != null) {
            autowiredBeanNames.addAll(matchingBeans.keySet());
        }
        return matchingBeans;
    }
    else {
        return null;
    }
}

3、AnnotationAwareOrderComparator比较器核心代码

3.1、首先来看两个重要类的继承结构

AnnotationAwareOrderComparator类继承结构



PriorityOrdered类继承结构


3.2 、比较器核心代码

调用顺序

OrderComparator#doCompare
org.springframework.core.OrderComparator#getOrder(java.lang.Object, org.springframework.core.OrderComparator.OrderSourceProvider) org.springframework.core.annotation.AnnotationAwareOrderComparator#findOrder
org.springframework.core.OrderComparator#findOrder
org.springframework.core.OrderComparator#getOrder(java.lang.Object)
//org.springframework.core.OrderComparator#doCompare
private int doCompare(@Nullable Object o1, @Nullable Object o2, @Nullable OrderSourceProvider sourceProvider) {
    boolean p1 = (o1 instanceof PriorityOrdered);
    boolean p2 = (o2 instanceof PriorityOrdered);
    /**
    * PriorityOrdered接口实例和非PriorityOrdered接口实例比较PriorityOrdered实例放前面
    **/
    if (p1 && !p2) {
        return -1;
    }
    else if (p2 && !p1) {
        return 1;
    }
    
    int i1 = getOrder(o1, sourceProvider);
    int i2 = getOrder(o2, sourceProvider);
    return Integer.compare(i1, i2);
}

//org.springframework.core.OrderComparator#getOrder(java.lang.Object, org.springframework.core.OrderComparator.OrderSourceProvider)
private int getOrder(@Nullable Object obj, @Nullable OrderSourceProvider sourceProvider) {
    Integer order = null;
    if (obj != null && sourceProvider != null) {
        Object orderSource = sourceProvider.getOrderSource(obj);
        if (orderSource != null) {
            if (orderSource.getClass().isArray()) {
                for (Object source : ObjectUtils.toObjectArray(orderSource)) {
                    order = findOrder(source);
                    if (order != null) {
                        break;
                    }
                }
            }
            else {
                order = findOrder(orderSource);
            }
        }
    }
    return (order != null ? order : getOrder(obj));
}

//org.springframework.core.OrderComparator#getOrder(java.lang.Object)
protected int getOrder(@Nullable Object obj) {
    if (obj != null) {
        Integer order = findOrder(obj);
        if (order != null) {
            return order;
        }
    }
    //如果没有获取到排序值 返回返回最大排序值即放到最后
    return Ordered.LOWEST_PRECEDENCE;
}

//org.springframework.core.OrderComparator#findOrder
@Nullable
protected Integer findOrder(Object obj) {
    //得到Ordered接口中的排序值 PriorityOrdered也是Ordered子类 没实现Ordered接口接口返回null
    return (obj instanceof Ordered ? ((Ordered) obj).getOrder() : null);
}

//org.springframework.core.annotation.AnnotationAwareOrderComparator#findOrder
@Override
@Nullable
protected Integer findOrder(Object obj) {
    //调用父类Ordered接口中findOrder方法
    Integer order = super.findOrder(obj);
    //有排序值则直接返回
    if (order != null) {
        return order;
    }
    //如果为空 说明实例没有实现Ordered接口 则取类上@Order注解上获取排序值
    return findOrderFromAnnotation(obj);
}

//org.springframework.core.annotation.AnnotationAwareOrderComparator#findOrderFromAnnotation
@Nullable
private Integer findOrderFromAnnotation(Object obj) {
    AnnotatedElement element = (obj instanceof AnnotatedElement ? (AnnotatedElement) obj : obj.getClass());
    MergedAnnotations annotations = MergedAnnotations.from(element, SearchStrategy.TYPE_HIERARCHY);
    //获取@Order注解中的排序值 没有返回null
    Integer order = OrderUtils.getOrderFromAnnotations(element, annotations);
    if (order == null && obj instanceof DecoratingProxy) {
        return findOrderFromAnnotation(((DecoratingProxy) obj).getDecoratedClass());
    }
    return order;
}

3.3 、小结

下面将没有实现PriorityOrdered接口,也没实现Ordered接口,也没有加@Order注解的类实例叫做 三无实例

OrderComparator类实现的功能:根据PriorityOrdered和Ordered接口中的排序值进行排序。总结一哈大概有以下情况:

  1. PriorityOrdered实例 和 非PriorityOrdered实例,PriorityOrdered实例放前面
  2. PriorityOrdered实例 和 PriorityOrdered实例,根据getOrder接口方法得到排序值比较
  3. Ordered实例 和 Ordered实例,根据getOrder接口方法得到排序值比较
  4. 三无实例 和 三无实例,三无实例排序值为Integer最大值,所以两个比较顺序不变
  5. Ordered实例 和 三无实例,三无实例排序值为Integer最大值,所有getOrder接口方法得到排序值和Integer最大值比较

AnnotationAwareOrderComparator类实现的功能:AnnotationAwareOrderComparator类是继承OrderComparator类的,所以在上面OrderComparator类功能的基础上,扩展了如果没有实现PriorityOrdered和Ordered接口的情况,从@Order注解中获取排序值。

总结一哈大概有以下情况:

  1. PriorityOrdered实例 和 非PriorityOrdered实例,PriorityOrdered实例放前面
  2. PriorityOrdered实例 和 PriorityOrdered实例,根据getOrder方法得到排序值比较
  3. Ordered实例 和 Ordered实例,根据getOrder方法得到排序值比较
  4. @Order实例 和 @Order实例, 根据@Order中的排序值比较
  5. 三无实例 和 三无实例,三无实例排序值为Integer最大值,所以两个比较顺序不变
  6. Ordered实例 和 三无实例,三无实例排序值为Integer最大值,所有getOrder接口方法得到排序值和Integer最大值比较
  7. Ordered实例 和 @Order实例,根据getOrder方法得到排序值和@Order中的排序值比较
  8. @Order实例 和 三无实例,三无实例排序值为Integer最大值,所有@Order中的排序值和Integer最大值比较

关于一个实现了PriorityOrdered接口、Ordered接口、加了@Order注解的类中取排序值的优先级:

通过源码可知,如果实现了PriorityOrdered接口,那么该类实例只能和同样实现了PriorityOrdered接口比较才是通过排序值进行比较的,不然和非实现PriorityOrdered接口的类实例比较,实现了PriorityOrdered接口直接拍前面(不会管排序值大小)。

如果不满足上面,就会先从Ordered接口中取排序值,没有实现Ordered接口的话,就会从@Order注解获取排序值,如果没有加@Order注解,排序值默认为Integer最大值。

二、@Autowired能注入的集合类型及集合中顺序

1、数组

看过源码可知是根据AnnotationAwareOrderComparator外部比较器进行排序的,所以支持PriorityOrdered接口 、Ordered接口、@Order排序

2、Collection及其子类且必须为接口

看过源码源码可知只有当为List及其子接口时才会进行排序,是根据AnnotationAwareOrderComparator比较器进行排序,所以支持PriorityOrdered接口 、Ordered接口、@Order排序

那么如果注入Set集合要排序怎么办呢,我们阔以注入到SortedSet集合中,在把要注入的实例类型实现Comparable接口实现自定义排序

3、只能是Map,不能是其子类

看过源码可知,Map是不能进行排序的,而且只能注入Map集合中,不能是Map子类。

Key为实例在容器中的名称,Value为该实例。

三、总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持教程之家。

觉得上面的内容有用吗?快来点个赞吧!

点赞() 我要打赏

温馨提示 : 本站内容来自会员投稿以及互联网,所有源码及教程均为作者总结编辑,请大家在使用过程中提前做好备份,以免发生无法预知的错误,源码类教程请勿直接用于生产环境!

 可能感兴趣的文章