[英]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.