我的库必须处理多个bean(拦截器)以任意顺序指定的(因为它们分布在多个配置文件中)。在应用它们之前,我必须按照它们的优先级对它们进行排序。我使用AnnotationAwareOrderComparator.sort(beans)
来实现这一点。只要@Order
注解添加在拦截器的类级别上,它就可以很好地工作。但是当我尝试在@中使用它时,它就不起作用了@Bean方法上的配置类:
@Configuration
public class Config {
@Bean
@Order(1)
public ServerInterceptor exceptionTranslatingServerInterceptor() {
return ...;
}
@Bean
@Order(2)
public ServerInterceptor authenticatingServerInterceptor() {
return ...;
}
@Bean
@Order(3)
public ServerInterceptor authorizationCheckingServerInterceptor() {
return ...
}
}
但如果我添加一个这样的测试:
@Test
void testOrderingOfTheDefaultInterceptors() {
List<ServerInterceptor> expected = new ArrayList<>();
expected.add(applicationContext.getBean(ExceptionTranslatingServerInterceptor.class));
expected.add(applicationContext.getBean(AuthenticatingServerInterceptor.class));
expected.add(applicationContext.getBean(AuthorizationCheckingServerInterceptor.class));
List<ServerInterceptor> actual = new ArrayList<>(this.registry.getServerInterceptors());
assertEquals(expected, actual); // Accidentally passes
// System.out.println(actual);
Collections.shuffle(actual);
AnnotationAwareOrderComparator.sort(actual);
assertEquals(expected, actual); // Fails
// System.out.println(actual);
}
那么测试将失败。从我的调试中我知道AnnotationAwareOrderComparator.findOrder(Object)
总是为那些bean的顺序返回null(未指定)。可能是因为bean示例没有被代理,因此既没有实现order,也没有类级别上的order注解。是否有BeanPostProcessor或配置选项需要启用?
我如何告诉spring保持注解顺序或者使用应用程序上下文的bean定义来适当地对bean进行排序?
2条答案
按热度按时间0g0grzrc1#
要使测试用例正常工作,您需要使用
Ordered
接口而不是注解。让我们检查AnnotationAwareOrderComparator的源代码。请注意,您是直接将对象传递给sort方法的。AnnotationAwareOrderComparator正在使用pased对象上的findOrder
,以便查找三个工件@Priority
注解@Order
注解或@Ordered
之一接口。在您的例子中,您正在传递拦截器示例,因此对Methidf和Class的if检查将返回false。您将命中最后一个if方法:if (obj != null)
在这种情况下,它只会检查对象类中@Order注解,在您的情况下,该注解将为null。2实际上,您的测试用例是错误的。3请注意,如果您实现了Ordered接口,您的测试用例将按预期的方式运行。
ykejflvf2#
我找到了一种方法来访问仅出现在bean工厂方法中的注解:
来源:易东楠/grpc-spring-boot-starter/拦截器订单