RepositoryRestConfigurer are again used in declared order.

4b36f79 introduced a regression by consuming registered RepositoryRestConfigurer instances via ApplicationContext.getBeansOfType(…).values() which, unlike the previous consumption via a List<RRC> in an @Bean method, is losing the declared order of the RRC instances as ….getBeansOfType() is a Map.

We now rather use an ObjectProvider and its ….orderedStream() method to consume the registered instances ordered properly.

Fixes #1995.
This commit is contained in:
Oliver Drotbohm
2021-04-09 12:42:24 +02:00
parent b4b8fdfee0
commit 6c007487c7
2 changed files with 32 additions and 2 deletions

View File

@@ -23,6 +23,7 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanFactoryUtils;
@@ -259,7 +260,10 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon
this.defaultConversionService = new DefaultFormattingConversionService();
this.configurerDelegate = Lazy.of(() -> {
return new RepositoryRestConfigurerDelegate(context.getBeansOfType(RepositoryRestConfigurer.class).values());
return new RepositoryRestConfigurerDelegate(context.getBeanProvider(RepositoryRestConfigurer.class)
.orderedStream()
.collect(Collectors.toList()));
});
this.repositoryRestConfiguration = Lazy.of(() -> context.getBean(RepositoryRestConfiguration.class));

View File

@@ -28,7 +28,6 @@ import javax.naming.ldap.LdapName;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@@ -36,6 +35,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort.Direction;
@@ -45,6 +45,8 @@ import org.springframework.data.rest.webmvc.RepositoryLinksResource;
import org.springframework.data.rest.webmvc.RestMediaTypes;
import org.springframework.data.rest.webmvc.alps.AlpsJsonHttpMessageConverter;
import org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module;
import org.springframework.data.util.Lazy;
import org.springframework.data.util.Streamable;
import org.springframework.data.web.HateoasPageableHandlerMethodArgumentResolver;
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
import org.springframework.hateoas.MediaTypes;
@@ -54,6 +56,7 @@ import org.springframework.hateoas.server.mvc.TypeConstrainedMappingJackson2Http
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.util.MultiValueMap;
import org.springframework.web.util.UriComponentsBuilder;
@@ -192,6 +195,22 @@ public class RepositoryRestMvConfigurationIntegrationTests {
assertThat(service.canConvert(String.class, LdapName.class)).isTrue();
}
@Test // #1995
@SuppressWarnings("unchecked")
public void registersRepositoryRestConfigurersInDeclaredOrder() {
RepositoryRestMvcConfiguration configuration = context.getBean(RepositoryRestMvcConfiguration.class);
ExtendingConfiguration userConfig = context.getBean(ExtendingConfiguration.class);
Lazy<RepositoryRestConfigurerDelegate> delegate = (Lazy<RepositoryRestConfigurerDelegate>) ReflectionTestUtils
.getField(configuration, "configurerDelegate");
Iterable<RepositoryRestConfigurer> configurations = (Iterable<RepositoryRestConfigurer>) ReflectionTestUtils
.getField(delegate.get(), "delegates");
assertThat(Streamable.of(configurations).toList())
.containsSequence(userConfig.otherConfigurer(), userConfig.configurer());
}
private static ObjectMapper getObjectMapper() {
AbstractJackson2HttpMessageConverter converter = context.getBean("halJacksonHttpMessageConverter",
@@ -214,6 +233,7 @@ public class RepositoryRestMvConfigurationIntegrationTests {
}
@Bean
@Order(200)
RepositoryRestConfigurer configurer() {
return RepositoryRestConfigurer.withConfig(config -> {
@@ -225,6 +245,12 @@ public class RepositoryRestMvConfigurationIntegrationTests {
config.setSortParamName("mySort");
});
}
@Bean
@Order(100)
RepositoryRestConfigurer otherConfigurer() {
return RepositoryRestConfigurer.withConfig(__ -> {});
}
}
@Configuration