简体   繁体   English

Spring bean 有序列表

[英]Spring ordered list of beans

I have several beans that implement the same interface.我有几个实现相同接口的bean。 Each bean is annotated with每个 bean 都带有注释

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

At one point I autowire a list of components and I expect a sorted list of beans.有一次,我自动装配了一个组件列表,并且我期望得到一个排序的 bean 列表。 The list of beans is not sorted according the orders I have set with the annotation. bean 列表未按照我使用注释设置的顺序进行排序。

I tried implementing the interface Ordered and the same behaviour occurs.我尝试实现接口 Ordered 并且发生了相同的行为。

@Component
public class Factory{


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

Am I doing anything wrong?我做错什么了吗?

Ordering autowired collections is supported since Spring 4. 从Spring 4开始,支持订购自动装配的集合。

See: Spring 4 Ordering Autowired Collections 请参阅: Spring 4订购自动收集的集合

Summary: if you add @Order(value=1) , @Order(value=2) ... to your bean definitions, they will be injected in a collection ordered according to the value parameter. 简介:如果将@Order(value=1) ,@ @Order(value=2) ...添加到bean定义中,它们将被注入根据value参数排序的集合中。 This is not the same as declaring that you want the collection in natural order - for that you have to explicitly sort the list yourself after receiving it, as per Jordi PS's answer . 这与声明您希望收集按自然顺序不同 - 因为根据Jordi PS的回答 ,您必须在收到后自己明确地对列表进行排序。

I found a solution to the issue, as you say, this annotation is not meant for that despite it would be a nice feature. 我找到了解决这个问题的方法,正如你所说,这个注释并不适用于那个,尽管它是一个很好的功能。

To make it work this way its just necessary to add the following code in the bean containing the sorted list. 为了使它以这种方式工作,它只需要在包含排序列表的bean中添加以下代码。

@PostConstruct
public void init() {
    Collections.sort(list,AnnotationAwareOrderComparator.INSTANCE);
}

Hope it helps. 希望能帮助到你。

The @Order annotation is used to specify the order in which AOP advice is executed, it doesn't sort lists. @Order注释用于指定执行AOP建议的顺序,它不对列表进行排序。 To achieve sorting on your list have your BeanInterface classes implement the Comparable interface and override the compareTo method to specify how the objects should be sorted. 要在列表上实现排序, BeanInterface类将实现Comparable接口并覆盖compareTo方法以指定对象的排序方式。 Then you can sort the list using Collections.sort(list) . 然后,您可以使用Collections.sort(list)对列表进行排序。 Assuming BeanInterface has a method called getSortOrder that returns an Integer object specifying the object's sort order, you could do something like this: 假设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());
    }
}

Then you can sort the list like this: 然后你可以像这样排序列表:

Collections.sort(list);

There is a jira issue about that feature in spring. 春天有一个关于这个功能的jira问题。 I have added an implementation of beanfactory in the comment which im currently using to support that feature: 我在评论中添加了beanfactory的实现,我目前正在使用它来支持该功能:

https://jira.springsource.org/browse/SPR-5574 https://jira.springsource.org/browse/SPR-5574

@Order annotation is here for rescue. @Order注释在这里是为了救援。

I am using SpringBoot 2.6.1 and its a working code snippet for me without adding any @PostConstruct to apply the sorting explicitely.我正在使用SpringBoot 2.6.1及其对我来说是一个工作代码片段,而没有添加任何@PostConstruct来明确应用排序。

interface MyFilter {
  
}

Below are multiple implementations for the interface下面是接口的多种实现

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


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


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

And below is the class where the list of MyFilter implementation needs to be injected.下面是需要注入 MyFilter 实现列表的 class。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM