Fix binding of classpath*: to resource arrays and collections
Fixes gh-15835
This commit is contained in:
parent
339f75d309
commit
0e3a196af5
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 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.
|
||||
|
@ -42,6 +42,7 @@ import org.springframework.core.convert.ConverterNotFoundException;
|
|||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.converter.ConditionalGenericConverter;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
|
@ -154,8 +155,8 @@ final class BindConverter {
|
|||
private static class TypeConverterConversionService extends GenericConversionService {
|
||||
|
||||
TypeConverterConversionService(Consumer<PropertyEditorRegistry> initializer) {
|
||||
addConverter(new TypeConverterConverter(initializer));
|
||||
ApplicationConversionService.addDelimitedStringConverters(this);
|
||||
addConverter(new TypeConverterConverter(initializer));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -196,16 +197,23 @@ final class BindConverter {
|
|||
|
||||
@Override
|
||||
public Set<ConvertiblePair> getConvertibleTypes() {
|
||||
return Collections.singleton(new ConvertiblePair(String.class, Object.class));
|
||||
return Set.of(new ConvertiblePair(String.class, Object.class),
|
||||
new ConvertiblePair(String.class, Object[].class),
|
||||
new ConvertiblePair(String.class, Collection.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
Class<?> type = targetType.getType();
|
||||
if (type == null || type == Object.class || Collection.class.isAssignableFrom(type)
|
||||
|| Map.class.isAssignableFrom(type)) {
|
||||
if (type == null || type == Object.class || Map.class.isAssignableFrom(type)) {
|
||||
return false;
|
||||
}
|
||||
if (Collection.class.isAssignableFrom(type)) {
|
||||
TypeDescriptor elementType = targetType.getElementTypeDescriptor();
|
||||
if (elementType == null || (!Resource.class.isAssignableFrom(elementType.getType()))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
PropertyEditor editor = this.matchesOnlyTypeConverter.getDefaultEditor(type);
|
||||
if (editor == null) {
|
||||
editor = this.matchesOnlyTypeConverter.findCustomEditor(type, null);
|
||||
|
@ -218,7 +226,7 @@ final class BindConverter {
|
|||
|
||||
@Override
|
||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||
return createTypeConverter().convertIfNecessary(source, targetType.getType());
|
||||
return createTypeConverter().convertIfNecessary(source, targetType.getType(), targetType);
|
||||
}
|
||||
|
||||
private SimpleTypeConverter createTypeConverter() {
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.time.Duration;
|
|||
import java.time.Period;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
|
@ -1173,6 +1174,22 @@ class ConfigurationPropertiesTests {
|
|||
assertThat(properties.getProp()).isEqualTo("alpha");
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadWhenBindingClasspathPatternToResourceArrayShouldBindMultipleValues() {
|
||||
load(ResourceArrayPropertiesConfiguration.class,
|
||||
"test.resources=classpath*:org/springframework/boot/context/properties/*.class");
|
||||
ResourceArrayProperties properties = this.context.getBean(ResourceArrayProperties.class);
|
||||
assertThat(properties.getResources()).hasSizeGreaterThan(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadWhenBindingClasspathPatternToResourceCollectionShouldBindMultipleValues() {
|
||||
load(ResourceCollectionPropertiesConfiguration.class,
|
||||
"test.resources=classpath*:org/springframework/boot/context/properties/*.class");
|
||||
ResourceCollectionProperties properties = this.context.getBean(ResourceCollectionProperties.class);
|
||||
assertThat(properties.getResources()).hasSizeGreaterThan(1);
|
||||
}
|
||||
|
||||
private AnnotationConfigApplicationContext load(Class<?> configuration, String... inlinedProperties) {
|
||||
return load(new Class<?>[] { configuration }, inlinedProperties);
|
||||
}
|
||||
|
@ -3058,4 +3075,44 @@ class ConfigurationPropertiesTests {
|
|||
|
||||
}
|
||||
|
||||
@EnableConfigurationProperties(ResourceArrayProperties.class)
|
||||
static class ResourceArrayPropertiesConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@ConfigurationProperties("test")
|
||||
static class ResourceArrayProperties {
|
||||
|
||||
private Resource[] resources;
|
||||
|
||||
Resource[] getResources() {
|
||||
return this.resources;
|
||||
}
|
||||
|
||||
void setResources(Resource[] resources) {
|
||||
this.resources = resources;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableConfigurationProperties(ResourceCollectionProperties.class)
|
||||
static class ResourceCollectionPropertiesConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@ConfigurationProperties("test")
|
||||
static class ResourceCollectionProperties {
|
||||
|
||||
private Collection<Resource> resources;
|
||||
|
||||
Collection<Resource> getResources() {
|
||||
return this.resources;
|
||||
}
|
||||
|
||||
void setResources(Collection<Resource> resources) {
|
||||
this.resources = resources;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue