Clarified repeatable PropertySource annotation vs use as meta-annotation
Issue: SPR-16592
This commit is contained in:
		
							parent
							
								
									3988dd9ebb
								
							
						
					
					
						commit
						c4e9ce8d0e
					
				| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2002-2017 the original author or authors.
 | 
					 * Copyright 2002-2018 the original author or authors.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 * you may not use this file except in compliance with the License.
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
| 
						 | 
					@ -298,18 +298,23 @@ public class AnnotationConfigUtils {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@SuppressWarnings("unchecked")
 | 
						@SuppressWarnings("unchecked")
 | 
				
			||||||
	static Set<AnnotationAttributes> attributesForRepeatable(AnnotationMetadata metadata,
 | 
						static Set<AnnotationAttributes> attributesForRepeatable(
 | 
				
			||||||
			String containerClassName, String annotationClassName) {
 | 
								AnnotationMetadata metadata, String containerClassName, String annotationClassName) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Set<AnnotationAttributes> result = new LinkedHashSet<>();
 | 
							Set<AnnotationAttributes> result = new LinkedHashSet<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Direct annotation present?
 | 
				
			||||||
		addAttributesIfNotNull(result, metadata.getAnnotationAttributes(annotationClassName, false));
 | 
							addAttributesIfNotNull(result, metadata.getAnnotationAttributes(annotationClassName, false));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Container annotation present?
 | 
				
			||||||
		Map<String, Object> container = metadata.getAnnotationAttributes(containerClassName, false);
 | 
							Map<String, Object> container = metadata.getAnnotationAttributes(containerClassName, false);
 | 
				
			||||||
		if (container != null && container.containsKey("value")) {
 | 
							if (container != null && container.containsKey("value")) {
 | 
				
			||||||
			for (Map<String, Object> containedAttributes : (Map<String, Object>[]) container.get("value")) {
 | 
								for (Map<String, Object> containedAttributes : (Map<String, Object>[]) container.get("value")) {
 | 
				
			||||||
				addAttributesIfNotNull(result, containedAttributes);
 | 
									addAttributesIfNotNull(result, containedAttributes);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Return merged result
 | 
				
			||||||
		return Collections.unmodifiableSet(result);
 | 
							return Collections.unmodifiableSet(result);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2002-2016 the original author or authors.
 | 
					 * Copyright 2002-2018 the original author or authors.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 * you may not use this file except in compliance with the License.
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
| 
						 | 
					@ -42,6 +42,7 @@ import org.springframework.core.io.support.PropertySourceFactory;
 | 
				
			||||||
 * @Configuration
 | 
					 * @Configuration
 | 
				
			||||||
 * @PropertySource("classpath:/com/myco/app.properties")
 | 
					 * @PropertySource("classpath:/com/myco/app.properties")
 | 
				
			||||||
 * public class AppConfig {
 | 
					 * public class AppConfig {
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 *     @Autowired
 | 
					 *     @Autowired
 | 
				
			||||||
 *     Environment env;
 | 
					 *     Environment env;
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -53,8 +54,8 @@ import org.springframework.core.io.support.PropertySourceFactory;
 | 
				
			||||||
 *     }
 | 
					 *     }
 | 
				
			||||||
 * }</pre>
 | 
					 * }</pre>
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Notice that the {@code Environment} object is @{@link
 | 
					 * Notice that the {@code Environment} object is
 | 
				
			||||||
 * org.springframework.beans.factory.annotation.Autowired Autowired} into the
 | 
					 * {@link org.springframework.beans.factory.annotation.Autowired @Autowired} into the
 | 
				
			||||||
 * configuration class and then used when populating the {@code TestBean} object. Given
 | 
					 * configuration class and then used when populating the {@code TestBean} object. Given
 | 
				
			||||||
 * the configuration above, a call to {@code testBean.getName()} will return "myTestBean".
 | 
					 * the configuration above, a call to {@code testBean.getName()} will return "myTestBean".
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -79,6 +80,7 @@ import org.springframework.core.io.support.PropertySourceFactory;
 | 
				
			||||||
 * @Configuration
 | 
					 * @Configuration
 | 
				
			||||||
 * @PropertySource("classpath:/com/${my.placeholder:default/path}/app.properties")
 | 
					 * @PropertySource("classpath:/com/${my.placeholder:default/path}/app.properties")
 | 
				
			||||||
 * public class AppConfig {
 | 
					 * public class AppConfig {
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 *     @Autowired
 | 
					 *     @Autowired
 | 
				
			||||||
 *     Environment env;
 | 
					 *     Environment env;
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -118,9 +120,9 @@ import org.springframework.core.io.support.PropertySourceFactory;
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * The override ordering depends on the order in which these classes are registered
 | 
					 * The override ordering depends on the order in which these classes are registered
 | 
				
			||||||
 * with the application context.
 | 
					 * with the application context.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 * <pre class="code">
 | 
					 * <pre class="code">
 | 
				
			||||||
 * AnnotationConfigApplicationContext ctx =
 | 
					 * AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
 | 
				
			||||||
 *     new AnnotationConfigApplicationContext();
 | 
					 | 
				
			||||||
 * ctx.register(ConfigA.class);
 | 
					 * ctx.register(ConfigA.class);
 | 
				
			||||||
 * ctx.register(ConfigB.class);
 | 
					 * ctx.register(ConfigB.class);
 | 
				
			||||||
 * ctx.refresh();
 | 
					 * ctx.refresh();
 | 
				
			||||||
| 
						 | 
					@ -139,6 +141,12 @@ import org.springframework.core.io.support.PropertySourceFactory;
 | 
				
			||||||
 * and {@link org.springframework.core.env.MutablePropertySources MutablePropertySources}
 | 
					 * and {@link org.springframework.core.env.MutablePropertySources MutablePropertySources}
 | 
				
			||||||
 * javadocs for details.
 | 
					 * javadocs for details.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 | 
					 * <p><b>NOTE: This annotation is repeatable according to Java 8 conventions.</b>
 | 
				
			||||||
 | 
					 * However, all such {@code @PropertySource} annotations need to be declared at the same
 | 
				
			||||||
 | 
					 * level: either directly on the configuration class or as meta-annotations within the
 | 
				
			||||||
 | 
					 * same custom annotation. Mixing of direct annotations and meta-annotations is not
 | 
				
			||||||
 | 
					 * recommended since direct annotations will effectively override meta-annotations.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 * @author Chris Beams
 | 
					 * @author Chris Beams
 | 
				
			||||||
 * @author Juergen Hoeller
 | 
					 * @author Juergen Hoeller
 | 
				
			||||||
 * @author Phillip Webb
 | 
					 * @author Phillip Webb
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8011,6 +8011,15 @@ be resolved to the corresponding value. If not, then "default/path" will be used
 | 
				
			||||||
as a default. If no default is specified and a property cannot be resolved, an
 | 
					as a default. If no default is specified and a property cannot be resolved, an
 | 
				
			||||||
`IllegalArgumentException` will be thrown.
 | 
					`IllegalArgumentException` will be thrown.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[NOTE]
 | 
				
			||||||
 | 
					====
 | 
				
			||||||
 | 
					The `@PropertySource` annotation is repeatable according to Java 8 conventions.
 | 
				
			||||||
 | 
					However, all such `@PropertySource` annotations need to be declared at the same
 | 
				
			||||||
 | 
					level: either directly on the configuration class or as meta-annotations within the
 | 
				
			||||||
 | 
					same custom annotation. Mixing of direct annotations and meta-annotations is not
 | 
				
			||||||
 | 
					recommended since direct annotations will effectively override meta-annotations.
 | 
				
			||||||
 | 
					====
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
=== Placeholder resolution in statements
 | 
					=== Placeholder resolution in statements
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue