16
16
17
17
package org .springframework .context .annotation ;
18
18
19
- import java .io .FileNotFoundException ;
20
19
import java .io .IOException ;
21
20
import java .lang .annotation .Annotation ;
22
- import java .net .SocketException ;
23
- import java .net .UnknownHostException ;
24
21
import java .util .ArrayDeque ;
25
22
import java .util .ArrayList ;
26
23
import java .util .Collection ;
40
37
import org .apache .commons .logging .Log ;
41
38
import org .apache .commons .logging .LogFactory ;
42
39
43
- import org .springframework .beans .BeanUtils ;
44
40
import org .springframework .beans .factory .BeanDefinitionStoreException ;
45
41
import org .springframework .beans .factory .annotation .AnnotatedBeanDefinition ;
46
42
import org .springframework .beans .factory .config .BeanDefinition ;
59
55
import org .springframework .core .annotation .AnnotationAttributes ;
60
56
import org .springframework .core .annotation .AnnotationAwareOrderComparator ;
61
57
import org .springframework .core .annotation .AnnotationUtils ;
62
- import org .springframework .core .env .CompositePropertySource ;
63
58
import org .springframework .core .env .ConfigurableEnvironment ;
64
59
import org .springframework .core .env .Environment ;
65
- import org .springframework .core .env .MutablePropertySources ;
66
- import org .springframework .core .env .PropertySource ;
67
- import org .springframework .core .io .Resource ;
68
60
import org .springframework .core .io .ResourceLoader ;
69
- import org .springframework .core .io .support .DefaultPropertySourceFactory ;
70
- import org .springframework .core .io .support .EncodedResource ;
71
- import org .springframework .core .io .support .PropertySourceFactory ;
72
- import org .springframework .core .io .support .ResourcePropertySource ;
61
+ import org .springframework .core .io .support .PropertySourceDescriptor ;
62
+ import org .springframework .core .io .support .PropertySourceProcessor ;
73
63
import org .springframework .core .type .AnnotationMetadata ;
74
64
import org .springframework .core .type .MethodMetadata ;
75
65
import org .springframework .core .type .StandardAnnotationMetadata ;
83
73
import org .springframework .util .CollectionUtils ;
84
74
import org .springframework .util .LinkedMultiValueMap ;
85
75
import org .springframework .util .MultiValueMap ;
86
- import org .springframework .util .StringUtils ;
87
76
88
77
/**
89
78
* Parses a {@link Configuration} class definition, populating a collection of
109
98
*/
110
99
class ConfigurationClassParser {
111
100
112
- private static final PropertySourceFactory DEFAULT_PROPERTY_SOURCE_FACTORY = new DefaultPropertySourceFactory ();
113
-
114
101
private static final Predicate <String > DEFAULT_EXCLUSION_FILTER = className ->
115
102
(className .startsWith ("java.lang.annotation." ) || className .startsWith ("org.springframework.stereotype." ));
116
103
@@ -128,6 +115,9 @@ class ConfigurationClassParser {
128
115
129
116
private final ResourceLoader resourceLoader ;
130
117
118
+ @ Nullable
119
+ private final PropertySourceRegistry propertySourceRegistry ;
120
+
131
121
private final BeanDefinitionRegistry registry ;
132
122
133
123
private final ComponentScanAnnotationParser componentScanParser ;
@@ -138,8 +128,6 @@ class ConfigurationClassParser {
138
128
139
129
private final Map <String , ConfigurationClass > knownSuperclasses = new HashMap <>();
140
130
141
- private final List <String > propertySourceNames = new ArrayList <>();
142
-
143
131
private final ImportStack importStack = new ImportStack ();
144
132
145
133
private final DeferredImportSelectorHandler deferredImportSelectorHandler = new DeferredImportSelectorHandler ();
@@ -159,6 +147,9 @@ public ConfigurationClassParser(MetadataReaderFactory metadataReaderFactory,
159
147
this .problemReporter = problemReporter ;
160
148
this .environment = environment ;
161
149
this .resourceLoader = resourceLoader ;
150
+ this .propertySourceRegistry = (this .environment instanceof ConfigurableEnvironment ce
151
+ ? new PropertySourceRegistry (new PropertySourceProcessor (ce , this .resourceLoader ))
152
+ : null );
162
153
this .registry = registry ;
163
154
this .componentScanParser = new ComponentScanAnnotationParser (
164
155
environment , resourceLoader , componentScanBeanNameGenerator , registry );
@@ -220,6 +211,10 @@ public Set<ConfigurationClass> getConfigurationClasses() {
220
211
return this .configurationClasses .keySet ();
221
212
}
222
213
214
+ List <PropertySourceDescriptor > getPropertySourceDescriptors () {
215
+ return (this .propertySourceRegistry != null ? this .propertySourceRegistry .getDescriptors ()
216
+ : Collections .emptyList ());
217
+ }
223
218
224
219
protected void processConfigurationClass (ConfigurationClass configClass , Predicate <String > filter ) throws IOException {
225
220
if (this .conditionEvaluator .shouldSkip (configClass .getMetadata (), ConfigurationPhase .PARSE_CONFIGURATION )) {
@@ -275,8 +270,8 @@ protected final SourceClass doProcessConfigurationClass(
275
270
for (AnnotationAttributes propertySource : AnnotationConfigUtils .attributesForRepeatable (
276
271
sourceClass .getMetadata (), PropertySources .class ,
277
272
org .springframework .context .annotation .PropertySource .class )) {
278
- if (this .environment instanceof ConfigurableEnvironment ) {
279
- processPropertySource (propertySource );
273
+ if (this .propertySourceRegistry != null ) {
274
+ this . propertySourceRegistry . processPropertySource (propertySource );
280
275
}
281
276
else {
282
277
logger .info ("Ignoring @PropertySource annotation on [" + sourceClass .getMetadata ().getClassName () +
@@ -433,85 +428,6 @@ private Set<MethodMetadata> retrieveBeanMethodMetadata(SourceClass sourceClass)
433
428
}
434
429
435
430
436
- /**
437
- * Process the given <code>@PropertySource</code> annotation metadata.
438
- * @param propertySource metadata for the <code>@PropertySource</code> annotation found
439
- * @throws IOException if loading a property source failed
440
- */
441
- private void processPropertySource (AnnotationAttributes propertySource ) throws IOException {
442
- String name = propertySource .getString ("name" );
443
- if (!StringUtils .hasLength (name )) {
444
- name = null ;
445
- }
446
- String encoding = propertySource .getString ("encoding" );
447
- if (!StringUtils .hasLength (encoding )) {
448
- encoding = null ;
449
- }
450
- String [] locations = propertySource .getStringArray ("value" );
451
- Assert .isTrue (locations .length > 0 , "At least one @PropertySource(value) location is required" );
452
- boolean ignoreResourceNotFound = propertySource .getBoolean ("ignoreResourceNotFound" );
453
-
454
- Class <? extends PropertySourceFactory > factoryClass = propertySource .getClass ("factory" );
455
- PropertySourceFactory factory = (factoryClass == PropertySourceFactory .class ?
456
- DEFAULT_PROPERTY_SOURCE_FACTORY : BeanUtils .instantiateClass (factoryClass ));
457
-
458
- for (String location : locations ) {
459
- try {
460
- String resolvedLocation = this .environment .resolveRequiredPlaceholders (location );
461
- Resource resource = this .resourceLoader .getResource (resolvedLocation );
462
- addPropertySource (factory .createPropertySource (name , new EncodedResource (resource , encoding )));
463
- }
464
- catch (IllegalArgumentException | FileNotFoundException | UnknownHostException | SocketException ex ) {
465
- // Placeholders not resolvable or resource not found when trying to open it
466
- if (ignoreResourceNotFound ) {
467
- if (logger .isInfoEnabled ()) {
468
- logger .info ("Properties location [" + location + "] not resolvable: " + ex .getMessage ());
469
- }
470
- }
471
- else {
472
- throw ex ;
473
- }
474
- }
475
- }
476
- }
477
-
478
- private void addPropertySource (PropertySource <?> propertySource ) {
479
- String name = propertySource .getName ();
480
- MutablePropertySources propertySources = ((ConfigurableEnvironment ) this .environment ).getPropertySources ();
481
-
482
- if (this .propertySourceNames .contains (name )) {
483
- // We've already added a version, we need to extend it
484
- PropertySource <?> existing = propertySources .get (name );
485
- if (existing != null ) {
486
- PropertySource <?> newSource = (propertySource instanceof ResourcePropertySource ?
487
- ((ResourcePropertySource ) propertySource ).withResourceName () : propertySource );
488
- if (existing instanceof CompositePropertySource ) {
489
- ((CompositePropertySource ) existing ).addFirstPropertySource (newSource );
490
- }
491
- else {
492
- if (existing instanceof ResourcePropertySource ) {
493
- existing = ((ResourcePropertySource ) existing ).withResourceName ();
494
- }
495
- CompositePropertySource composite = new CompositePropertySource (name );
496
- composite .addPropertySource (newSource );
497
- composite .addPropertySource (existing );
498
- propertySources .replace (name , composite );
499
- }
500
- return ;
501
- }
502
- }
503
-
504
- if (this .propertySourceNames .isEmpty ()) {
505
- propertySources .addLast (propertySource );
506
- }
507
- else {
508
- String firstProcessed = this .propertySourceNames .get (this .propertySourceNames .size () - 1 );
509
- propertySources .addBefore (firstProcessed , propertySource );
510
- }
511
- this .propertySourceNames .add (name );
512
- }
513
-
514
-
515
431
/**
516
432
* Returns {@code @Import} class, considering all meta-annotations.
517
433
*/
0 commit comments