#1252 - Make sure HypermediaWebTestClientConfigurer is only included with spring-test on the classpath.
HypermediaConfigurationImportSelector is now ResourceLoaderAware to make sure it uses the class loader used to bootstrap the application context. This is important for both testing as well as custom classloader arrangements like Boot's DevTools. We now only include WebTestHateoasConfiguration if WebTestClient is on the classpath. The configuration class has been extracted to not leak references to code tied to spring-test into production deployments. Added test cases to check both the inclusion and exclusion of the configuration classes based on the classpath arrangement. Original pull request: #1251.
This commit is contained in:
committed by
Oliver Drotbohm
parent
599a366c85
commit
de38b9e200
@@ -20,26 +20,44 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.context.ResourceLoaderAware;
|
||||
import org.springframework.context.annotation.ImportSelector;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* {@link ImportSelector} that looks up configuration classes from all {@link MediaTypeConfigurationProvider}
|
||||
* implementations listed in {@code META-INF/spring.factories}.
|
||||
*
|
||||
* @author Oliver Drotbohm
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
class HypermediaConfigurationImportSelector implements ImportSelector {
|
||||
class HypermediaConfigurationImportSelector implements ImportSelector, ResourceLoaderAware {
|
||||
|
||||
public static final String SPRING_TEST = "org.springframework.test.web.reactive.server.WebTestClient";
|
||||
|
||||
private ResourceLoader resourceLoader;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.annotation.ImportSelector#selectImports(org.springframework.core.type.AnnotationMetadata)
|
||||
* @see org.springframework.context.ResourceLoaderAware#setResourceLoader(org.springframework.core.io.ResourceLoader)
|
||||
*/
|
||||
@Override
|
||||
public void setResourceLoader(ResourceLoader resourceLoader) {
|
||||
this.resourceLoader = resourceLoader;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.annotation.ImportSelector#selectImports(org.springframework.core.type.AnnotationMetadata)
|
||||
*/
|
||||
@Override
|
||||
public String[] selectImports(AnnotationMetadata metadata) {
|
||||
|
||||
Map<String, Object> attributes = metadata.getAnnotationAttributes(EnableHypermediaSupport.class.getName());
|
||||
@@ -54,11 +72,17 @@ class HypermediaConfigurationImportSelector implements ImportSelector {
|
||||
MediaTypeConfigurationProvider.class, HypermediaConfigurationImportSelector.class.getClassLoader());
|
||||
|
||||
// Filter the ones supporting the given media types
|
||||
return configurationProviders.stream() //
|
||||
Stream<String> imports = configurationProviders.stream() //
|
||||
.filter(it -> it.supportsAny(types)) //
|
||||
.map(MediaTypeConfigurationProvider::getConfiguration) //
|
||||
.map(Class::getName) //
|
||||
.toArray(String[]::new);
|
||||
.map(Class::getName);
|
||||
|
||||
// Conditionally apply other configurations
|
||||
if (ClassUtils.isPresent(SPRING_TEST, resourceLoader.getClassLoader())) {
|
||||
imports = Stream.concat(imports, Stream.of(WebTestHateoasConfiguration.class.getName()));
|
||||
}
|
||||
|
||||
return imports.toArray(String[]::new);
|
||||
}
|
||||
|
||||
public String[] selectImports(List<MediaType> mediaType) {
|
||||
|
||||
@@ -37,7 +37,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
*/
|
||||
public class HypermediaWebClientConfigurer {
|
||||
|
||||
Consumer<ClientCodecConfigurer> configurer;
|
||||
final Consumer<ClientCodecConfigurer> configurer;
|
||||
|
||||
/**
|
||||
* Creates a new {@link HypermediaWebClientConfigurer} for the given {@link ObjectMapper} and
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
@@ -45,13 +44,6 @@ class WebClientHateoasConfiguration {
|
||||
return new HypermediaWebClientConfigurer(mapper.getIfAvailable(ObjectMapper::new), hypermediaTypes);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Lazy
|
||||
HypermediaWebTestClientConfigurer webTestClientConfigurer(ObjectProvider<ObjectMapper> mapper,
|
||||
List<HypermediaMappingInformation> hypermediaTypes) {
|
||||
return new HypermediaWebTestClientConfigurer(mapper.getIfAvailable(ObjectMapper::new), hypermediaTypes);
|
||||
}
|
||||
|
||||
@Bean
|
||||
static HypermediaWebClientBeanPostProcessor webClientBeanPostProcessor(HypermediaWebClientConfigurer configurer) {
|
||||
return new HypermediaWebClientBeanPostProcessor(configurer);
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.hateoas.config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* Configuration for Spring TEST-specific things
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @author Oliver Drotbohm
|
||||
* @since 1.1
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
class WebTestHateoasConfiguration {
|
||||
|
||||
@Bean
|
||||
@Lazy
|
||||
HypermediaWebTestClientConfigurer webTestClientConfigurer(ObjectProvider<ObjectMapper> mapper,
|
||||
List<HypermediaMappingInformation> hypermediaTypes) {
|
||||
return new HypermediaWebTestClientConfigurer(mapper.getIfAvailable(ObjectMapper::new), hypermediaTypes);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user