|
16 | 16 |
|
17 | 17 | package org.springframework.context.annotation;
|
18 | 18 |
|
| 19 | +import java.io.FileNotFoundException; |
19 | 20 | import java.io.IOException;
|
20 | 21 | import java.util.ArrayList;
|
21 | 22 | import java.util.Collection;
|
|
55 | 56 | import org.springframework.core.env.CompositePropertySource;
|
56 | 57 | import org.springframework.core.env.Environment;
|
57 | 58 | import org.springframework.core.env.PropertySource;
|
| 59 | +import org.springframework.core.io.Resource; |
58 | 60 | import org.springframework.core.io.ResourceLoader;
|
59 | 61 | import org.springframework.core.io.support.ResourcePropertySource;
|
60 | 62 | import org.springframework.core.type.AnnotationMetadata;
|
|
63 | 65 | import org.springframework.core.type.classreading.MetadataReader;
|
64 | 66 | import org.springframework.core.type.classreading.MetadataReaderFactory;
|
65 | 67 | import org.springframework.core.type.filter.AssignableTypeFilter;
|
| 68 | +import org.springframework.util.LinkedMultiValueMap; |
| 69 | +import org.springframework.util.MultiValueMap; |
66 | 70 | import org.springframework.util.StringUtils;
|
67 | 71 |
|
68 | 72 | /**
|
@@ -112,7 +116,7 @@ public int compare(DeferredImportSelectorHolder o1, DeferredImportSelectorHolder
|
112 | 116 |
|
113 | 117 | private final Map<String, ConfigurationClass> knownSuperclasses = new HashMap<String, ConfigurationClass>();
|
114 | 118 |
|
115 |
| - private final Stack<PropertySource<?>> propertySources = new Stack<PropertySource<?>>(); |
| 119 | + private final MultiValueMap<String, PropertySource<?>> propertySources = new LinkedMultiValueMap<String, PropertySource<?>>(); |
116 | 120 |
|
117 | 121 | private final ImportStack importStack = new ImportStack();
|
118 | 122 |
|
@@ -218,9 +222,9 @@ protected final SourceClass doProcessConfigurationClass(ConfigurationClass confi
|
218 | 222 | processMemberClasses(configClass, sourceClass);
|
219 | 223 |
|
220 | 224 | // process any @PropertySource annotations
|
221 |
| - AnnotationAttributes propertySource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), |
222 |
| - org.springframework.context.annotation.PropertySource.class); |
223 |
| - if (propertySource != null) { |
| 225 | + for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable( |
| 226 | + sourceClass.getMetadata(), PropertySources.class, |
| 227 | + org.springframework.context.annotation.PropertySource.class)) { |
224 | 228 | processPropertySource(propertySource);
|
225 | 229 | }
|
226 | 230 |
|
@@ -301,29 +305,29 @@ private void processMemberClasses(ConfigurationClass configClass, SourceClass so
|
301 | 305 | private void processPropertySource(AnnotationAttributes propertySource) throws IOException {
|
302 | 306 | String name = propertySource.getString("name");
|
303 | 307 | String[] locations = propertySource.getStringArray("value");
|
| 308 | + boolean ignoreResourceNotFound = propertySource.getBoolean("ignoreResourceNotFound"); |
304 | 309 | int locationCount = locations.length;
|
305 | 310 | if (locationCount == 0) {
|
306 | 311 | throw new IllegalArgumentException("At least one @PropertySource(value) location is required");
|
307 | 312 | }
|
308 |
| - for (int i = 0; i < locationCount; i++) { |
309 |
| - locations[i] = this.environment.resolveRequiredPlaceholders(locations[i]); |
310 |
| - } |
311 |
| - ClassLoader classLoader = this.resourceLoader.getClassLoader(); |
312 |
| - if (!StringUtils.hasText(name)) { |
313 |
| - for (String location : locations) { |
314 |
| - this.propertySources.push(new ResourcePropertySource(location, classLoader)); |
315 |
| - } |
316 |
| - } |
317 |
| - else { |
318 |
| - if (locationCount == 1) { |
319 |
| - this.propertySources.push(new ResourcePropertySource(name, locations[0], classLoader)); |
| 313 | + for (String location : locations) { |
| 314 | + Resource resource = this.resourceLoader.getResource( |
| 315 | + this.environment.resolveRequiredPlaceholders(location)); |
| 316 | + try { |
| 317 | + if (!StringUtils.hasText(name) || this.propertySources.containsKey(name)) { |
| 318 | + // We need to ensure unique names when the property source will |
| 319 | + // ultimately end up in a composite |
| 320 | + ResourcePropertySource ps = new ResourcePropertySource(resource); |
| 321 | + this.propertySources.add((StringUtils.hasText(name) ? name : ps.getName()), ps); |
| 322 | + } |
| 323 | + else { |
| 324 | + this.propertySources.add(name, new ResourcePropertySource(name, resource)); |
| 325 | + } |
320 | 326 | }
|
321 |
| - else { |
322 |
| - CompositePropertySource ps = new CompositePropertySource(name); |
323 |
| - for (int i = locations.length - 1; i >= 0; i--) { |
324 |
| - ps.addPropertySource(new ResourcePropertySource(locations[i], classLoader)); |
| 327 | + catch (FileNotFoundException ex) { |
| 328 | + if (!ignoreResourceNotFound) { |
| 329 | + throw ex; |
325 | 330 | }
|
326 |
| - this.propertySources.push(ps); |
327 | 331 | }
|
328 | 332 | }
|
329 | 333 | }
|
@@ -473,10 +477,27 @@ public Set<ConfigurationClass> getConfigurationClasses() {
|
473 | 477 | return this.configurationClasses;
|
474 | 478 | }
|
475 | 479 |
|
476 |
| - public Stack<PropertySource<?>> getPropertySources() { |
477 |
| - return this.propertySources; |
| 480 | + public List<PropertySource<?>> getPropertySources() { |
| 481 | + List<PropertySource<?>> propertySources = new LinkedList<PropertySource<?>>(); |
| 482 | + for (Map.Entry<String, List<PropertySource<?>>> entry : this.propertySources.entrySet()) { |
| 483 | + propertySources.add(0, collatePropertySources(entry.getKey(), entry.getValue())); |
| 484 | + } |
| 485 | + return propertySources; |
478 | 486 | }
|
479 | 487 |
|
| 488 | + private PropertySource<?> collatePropertySources(String name, |
| 489 | + List<PropertySource<?>> propertySources) { |
| 490 | + if (propertySources.size() == 1) { |
| 491 | + return propertySources.get(0); |
| 492 | + } |
| 493 | + CompositePropertySource result = new CompositePropertySource(name); |
| 494 | + for (int i = propertySources.size() - 1; i >= 0; i--) { |
| 495 | + result.addPropertySource(propertySources.get(i)); |
| 496 | + } |
| 497 | + return result; |
| 498 | + } |
| 499 | + |
| 500 | + |
480 | 501 | ImportRegistry getImportRegistry() {
|
481 | 502 | return this.importStack;
|
482 | 503 | }
|
|
0 commit comments