2929import org .springframework .beans .factory .BeanFactoryUtils ;
3030import org .springframework .beans .factory .ObjectFactory ;
3131import org .springframework .beans .factory .ObjectProvider ;
32- import org .springframework .beans .factory .annotation .Autowired ;
3332import org .springframework .beans .factory .annotation .Qualifier ;
3433import org .springframework .context .ApplicationContext ;
3534import org .springframework .context .annotation .Bean ;
8988import org .springframework .data .rest .webmvc .support .RepositoryEntityLinks ;
9089import org .springframework .data .util .AnnotatedTypeScanner ;
9190import org .springframework .data .util .Lazy ;
91+ import org .springframework .data .util .StreamUtils ;
9292import org .springframework .data .web .HateoasPageableHandlerMethodArgumentResolver ;
9393import org .springframework .data .web .HateoasSortHandlerMethodArgumentResolver ;
9494import org .springframework .data .web .config .EnableSpringDataWebSupport ;
@@ -156,48 +156,43 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon
156156 private static final boolean IS_JPA_AVAILABLE = ClassUtils .isPresent ("javax.persistence.EntityManager" ,
157157 RepositoryRestMvcConfiguration .class .getClassLoader ());
158158
159- @ Autowired ApplicationContext applicationContext ;
159+ private final ApplicationContext applicationContext ;
160+ private final ConversionService defaultConversionService ;
160161
161- @ Autowired (required = false ) List <EntityLookup <?>> lookups = Collections .emptyList ();
162-
163- @ Autowired List <HttpMessageConverter <?>> defaultMessageConverters ;
164-
165- ObjectProvider <LinkRelationProvider > relProvider ;
166- ObjectProvider <CurieProvider > curieProvider ;
167- ObjectProvider <HalConfiguration > halConfiguration ;
168- ObjectProvider <ObjectMapper > objectMapper ;
169- ObjectProvider <RepresentationModelProcessorInvoker > invoker ;
170- ObjectProvider <MessageResolver > resolver ;
171- ObjectProvider <GeoModule > geoModule ;
172- ObjectProvider <AuditableBeanWrapperFactory > auditingBeanWrapperFactoryProvider ;
173-
174- ConversionService defaultConversionService ;
162+ private final ObjectProvider <LinkRelationProvider > relProvider ;
163+ private final ObjectProvider <CurieProvider > curieProvider ;
164+ private final ObjectProvider <HalConfiguration > halConfiguration ;
165+ private final ObjectProvider <ObjectMapper > objectMapper ;
166+ private final ObjectProvider <RepresentationModelProcessorInvoker > invoker ;
167+ private final ObjectProvider <MessageResolver > resolver ;
168+ private final ObjectProvider <GeoModule > geoModule ;
169+ private final ObjectProvider <PathPatternParser > parser ;
175170
176171 private final Lazy <ObjectMapper > mapper ;
177- private final ObjectProvider <PathPatternParser > parser ;
172+ private final Lazy <? extends List <EntityLookup <?>>> lookups ;
173+ private final Lazy <? extends List <HttpMessageConverter <?>>> defaultMessageConverters ;
174+ private final Lazy <RepositoryRestConfigurerDelegate > configurerDelegate ;
175+ private final Lazy <SelfLinkProvider > selfLinkProvider ;
176+ private final Lazy <PersistentEntityResourceHandlerMethodArgumentResolver > persistentEntityArgumentResolver ;
177+ private final Lazy <RootResourceInformationHandlerMethodArgumentResolver > repoRequestArgumentResolver ;
178+ private final Lazy <BaseUri > baseUri ;
179+ private final Lazy <RepositoryResourceMappings > resourceMappings ;
180+ private final Lazy <Repositories > repositories ;
181+ private final Lazy <ResourceMetadataHandlerMethodArgumentResolver > resourceMetadataHandlerMethodArgumentResolver ;
182+ private final Lazy <ExcerptProjector > excerptProjector ;
183+ private final Lazy <PersistentEntities > persistentEntities ;
184+ private final Lazy <BackendIdHandlerMethodArgumentResolver > backendIdHandlerMethodArgumentResolver ;
185+ private final Lazy <Associations > associationLinks ;
186+ private final Lazy <EnumTranslator > enumTranslator ;
187+ private final Lazy <ServerHttpRequestMethodArgumentResolver > serverHttpRequestMethodArgumentResolver ;
188+ private final Lazy <ETagArgumentResolver > eTagArgumentResolver ;
189+ private final Lazy <RepositoryInvokerFactory > repositoryInvokerFactory ;
190+ private final Lazy <RepositoryRestConfiguration > repositoryRestConfiguration ;
191+ private final Lazy <HateoasPageableHandlerMethodArgumentResolver > pageableResolver ;
192+ private final Lazy <HateoasSortHandlerMethodArgumentResolver > sortResolver ;
178193
179194 private ClassLoader beanClassLoader ;
180195
181- private Lazy <RepositoryRestConfigurerDelegate > configurerDelegate ;
182- private Lazy <SelfLinkProvider > selfLinkProvider ;
183- private Lazy <PersistentEntityResourceHandlerMethodArgumentResolver > persistentEntityArgumentResolver ;
184- private Lazy <RootResourceInformationHandlerMethodArgumentResolver > repoRequestArgumentResolver ;
185- private Lazy <BaseUri > baseUri ;
186- private Lazy <RepositoryResourceMappings > resourceMappings ;
187- private Lazy <Repositories > repositories ;
188- private Lazy <ResourceMetadataHandlerMethodArgumentResolver > resourceMetadataHandlerMethodArgumentResolver ;
189- private Lazy <ExcerptProjector > excerptProjector ;
190- private Lazy <PersistentEntities > persistentEntities ;
191- private Lazy <BackendIdHandlerMethodArgumentResolver > backendIdHandlerMethodArgumentResolver ;
192- private Lazy <Associations > associationLinks ;
193- private Lazy <EnumTranslator > enumTranslator ;
194- private Lazy <ServerHttpRequestMethodArgumentResolver > serverHttpRequestMethodArgumentResolver ;
195- private Lazy <ETagArgumentResolver > eTagArgumentResolver ;
196- private Lazy <RepositoryInvokerFactory > repositoryInvokerFactory ;
197- private Lazy <RepositoryRestConfiguration > repositoryRestConfiguration ;
198- private Lazy <HateoasPageableHandlerMethodArgumentResolver > pageableResolver ;
199- private Lazy <HateoasSortHandlerMethodArgumentResolver > sortResolver ;
200-
201196 public RepositoryRestMvcConfiguration ( //
202197 ApplicationContext context , //
203198 @ Qualifier ("mvcConversionService" ) ObjectFactory <ConversionService > conversionService , //
@@ -212,6 +207,7 @@ public RepositoryRestMvcConfiguration( //
212207
213208 super (context , conversionService );
214209
210+ this .applicationContext = context ;
215211 this .relProvider = relProvider ;
216212 this .curieProvider = curieProvider ;
217213 this .halConfiguration = halConfiguration ;
@@ -220,6 +216,7 @@ public RepositoryRestMvcConfiguration( //
220216 this .resolver = resolver ;
221217 this .geoModule = geoModule ;
222218 this .parser = parser ;
219+ this .defaultConversionService = new DefaultFormattingConversionService ();
223220
224221 this .mapper = Lazy .of (() -> {
225222
@@ -255,11 +252,10 @@ public RepositoryRestMvcConfiguration( //
255252 this .serverHttpRequestMethodArgumentResolver = Lazy
256253 .of (() -> context .getBean (ServerHttpRequestMethodArgumentResolver .class ));
257254 this .eTagArgumentResolver = Lazy .of (() -> context .getBean (ETagArgumentResolver .class ));
255+
258256 this .repositoryInvokerFactory = Lazy .of (() -> new UnwrappingRepositoryInvokerFactory (
259257 new DefaultRepositoryInvokerFactory (repositories .get (), defaultConversionService ), getEntityLookups ()));
260258
261- this .defaultConversionService = new DefaultFormattingConversionService ();
262-
263259 this .configurerDelegate = Lazy .of (() -> {
264260
265261 return new RepositoryRestConfigurerDelegate (context .getBeanProvider (RepositoryRestConfigurer .class )
@@ -270,6 +266,11 @@ public RepositoryRestMvcConfiguration( //
270266 this .repositoryRestConfiguration = Lazy .of (() -> context .getBean (RepositoryRestConfiguration .class ));
271267 this .pageableResolver = Lazy .of (() -> context .getBean (HateoasPageableHandlerMethodArgumentResolver .class ));
272268 this .sortResolver = Lazy .of (() -> context .getBean (HateoasSortHandlerMethodArgumentResolver .class ));
269+
270+ // Resolution via ResolvableType needed to make the wildcard assignment work
271+
272+ this .lookups = beansOfType (context , EntityLookup .class );
273+ this .defaultMessageConverters = beansOfType (context , HttpMessageConverter .class );
273274 }
274275
275276 /*
@@ -751,7 +752,7 @@ public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> excep
751752 ExceptionHandlerExceptionResolver er = new ExceptionHandlerExceptionResolver ();
752753 er .setCustomArgumentResolvers (defaultMethodArgumentResolvers (selfLinkProvider .get (),
753754 persistentEntityArgumentResolver .get (), repoRequestArgumentResolver .get ()));
754- er .setMessageConverters (defaultMessageConverters );
755+ er .setMessageConverters (defaultMessageConverters . get () );
755756
756757 configurerDelegate .get ().configureExceptionHandlerExceptionResolver (er );
757758
@@ -886,7 +887,7 @@ protected List<EntityLookup<?>> getEntityLookups() {
886887
887888 List <EntityLookup <?>> lookups = new ArrayList <>();
888889 lookups .addAll (repositoryRestConfiguration .get ().getEntityLookups (repositories .get ()));
889- lookups .addAll (this .lookups );
890+ lookups .addAll (this .lookups . get () );
890891
891892 return lookups ;
892893 }
@@ -997,6 +998,23 @@ public void addResourceHandlers(ResourceHandlerRegistry registry) {
997998 .forEach (it -> it .customizeResources (registry , repositoryRestConfiguration .get ()));
998999 }
9991000
1001+ /**
1002+ * Helper to be able to obtain a {@link List} of generic types. Otherwise the assignment from {@code Foo} to
1003+ * {@code Foo<?>} doesn't work.
1004+ *
1005+ * @param <S>
1006+ * @param context
1007+ * @param type
1008+ * @return
1009+ */
1010+ @ SuppressWarnings ("unchecked" )
1011+ private static <S > Lazy <List <S >> beansOfType (ApplicationContext context , Class <?> type ) {
1012+
1013+ return Lazy .of (() -> (List <S >) context .getBeanProvider (type )
1014+ .orderedStream ()
1015+ .collect (StreamUtils .toUnmodifiableList ()));
1016+ }
1017+
10001018 private static class ResourceSupportHttpMessageConverter extends TypeConstrainedMappingJackson2HttpMessageConverter
10011019 implements Ordered {
10021020
0 commit comments