/*
 * Copyright 2002-2018 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
 *
 *      http://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.context.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.core.io.support.PropertySourceFactory;

Annotation providing a convenient and declarative mechanism for adding a PropertySource to Spring's Environment. To be used in conjunction with @Configuration classes.

Example usage

Given a file app.properties containing the key/value pair testbean.name=myTestBean, the following @Configuration class uses @PropertySource to contribute app.properties to the Environment's set of PropertySources.

@Configuration
@PropertySource("classpath:/com/myco/app.properties")
public class AppConfig {
    @Autowired
    Environment env;
    @Bean
    public TestBean testBean() {
        TestBean testBean = new TestBean();
        testBean.setName(env.getProperty("testbean.name"));
        return testBean;
    }
}

Notice that the Environment object is @Autowired into the configuration class and then used when populating the TestBean object. Given the configuration above, a call to testBean.getName() will return "myTestBean".

Resolving ${...} placeholders in <bean> and @Value annotations

In order to resolve ${...} placeholders in <bean> definitions or @Value annotations using properties from a PropertySource, you must ensure that an appropriate embedded value resolver is registered in the BeanFactory used by the ApplicationContext. This happens automatically when using <context:property-placeholder> in XML. When using @Configuration classes this can be achieved by explicitly registering a PropertySourcesPlaceholderConfigurer via a static @Bean method. Note, however, that explicit registration of a PropertySourcesPlaceholderConfigurer via a static @Bean method is typically only required if you need to customize configuration such as the placeholder syntax, etc. See the "Working with externalized values" section of @Configuration's javadocs and "a note on BeanFactoryPostProcessor-returning @Bean methods" of @Bean's javadocs for details and examples.

Resolving ${...} placeholders within @PropertySource resource locations

Any ${...} placeholders present in a @PropertySource resource location will be resolved against the set of property sources already registered against the environment. For example:

@Configuration
@PropertySource("classpath:/com/${my.placeholder:default/path}/app.properties")
public class AppConfig {
    @Autowired
    Environment env;
    @Bean
    public TestBean testBean() {
        TestBean testBean = new TestBean();
        testBean.setName(env.getProperty("testbean.name"));
        return testBean;
    }
}

Assuming that "my.placeholder" is present in one of the property sources already registered, e.g. system properties or environment variables, the placeholder will be resolved to the corresponding value. If not, then "default/path" will be used as a default. Expressing a default value (delimited by colon ":") is optional. If no default is specified and a property cannot be resolved, an IllegalArgumentException will be thrown.

A note on property overriding with @PropertySource

In cases where a given property key exists in more than one .properties file, the last @PropertySource annotation processed will 'win' and override.

For example, given two properties files a.properties and b.properties, consider the following two configuration classes that reference them with @PropertySource annotations:

@Configuration
@PropertySource("classpath:/com/myco/a.properties")
public class ConfigA { }
@Configuration
@PropertySource("classpath:/com/myco/b.properties")
public class ConfigB { }

The override ordering depends on the order in which these classes are registered with the application context.

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(ConfigA.class);
ctx.register(ConfigB.class);
ctx.refresh();

In the scenario above, the properties in b.properties will override any duplicates that exist in a.properties, because ConfigB was registered last.

In certain situations, it may not be possible or practical to tightly control property source ordering when using @PropertySource annotations. For example, if the @Configuration classes above were registered via component-scanning, the ordering is difficult to predict. In such cases - and if overriding is important - it is recommended that the user fall back to using the programmatic PropertySource API. See ConfigurableEnvironment and MutablePropertySources javadocs for details.

NOTE: This 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.

Author:Chris Beams, Juergen Hoeller, Phillip Webb, Sam Brannen
See Also:
Since:3.1
/** * Annotation providing a convenient and declarative mechanism for adding a * {@link org.springframework.core.env.PropertySource PropertySource} to Spring's * {@link org.springframework.core.env.Environment Environment}. To be used in * conjunction with @{@link Configuration} classes. * * <h3>Example usage</h3> * * <p>Given a file {@code app.properties} containing the key/value pair * {@code testbean.name=myTestBean}, the following {@code @Configuration} class * uses {@code @PropertySource} to contribute {@code app.properties} to the * {@code Environment}'s set of {@code PropertySources}. * * <pre class="code"> * &#064;Configuration * &#064;PropertySource("classpath:/com/myco/app.properties") * public class AppConfig { * * &#064;Autowired * Environment env; * * &#064;Bean * public TestBean testBean() { * TestBean testBean = new TestBean(); * testBean.setName(env.getProperty("testbean.name")); * return testBean; * } * }</pre> * * <p>Notice that the {@code Environment} object is * {@link org.springframework.beans.factory.annotation.Autowired @Autowired} into the * configuration class and then used when populating the {@code TestBean} object. Given * the configuration above, a call to {@code testBean.getName()} will return "myTestBean". * * <h3>Resolving <code>${...}</code> placeholders in {@code <bean>} and {@code @Value} annotations</h3> * * <p>In order to resolve ${...} placeholders in {@code <bean>} definitions or {@code @Value} * annotations using properties from a {@code PropertySource}, you must ensure that an * appropriate <em>embedded value resolver</em> is registered in the {@code BeanFactory} * used by the {@code ApplicationContext}. This happens automatically when using * {@code <context:property-placeholder>} in XML. When using {@code @Configuration} classes * this can be achieved by explicitly registering a {@code PropertySourcesPlaceholderConfigurer} * via a {@code static} {@code @Bean} method. Note, however, that explicit registration * of a {@code PropertySourcesPlaceholderConfigurer} via a {@code static} {@code @Bean} * method is typically only required if you need to customize configuration such as the * placeholder syntax, etc. See the "Working with externalized values" section of * {@link Configuration @Configuration}'s javadocs and "a note on * BeanFactoryPostProcessor-returning {@code @Bean} methods" of {@link Bean @Bean}'s * javadocs for details and examples. * * <h3>Resolving ${...} placeholders within {@code @PropertySource} resource locations</h3> * * <p>Any ${...} placeholders present in a {@code @PropertySource} {@linkplain #value() * resource location} will be resolved against the set of property sources already * registered against the environment. For example: * * <pre class="code"> * &#064;Configuration * &#064;PropertySource("classpath:/com/${my.placeholder:default/path}/app.properties") * public class AppConfig { * * &#064;Autowired * Environment env; * * &#064;Bean * public TestBean testBean() { * TestBean testBean = new TestBean(); * testBean.setName(env.getProperty("testbean.name")); * return testBean; * } * }</pre> * * <p>Assuming that "my.placeholder" is present in one of the property sources already * registered, e.g. system properties or environment variables, the placeholder will * be resolved to the corresponding value. If not, then "default/path" will be used as a * default. Expressing a default value (delimited by colon ":") is optional. If no * default is specified and a property cannot be resolved, an {@code * IllegalArgumentException} will be thrown. * * <h3>A note on property overriding with @PropertySource</h3> * * <p>In cases where a given property key exists in more than one {@code .properties} * file, the last {@code @PropertySource} annotation processed will 'win' and override. * * <p>For example, given two properties files {@code a.properties} and * {@code b.properties}, consider the following two configuration classes * that reference them with {@code @PropertySource} annotations: * * <pre class="code"> * &#064;Configuration * &#064;PropertySource("classpath:/com/myco/a.properties") * public class ConfigA { } * * &#064;Configuration * &#064;PropertySource("classpath:/com/myco/b.properties") * public class ConfigB { } * </pre> * * <p>The override ordering depends on the order in which these classes are registered * with the application context. * * <pre class="code"> * AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); * ctx.register(ConfigA.class); * ctx.register(ConfigB.class); * ctx.refresh(); * </pre> * * <p>In the scenario above, the properties in {@code b.properties} will override any * duplicates that exist in {@code a.properties}, because {@code ConfigB} was registered * last. * * <p>In certain situations, it may not be possible or practical to tightly control * property source ordering when using {@code @PropertySource} annotations. For example, * if the {@code @Configuration} classes above were registered via component-scanning, * the ordering is difficult to predict. In such cases - and if overriding is important - * it is recommended that the user fall back to using the programmatic PropertySource API. * See {@link org.springframework.core.env.ConfigurableEnvironment ConfigurableEnvironment} * and {@link org.springframework.core.env.MutablePropertySources MutablePropertySources} * 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 Juergen Hoeller * @author Phillip Webb * @author Sam Brannen * @since 3.1 * @see PropertySources * @see Configuration * @see org.springframework.core.env.PropertySource * @see org.springframework.core.env.ConfigurableEnvironment#getPropertySources() * @see org.springframework.core.env.MutablePropertySources */
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Repeatable(PropertySources.class) public @interface PropertySource {
Indicate the name of this property source. If omitted, a name will be generated based on the description of the underlying resource.
See Also:
/** * Indicate the name of this property source. If omitted, a name will * be generated based on the description of the underlying resource. * @see org.springframework.core.env.PropertySource#getName() * @see org.springframework.core.io.Resource#getDescription() */
String name() default "";
Indicate the resource location(s) of the properties file to be loaded.

Both traditional and XML-based properties file formats are supported — for example, "classpath:/com/myco/app.properties" or "file:/path/to/file.xml".

Resource location wildcards (e.g. **/*.properties) are not permitted; each location must evaluate to exactly one .properties resource.

${...} placeholders will be resolved against any/all property sources already registered with the Environment. See above for examples.

Each location will be added to the enclosing Environment as its own property source, and in the order declared.

/** * Indicate the resource location(s) of the properties file to be loaded. * <p>Both traditional and XML-based properties file formats are supported * &mdash; for example, {@code "classpath:/com/myco/app.properties"} * or {@code "file:/path/to/file.xml"}. * <p>Resource location wildcards (e.g. *&#42;/*.properties) are not permitted; * each location must evaluate to exactly one {@code .properties} resource. * <p>${...} placeholders will be resolved against any/all property sources already * registered with the {@code Environment}. See {@linkplain PropertySource above} * for examples. * <p>Each location will be added to the enclosing {@code Environment} as its own * property source, and in the order declared. */
String[] value();
Indicate if failure to find the a property resource should be ignored.

true is appropriate if the properties file is completely optional. Default is false.

Since:4.0
/** * Indicate if failure to find the a {@link #value() property resource} should be * ignored. * <p>{@code true} is appropriate if the properties file is completely optional. * Default is {@code false}. * @since 4.0 */
boolean ignoreResourceNotFound() default false;
A specific character encoding for the given resources, e.g. "UTF-8".
Since:4.3
/** * A specific character encoding for the given resources, e.g. "UTF-8". * @since 4.3 */
String encoding() default "";
Specify a custom PropertySourceFactory, if any.

By default, a default factory for standard resource files will be used.

See Also:
Since:4.3
/** * Specify a custom {@link PropertySourceFactory}, if any. * <p>By default, a default factory for standard resource files will be used. * @since 4.3 * @see org.springframework.core.io.support.DefaultPropertySourceFactory * @see org.springframework.core.io.support.ResourcePropertySource */
Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class; }