Spring有序的Bean列表

27

我有几个实现了同一接口的豆子。 每个豆子都带有注释

@Component 
@Order(SORT_ORDER).
public class MyClass implements BeanInterface{
    ...
}

有一次,我自动装配了一个组件列表,我希望得到一个排序后的bean列表。 但实际上,这个bean列表并没有按照我使用注解设置的顺序进行排序。

我尝试实现了Ordered接口,但结果还是同样的行为。

@Component
public class Factory{


    @Autowired
    private List<BeanInterface> list; // <- I expect a sorted list here
    ...
}

我有做错什么吗?

5个回答

38

自Spring 4以来,支持对自动装配的集合进行排序。

参见:Spring 4 Ordering Autowired Collections

简述:如果您在bean定义中添加@Order(value = 1)@Order(value = 2) ...,它们将被注入到按照value参数排序的集合中。这不同于声明要在自然顺序中使用集合 - 为此,必须在接收到列表后显式地对其进行排序,如Jordi P.S.'s answer所述。


1
这对许多人很有用,但并没有回答实际问题。最好将信息放在答案中,以防博客消失。我编辑了一份摘要。 - Andrew Spencer
请访问官方Spring 5文档 - Gerardo Cauich

25

我找到了一个解决这个问题的方法,正如你所说,这个注释并不是为此而设计的,尽管这将是一个很好的功能。

要使其按照这种方式工作,只需在包含已排序列表的bean中添加以下代码即可。

@PostConstruct
public void init() {
    Collections.sort(list,AnnotationAwareOrderComparator.INSTANCE);
}
希望它能帮助到您。

2
这在Spring 4中仍然适用吗? - Kai

1
对于Spring版本小于4,使用@Order注解来指定AOP建议执行的顺序,它不会对列表进行排序。要在列表上实现排序,请让您的BeanInterface类实现Comparable接口并覆盖compareTo方法以指定对象应如何排序。然后,您可以使用Collections.sort(list)对列表进行排序。假设BeanInterface有一个名为getSortOrder的方法,该方法返回一个指定对象排序顺序的Integer对象,您可以像这样执行操作:
@Component 
public class MyClass implements BeanInterface, Comparable<BeanInterface> {
    public Integer getSortOrder() {
        return sortOrder;
    }

    public int compareTo(BeanInterface other) {
        return getSortOrder().compareTo(other.getSortOrder());
    }
}

然后你可以像这样对列表进行排序:
Collections.sort(list);

这个答案似乎仅适用于 Spring < 4。 - tkruse
@tkruse 我想这是有道理的,因为答案是在2013年6月发布的,早在Spring 4存在之前。 - clav
只需将其限定在“Spring版本4之前”等范围内即可解决。 - tkruse

1

0

@Order注解来拯救了。

我正在使用SpringBoot 2.6.1,而且这段代码对我来说是有效的,而不需要添加任何@PostConstruct来显式地应用排序。

interface MyFilter {
  
}

以下是接口的多个实现

@Order(value=1)
public class MyFilterImpl1 implements MyFilter {
} 


@Order(value=2)
public class MyFilterImpl2 implements MyFilter {
} 


@Order(value=3)
public class MyFilterImpl3 implements MyFilter {
} 

以下是需要注入MyFilter实现列表的类。

@Component
    @RequiredArgConstructor
    public class MyBean {
     private final List<MyFilter> myFilters;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接