From 1e78de5eac5e639ffdead6f5dcba47ae5c1928f9 Mon Sep 17 00:00:00 2001 From: Oliver Drotbohm Date: Mon, 14 Dec 2020 18:50:40 +0100 Subject: [PATCH] DATAREST-1590 - Avoid need for eager access to components in RepositoryRestMvcConfiguration. Switch to ObjectProvider for all component dependencies in the constructor of RepositoryRestMvcConfiguration. Made the bean definition of AnnotatedEventHandlerInvoker a static bean as it's an application listener and it being an instance method causes extend initialization of the configuration class trickling down into unnecessary bean lookups that early in the lifecycle. --- .../RepositoryRestMvcConfiguration.java | 54 ++++++++++--------- .../webmvc/support/RepositoryEntityLinks.java | 18 +++++-- 2 files changed, 42 insertions(+), 30 deletions(-) diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java index e8a3f18fb..2954399db 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java @@ -158,18 +158,17 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon @Autowired ApplicationContext applicationContext; @Autowired(required = false) List idConverters = Collections.emptyList(); - @Autowired(required = false) List configurers = Collections.emptyList(); @Autowired(required = false) List> lookups = Collections.emptyList(); @Autowired List> defaultMessageConverters; - Optional relProvider; - Optional curieProvider; - Optional halConfiguration; + ObjectProvider relProvider; + ObjectProvider curieProvider; + ObjectProvider halConfiguration; ObjectProvider objectMapper; ObjectProvider invoker; - MessageResolver resolver; - GeoModule geoModule; + ObjectProvider resolver; + ObjectProvider geoModule; ConversionService defaultConversionService; private final Lazy mapper; @@ -200,13 +199,13 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon public RepositoryRestMvcConfiguration( // ApplicationContext context, // @Qualifier("mvcConversionService") ObjectFactory conversionService, // - Optional relProvider, // - Optional curieProvider, // - Optional halConfiguration, // + ObjectProvider relProvider, // + ObjectProvider curieProvider, // + ObjectProvider halConfiguration, // ObjectProvider objectMapper, // ObjectProvider invoker, // - MessageResolver resolver, // - GeoModule geoModule) { + ObjectProvider resolver, // + ObjectProvider geoModule) { super(context, conversionService); @@ -389,7 +388,7 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon * @return */ @Bean - public AnnotatedEventHandlerInvoker annotatedEventHandlerInvoker() { + public static AnnotatedEventHandlerInvoker annotatedEventHandlerInvoker() { return new AnnotatedEventHandlerInvoker(); } @@ -456,13 +455,17 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon * @throws Exception */ @Bean - public RepositoryEntityLinks entityLinks(HateoasPageableHandlerMethodArgumentResolver pageableResolver, - Repositories repositories, RepositoryResourceMappings resourceMappings, - PluginRegistry> backendIdConverterRegistry, - RepositoryRestConfiguration repositoryRestConfiguration, HateoasSortHandlerMethodArgumentResolver sortResolver) { + public RepositoryEntityLinks entityLinks(ObjectFactory pageableResolver, // + Repositories repositories, // + RepositoryResourceMappings resourceMappings, // + PluginRegistry> backendIdConverterRegistry, // + RepositoryRestConfiguration repositoryRestConfiguration, // + ObjectFactory sortResolver) { - PagingAndSortingTemplateVariables templateVariables = new ArgumentResolverPagingAndSortingTemplateVariables( - pageableResolver, sortResolver); + Lazy templateVariables = Lazy + .of(() -> new ArgumentResolverPagingAndSortingTemplateVariables(pageableResolver.getObject(), + sortResolver.getObject())); return new RepositoryEntityLinks(repositories, resourceMappings, repositoryRestConfiguration, templateVariables, backendIdConverterRegistry); @@ -497,7 +500,8 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon Associations associationLinks, @Qualifier RepositoryInvokerFactory repositoryInvokerFactory, RepositoryRestConfiguration repositoryRestConfiguration) { - return new PersistentEntityToJsonSchemaConverter(persistentEntities, associationLinks, resolver, objectMapper(), + return new PersistentEntityToJsonSchemaConverter(persistentEntities, associationLinks, resolver.getObject(), + objectMapper(), repositoryRestConfiguration, new ValueTypeSchemaPropertyCustomizerFactory(repositoryInvokerFactory)); } @@ -569,11 +573,11 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon public ObjectMapper halObjectMapper(LinkCollector linkCollector) { - LinkRelationProvider defaultedRelProvider = this.relProvider.orElseGet(EvoInflectorLinkRelationProvider::new); - HalConfiguration halConfiguration = this.halConfiguration.orElseGet(HalConfiguration::new); - + LinkRelationProvider defaultedRelProvider = this.relProvider.getIfUnique(EvoInflectorLinkRelationProvider::new); + HalConfiguration halConfiguration = this.halConfiguration.getIfUnique(HalConfiguration::new); HalHandlerInstantiator instantiator = new HalHandlerInstantiator(defaultedRelProvider, - curieProvider.orElse(new DefaultCurieProvider(Collections.emptyMap())), resolver, halConfiguration); + curieProvider.getIfUnique(() -> new DefaultCurieProvider(Collections.emptyMap())), resolver.getObject(), + halConfiguration); ObjectMapper mapper = basicObjectMapper(); mapper.registerModule(persistentEntityJackson2Module(linkCollector)); @@ -885,7 +889,7 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon // Configure custom Modules configurerDelegate.get().configureJacksonObjectMapper(objectMapper); - objectMapper.registerModule(geoModule); + objectMapper.registerModule(geoModule.getObject()); if (repositoryRestConfiguration.get().isEnableEnumTranslation()) { objectMapper.registerModule(new JacksonSerializers(enumTranslator.get())); @@ -926,7 +930,7 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon Associations associationLinks, RepositoryRestConfiguration repositoryRestConfiguration) { return new RootResourceInformationToAlpsDescriptorConverter(associationLinks, repositories, persistentEntities, - entityLinks, resolver, repositoryRestConfiguration, objectMapper(), enumTranslator); + entityLinks, resolver.getObject(), repositoryRestConfiguration, objectMapper(), enumTranslator); } @Bean diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryEntityLinks.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryEntityLinks.java index 22f02c9ce..e95c3e236 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryEntityLinks.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryEntityLinks.java @@ -35,6 +35,7 @@ import org.springframework.data.rest.core.mapping.SearchResourceMappings; import org.springframework.data.rest.webmvc.BaseUri; import org.springframework.data.rest.webmvc.spi.BackendIdConverter; import org.springframework.data.rest.webmvc.spi.BackendIdConverter.DefaultIdConverter; +import org.springframework.data.util.Lazy; import org.springframework.hateoas.Link; import org.springframework.hateoas.LinkRelation; import org.springframework.hateoas.Links; @@ -62,11 +63,18 @@ public class RepositoryEntityLinks extends AbstractEntityLinks { private final Repositories repositories; private final ResourceMappings mappings; private final RepositoryRestConfiguration config; - private final PagingAndSortingTemplateVariables templateVariables; + private final Lazy templateVariables; private final PluginRegistry> idConverters; public RepositoryEntityLinks(Repositories repositories, ResourceMappings mappings, RepositoryRestConfiguration config, PagingAndSortingTemplateVariables templateVariables, PluginRegistry> idConverters) { + this(repositories, mappings, config, Lazy.of(templateVariables), idConverters); + } + + public RepositoryEntityLinks(Repositories repositories, ResourceMappings mappings, + RepositoryRestConfiguration config, + Lazy templateVariables, + PluginRegistry> idConverters) { Assert.notNull(repositories, "Repositories must not be null!"); Assert.notNull(mappings, "ResourceMappings must not be null!"); @@ -297,7 +305,7 @@ public class RepositoryEntityLinks extends AbstractEntityLinks { private TemplateVariables getTemplateVariables(UriComponents components, ResourceMapping mapping, Pageable pageable) { if (mapping.isPagingResource()) { - return templateVariables.getPaginationTemplateVariables(null, components); + return templateVariables.get().getPaginationTemplateVariables(null, components); } else { return TemplateVariables.NONE; } @@ -317,7 +325,7 @@ public class RepositoryEntityLinks extends AbstractEntityLinks { Pageable pageable, Sort sort) { if (mapping.isSortableResource()) { - return templateVariables.getSortTemplateVariables(null, components); + return templateVariables.get().getSortTemplateVariables(null, components); } else { return getTemplateVariables(components, mapping, pageable); } @@ -362,7 +370,7 @@ public class RepositoryEntityLinks extends AbstractEntityLinks { if (mapping.isSortableResource()) { UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString(uri); - templateVariables.enhance(uriBuilder, null, sort); + templateVariables.get().enhance(uriBuilder, null, sort); return uriBuilder.build(); } else { return prepareUri(uri, mapping, pageable); @@ -374,7 +382,7 @@ public class RepositoryEntityLinks extends AbstractEntityLinks { UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString(uri); if (mapping.isPagingResource()) { - templateVariables.enhance(uriBuilder, null, pageable); + templateVariables.get().enhance(uriBuilder, null, pageable); } return uriBuilder.build();