DATAREST-1567 - Replace component scan with explicit bean methods.
We replaced the component scan in RespositoryRestMvcConfiguration with dedicated bean methods. This allows us to be more explicit in resolving required components, which is required for better support of GraalVM native image. Original pull request: #382.
This commit is contained in:
committed by
Oliver Drotbohm
parent
060c84dcf3
commit
8ff438678d
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.halexplorer;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
|
||||
import org.springframework.data.rest.webmvc.config.StaticResourceProvider;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
@@ -23,9 +25,11 @@ import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
|
||||
* {@link StaticResourceProvider} to expose the HAL Browser WebJar content via a static resource route.
|
||||
*
|
||||
* @author Oliver Drotbohm
|
||||
* @author Christoph Strobl
|
||||
* @since 3.2
|
||||
* @soundtrack Tedeschi Trucks Band - Signs, High Times (Signs)
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
class HalExplorerConfiguration implements StaticResourceProvider {
|
||||
|
||||
/*
|
||||
@@ -39,4 +43,17 @@ class HalExplorerConfiguration implements StaticResourceProvider {
|
||||
|
||||
registry.addResourceHandler(basePath.concat("/**")).addResourceLocations(rootLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* The controller that exposes the {@link HalExplorer}.
|
||||
*
|
||||
* @return never {@literal null}.
|
||||
* @since 3.4
|
||||
*/
|
||||
@Bean
|
||||
HalExplorer halExplorer() {
|
||||
|
||||
// TODO: maybe register this one directly on mvc via WebMvcConfigurer.addRedirectVieController()
|
||||
return new HalExplorer();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright 2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.repository.support.Repositories;
|
||||
import org.springframework.data.repository.support.RepositoryInvokerFactory;
|
||||
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
|
||||
import org.springframework.data.rest.core.mapping.RepositoryResourceMappings;
|
||||
import org.springframework.data.rest.webmvc.alps.AlpsController;
|
||||
import org.springframework.data.rest.webmvc.json.JsonSchema;
|
||||
import org.springframework.data.rest.webmvc.json.PersistentEntityToJsonSchemaConverter;
|
||||
import org.springframework.data.rest.webmvc.support.RepositoryEntityLinks;
|
||||
import org.springframework.data.web.PagedResourcesAssembler;
|
||||
import org.springframework.hateoas.server.EntityLinks;
|
||||
|
||||
/**
|
||||
* Configuration class registering required {@link org.springframework.stereotype.Component components} that declare
|
||||
* request mappings as {@link Bean beans}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @since 3.4
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class RestControllerConfiguration {
|
||||
|
||||
private final RepositoryRestConfiguration restConfiguration;
|
||||
private final RepositoryResourceMappings resourceMappings;
|
||||
private final PagedResourcesAssembler<Object> resourcesAssembler;
|
||||
private final Repositories repositories;
|
||||
|
||||
RestControllerConfiguration(RepositoryRestConfiguration restConfiguration,
|
||||
RepositoryResourceMappings resourceMappings, PagedResourcesAssembler<Object> resourcesAssembler,
|
||||
Repositories repositories) {
|
||||
|
||||
this.restConfiguration = restConfiguration;
|
||||
this.resourceMappings = resourceMappings;
|
||||
this.resourcesAssembler = resourcesAssembler;
|
||||
this.repositories = repositories;
|
||||
}
|
||||
|
||||
/**
|
||||
* The controller for the root resource exposing links to the repository resources.
|
||||
*
|
||||
* @param entityLinks the accessor to links pointing to controllers backing an entity type. Must not be
|
||||
* {@literal null}.
|
||||
* @return never {@literal null}.
|
||||
*/
|
||||
@Bean
|
||||
protected RepositoryController repositoryController(EntityLinks entityLinks) {
|
||||
return new RepositoryController(resourcesAssembler, repositories, entityLinks, resourceMappings);
|
||||
}
|
||||
|
||||
/**
|
||||
* The root controller for entities reachable via {@code /{repository}}.
|
||||
*
|
||||
* @param entityLinks the accessor to links pointing to controllers backing an entity type. Must not be *
|
||||
* {@literal null}.
|
||||
* @param headersPreparer must not be {@literal null}.
|
||||
* @return never {@literal null}.
|
||||
*/
|
||||
@Bean
|
||||
protected RepositoryEntityController repositoryEntityController(RepositoryEntityLinks entityLinks,
|
||||
HttpHeadersPreparer headersPreparer) {
|
||||
return new RepositoryEntityController(repositories, restConfiguration, entityLinks, resourcesAssembler,
|
||||
headersPreparer);
|
||||
}
|
||||
|
||||
/**
|
||||
* The controller to access referenced properties via {@code /{repository}/{id}/{property}}.
|
||||
*
|
||||
* @param repositoryInvokerFactory must not be {@literal null}.
|
||||
* @return never {@literal null}.
|
||||
*/
|
||||
@Bean
|
||||
protected RepositoryPropertyReferenceController repositoryPropertyReferenceController(
|
||||
RepositoryInvokerFactory repositoryInvokerFactory) {
|
||||
return new RepositoryPropertyReferenceController(repositories, repositoryInvokerFactory, resourcesAssembler);
|
||||
}
|
||||
|
||||
/**
|
||||
* The controller that performs lookups and executes searches.
|
||||
*
|
||||
* @param entityLinks he accessor to links pointing to controllers backing an entity type. Must not be *
|
||||
* {@literal null}.
|
||||
* @param headersPreparer must not be {@literal null}.
|
||||
* @return never {@literal null}.
|
||||
*/
|
||||
@Bean
|
||||
protected RepositorySearchController repositorySearchController(RepositoryEntityLinks entityLinks,
|
||||
HttpHeadersPreparer headersPreparer) {
|
||||
return new RepositorySearchController(resourcesAssembler, entityLinks, resourceMappings, headersPreparer);
|
||||
}
|
||||
|
||||
/**
|
||||
* The controller that exposes the JSON schema via {@code /repository/schema}.
|
||||
*
|
||||
* @param jsonSchemaConverter the converter to create the {@link JsonSchema}. Must not be {@literal null}.
|
||||
* @return never {@literal null}.
|
||||
*/
|
||||
@Bean
|
||||
protected RepositorySchemaController repositorySchemaController(
|
||||
PersistentEntityToJsonSchemaConverter jsonSchemaConverter) {
|
||||
return new RepositorySchemaController(jsonSchemaConverter);
|
||||
}
|
||||
|
||||
/**
|
||||
* The controller that exposes semantic documentation in the <a href="http://alps.io/">ALPS</a> (Application Level
|
||||
* Profile Semantics) format.
|
||||
*
|
||||
* @return never {@literal null}.
|
||||
*/
|
||||
@Bean
|
||||
protected AlpsController alpsController() {
|
||||
return new AlpsController(restConfiguration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Profile-based controller exposing multiple forms of metadata via {@code /profile}.
|
||||
*
|
||||
* @return never {@literal null}.
|
||||
*/
|
||||
@Bean
|
||||
protected ProfileController profileController() {
|
||||
return new ProfileController(restConfiguration, resourceMappings, repositories);
|
||||
}
|
||||
}
|
||||
@@ -32,8 +32,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
@@ -144,13 +142,13 @@ import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
|
||||
* @author Jon Brisbin
|
||||
* @author Greg Turnquist
|
||||
* @author Mark Paluch
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableHypermediaSupport(type = HypermediaType.HAL)
|
||||
@ComponentScan(basePackageClasses = RepositoryRestController.class,
|
||||
includeFilters = @Filter(BasePathAwareController.class), useDefaultFilters = false)
|
||||
@ImportResource("classpath*:META-INF/spring-data-rest/**/*.xml")
|
||||
@Import({ SpringDataJacksonConfiguration.class, EnableSpringDataWebSupport.QuerydslActivator.class })
|
||||
@Import({ RestControllerImportSelector.class, SpringDataJacksonConfiguration.class,
|
||||
EnableSpringDataWebSupport.QuerydslActivator.class })
|
||||
public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebConfiguration
|
||||
implements BeanClassLoaderAware {
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.config;
|
||||
|
||||
import org.springframework.context.annotation.ImportSelector;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.data.rest.webmvc.RestControllerConfiguration;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* {@link ImportSelector} choosing additional controller configuration (eg. for the {@litearl Hal Explorer}) when
|
||||
* present.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @since 3.4
|
||||
*/
|
||||
class RestControllerImportSelector implements ImportSelector {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.annotation.ImportSelector#selectImports(org.springframework.core.type.AnnotationMetadata)
|
||||
*/
|
||||
@Override
|
||||
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
|
||||
|
||||
if (ClassUtils.isPresent("org.springframework.data.rest.webmvc.halexplorer.HalExplorerConfiguration",
|
||||
importingClassMetadata.getClass().getClassLoader())) {
|
||||
|
||||
return new String[] { RestControllerConfiguration.class.getName(),
|
||||
"org.springframework.data.rest.webmvc.halexplorer.HalExplorerConfiguration" };
|
||||
}
|
||||
|
||||
return new String[] { RestControllerConfiguration.class.getName() };
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user