Hot questions for Spring Properties

Hot questions for Spring Properties

Top 10 Java Open Source / Spring / Spring Properties


I want to have a list of values in a .properties file, ie:


And to load it in my class directly, ie:

private List<String> myList;

As I understand, an alternative of doing this is to have it in the spring config file, and load it as a bean reference (correct me if I'm wrong), ie

<bean name="list">

But is there any way of doing this? using a .properties file? ps: I would like to do this with out any custom code if possible.


Using Spring EL:

private List<String> myList;

Assuming your properties file is loaded correctly with the following:



I am working on a Spring Boot application. I need to parse an XML file (countries.xml) on start. The problem is that I do not understand where to put it so that I could access it. My folders structure is


My first idea was to put it in src/main/resources, but when I try to create File (countries.xml) I get a NPE and the stacktrace shows that my file is looked in the ProjectDirectory (so src/main/resources/ is not added). I tried to create File (resources/countries.xml) and the path would look like ProjectDirectory/resources/countries.xml (so again src/main is not added).

I tried adding this with no result

public void addResourceHandlers(final ResourceHandlerRegistry registry) {

I know that I can add src/main/ manually, but I want to understand why is it not working as it has to. I also tried examples with ResourceLoader - with the same no result.

Could anyone suggest what the problem is?

UPDATE: Just for future references - after building the project, I encountered problem with accessing file, so I changed File to InputStream

InputStream is = new ClassPathResource("countries.xml").getInputStream();


Just use Spring type ClassPathResource.

File file = new ClassPathResource("countries.xml").getFile();

As long as this file is somewhere on classpath Spring will find it. This can be src/main/resources during development and testing. In production, it can be current running directory.

EDIT: This approach doesn't work if file is in fat JAR. In such case you need to use:

InputStream is = new ClassPathResource("countries.xml").getInputStream();


I've had this working in some other project before, I am just re-doing the same thing but for some reason it's not working. The Spring @Value is not reading from property file, but instead it's taking the value literally

public class AppConfig
    private String value;

    public String getValue()
        return value;


    base-package="com.test.config" />
<context:annotation-config />

<bean id="appConfigProperties"
    <property name="location" value="" />

key.value1=test value 1

In my controller, where I have:

private AppConfig appConfig;

The application starts just fine, but when I do


it returns


It doesn't resolve to the value inside the properties file.



I also found the reason @value was not working is, @value requires PropertySourcesPlaceholderConfigurer instead of a PropertyPlaceholderConfigurer. i did the same changes and it worked for me, i am using spring 4.0.3 release. I configured this using below code in my configuration file -

public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();


I have the following property annotated with @Value. I have a default value defined using the default separator of ':"


Is there a way to escape the ':' in or do I have to define a different separator value in my configuration.


Update: For spring 4.2 and higher, no single quotes are needed. Spring will see the first colon as special, and use all the rest as a single string value.

For spring 4.2 and higher,


For the previous versions, I believe single quotes will do the trick:



I want to use the @Value annotation to inject a Double property such as:

public class MyService {

    private Double priceFactor = 0.1;

// ...

and using Spring property placeholder (Properties files):


I get Exception:

org.springframework.beans.TypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.lang.Double'; nested exception is java.lang.NumberFormatException: For input string: "${item.priceFactor}"

Is there a way to use a Double value coming from a properties file?


Try changing the following line



@Value("#{new Double('${item.priceFactor}')}")



public enum Property {


protected Property property; (lower case)

When I'm running application I have an error:

Cannot convert value of type [java.lang.String] to required type []: no matching editors or conversion strategy found.

Whereas (upper case):

Works fine.

Is there a way to bind the value case insensitive? Like ABC, Abc, AbC, abc any pattern should work.

NOTE: I saw this question - Spring 3.0 MVC binding Enums Case Sensitive but in my case I have over 10 enums/values (and expect to have more) classes and to implement 10 different custom property binders would be painful, I need some generic solution.


@Value and @ConfigurationProperties features do not match. I couldn't stress enough how @ConfigurationProperties is superior.

First, you get to design your configuration in a simple POJO that you can inject wherever you want (rather than having expressions in annotation that you can easily break with a typo). Second, the meta-data support means that you can very easily get auto-completion in your IDE for your own keys.

And finally, the relaxed binding described in the doc only applies to @ConfigurationProperties. @Value is a Spring Framework feature and is unaware of relaxed binding. We intend to make that more clear in the doc.

TL;DR abc works with @ConfigurationProperties but won't with @Value.


Is there a way we can lookup file resources using relative path in file in Spring boot application as specified below



@membersound answer is just breaking up the hardcoded path in 2 parts, not dynamically resolving the property. I can tell you how to achieve what you're looking for, but you need to understand is that there is NO project.basedir when you're running the application as a jar or war. Outside the local workspace, the source code structure doesn't exist.

If you still want to do this for testing, that's feasible and what you need is to manipulate the PropertySources. Your simplest option is as follows:

Define an ApplicationContextInitializer, and set the property there. Something like the following:

    public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    public void initialize(ConfigurableApplicationContext appCtx) {
        try {
            // should be /<path-to-projectBasedir>/build/classes/main/
            File pwd = new File(getClass().getResource("/").toURI());
            String projectDir = pwd.getParentFile().getParentFile().getParent();
            String conf = new File(projectDir, "db/init").getAbsolutePath();
            Map<String, Object> props = new HashMap<>();
            props.put("spring.datasource.url", conf);
            MapPropertySource mapPropertySource = new MapPropertySource("db-props", props);
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);

Looks like you're using Boot, so you can just declare context.initializer.classes=com.example.MyApplicationContextInitializer in your and Boot will run this class at startup.

Words of caution again:

  1. This will not work outside the local workspace as it depends on the source code structure.

  2. I've assumed a Gradle project structure here /build/classes/main. If necessary, adjust according to your build tool.

  3. If MyApplicationContextInitializer is in the src/test/java, pwd will be <projectBasedir>/build/classes/test/, not <projectBasedir>/build/classes/main/.


I have a application.properites file with the following: = sandbox
xxx.sandbox = 123
xxx.production = 456

I would like to map to a string value 123 in case == sandbox and 456 in case == production

public class temp { 

    private String token;

is it possible to fill in a condition incited of the ?????? that will map the token to 123 or 456 according to ?


A simple way in case someone will hit this question:

@Value("#{'${}'=='sandbox' ? '${xxx.sandbox}' : '${xxx.production}'}")

I just think it is much easier that start working with profiles.


I have a requirement of accessing file outside the project location. I am able to achieve the same using following :

        @PropertySource(value = "file:${user.home}/file/path/", ignoreResourceNotFound = false) })
public class PropConfig implements InitializingBean {

Now, I want to achieve the same using active profile. If dev profile is active, I need to fetch, if stage profile is active, I want to fetch and so on.

I am using Windows platform and JAVA 8 with Spring Boot 1.5.x

I tried setting the active profile in file. But it doesn't work


Solution for Spring Boot 1.5.X

You can add the folder as a custom config location by running your app with the following JVM argument:


With this JVM argument configured, all application-{profile}.properties files within this folder will be automatically resolved.

( Alternatively, if you prefer to use environment variables instead of JVM arguments, you can do the same thing by setting the SPRING_CONFIG_LOCATION environment variable, for example by using following command in the linux terminal: export SPRING_CONFIG_LOCATION=file:${user.home}/file/path/ )

Now, if you have a file in your custom config folder, it should be enough to activate the profile in your default file by adding:

Finally, the @PropertySources annotation is redundant and you can remove it:

public class PropConfig implements InitializingBean {


Solution for Spring Boot 2.X

The approach is mainly the same as for Spring Boot 1.5.X but with a slight difference.

In Spring Boot 2.X the behavior of the spring.config.location argument is slightly different than in earlier versions. The difference is that in Spring Boot 2.X the spring.config.location argument overrides the default config locations:

When custom config locations are configured by using spring.config.location, they replace the default locations. (Source: Spring Boot Documentation)

Since setting this argument to your custom config folder would override the default locations (I suppose that losing the config files on the default config locations is not the desired behavior), it is better to use the new spring.config.additional-location argument which doesn't override but only extend the default locations:


( Alternatively, you can use the SPRING_CONFIG_ADDITIONAL-LOCATION environment variable if you prefer to use environment variables instead of JVM arguments )



I have property file application-dev.yml with content:

spring.profiles: dev

and another application-staging.yml with content:

spring.profiles: staging

so I basically do not know size of list. When I reference this list in main application.yml like this:

some.value: ${config.some.value}

I get Failed to convert property value of type 'java.lang.String' to required type 'java.util.List' for property 'value'. How to reference it correctly?



One way would be to use comma-separated lists in your profiles:

  • application-dev.yml
spring.profiles: dev
config.some.value: ELEMENT1,ELEMENT2
  • application-staging.yml
spring.profiles: staging
config.some.value: ELEMENT1,ELEMENT2,ELEMENT3

Then you should be able to access it in application.yml

some.value: ${config.some.value}

This solution doesn't require knowing list size upfront.


The reason why this is working is described here. Specifically:

YAML lists are represented as comma-separated values (useful for simple String values) and also as property keys with [index] dereferencers, for example this YAML:
Would be transformed into these properties:,

In particular this means, that if you specify comma-separated list of strings in application.yml and define List<String> as value in @ConfigurationProperties, spring configuration properties binder will convert that comma-separated list of string to List<Strings>.


I have created a Spring Boot app which uses a legacy library. This legacy library defines a number of Spring Beans in XML. One of which take in a property value as a constructor argument:

<beans xmlns="" xmlns:xsi=""

    <bean id="myBean" class="com.em.MyBean">
        <constructor-arg name="url" value="${my.url}"/>

In my Spring Boot app, I have an which defines this property as follows:


I use the Maven Spring Boot plugin to run my app locally as follows:

mvn spring-boot:run

And the property value is injected into the bean as expected.

If I try and override the my.url property on the command line like this:

mvn spring-boot:run -Dmy.url=

The overriden value is not used and instead, the value inside is used.

According to the Spring Boot docs, values from the command line should be picked up as the first priority: That does not appear to be the case here because if I remove the property from then the value passed in on the command line is used so it is not a case of the command line value being ignored altogether. It seems like the value is overriding the command line value.

Does anyone have any ideas as to what is going on?


Using -D sets a system property. Spring Boot can consume configuration from System properties so, generally speaking, it'll work. However, it won't work if spring-boot:run is forking a separate JVM for your application as the System property will be set on the wrong JVM. As it is not working, I would guess that is what is happening.

You can use -Drun.arguments to pass arguments to the application that's being run, irrespective of whether it's run in a forked JVM. The arguments should be a comma-separated list each prefixed with --. For example, to set my.url:

mvn spring-boot:run -Drun.arguments=--my.url=

The other possible cause of this problem is that your main method isn't passing the arguments that it receives into the SpringApplication that it creates. You should also check that your main method looks similar to this:

public static void main(String[] args) throws Exception {, args);

Note that args is being passed into the call to