69

I have following configuration class:

@Configuration
@PropertySource(name = "props", value = "classpath:/app-config.properties")
@ComponentScan("service")
public class AppConfig {

and I have service with property:

@Component 
public class SomeService {
    @Value("#{props['some.property']}") private String someProperty;

I receive error when I want to test the AppConfig configuration class with

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'someService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.lang.String service.SomeService.someProperty; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Field or property 'props' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' 

The issue is documented in SPR-8539

but anyway I cannot figure out how to configure PropertySourcesPlaceholderConfigurer to get it work.

Edit 1

This approach works well with xml configuration

<util:properties id="props" location="classpath:/app-config.properties" />

but I want to use java for configuration.

1
  • done :) I didn't investigate more but mentioned ticked was marked as "won't fix" Commented Nov 10, 2015 at 16:37

13 Answers 13

138

as @cwash said;

@Configuration
@PropertySource("classpath:/test-config.properties")
public class TestConfig {

     @Value("${name}")
     public String name;


     //You need this
     @Bean
     public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
     }

}
Sign up to request clarification or add additional context in comments.

3 Comments

This is also the way suggested in the java docs. See "Using the @Value annotation" in docs.spring.io/spring/docs/4.2.4.RELEASE/javadoc-api/org/…
This works perfectly, we do not need to use xml config files. Just PropertySource annotation and declaring the PropertySourcesPlaceholderConfigurer with Bean annotation is enough.
I just put @Component on my custom implementation of PropertySourcesPlaceholderConfigurer and it registered fine without needing to declare a dedicated bean
37

If you use @PropertySource, properties have to be retrieved with:

@Autowired
Environment env;
// ...
String subject = env.getProperty("mail.subject");

If you want to retrieve with @Value("${mail.subject}"), you have to register the prop placeholder by xml.

Reason: https://jira.springsource.org/browse/SPR-8539

1 Comment

You can also add the static PropertySourcesPlaceholderConfigurer bean in java to allow for the @Value to work.. Here is a sample public static PropertySourcesPlaceholderConfigurer properties() { PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer(); configurer.setIgnoreUnresolvablePlaceholders(true); configurer.setIgnoreResourceNotFound(true); return configurer; }
16

I found the reason @value was not working for me 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.

@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
   return new PropertySourcesPlaceholderConfigurer();
}

2 Comments

I am using Spring 4.3.10 and "@value" is working with "@PropertySource". I didn't configure PropertySourcesPlaceholderConfigurer bean
Confirmed, Spring 4.3.10 no needs PropertySourcesPlaceholderConfigurer.
13

Don't you need a method on your @Configuration class that returns PropertySourcesPlaceholderConfigurer, annotated @Bean and is static, to register any @PropertySource with Spring?

http://www.baeldung.com/2012/02/06/properties-with-spring/#java

https://jira.springsource.org/browse/SPR-8539

Comments

6

I had the very same problem. @PropertySource is not playing well with @Value. A quick workaround is to have an XML configuration which you'll refer to it from your Spring Java Configuration using @ImportResource as usual and that XML configuration file will include a single entry: <context:property-placeholder /> (of course with the needed namespace ceremony). Without any other change @Value will inject properties in your @Configuration pojo.

Comments

5

This can also be configured in java this way

@Bean
public static PropertySourcesPlaceholderConfigurer properties() {
    PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
    configurer.setIgnoreUnresolvablePlaceholders(true);
    configurer.setIgnoreResourceNotFound(true);
    return configurer;
}

Comments

4

That looks mighty complicated, can't you just do

 <context:property-placeholder location="classpath:some.properties" ignore-unresolvable="true"/>

then in code reference:

@Value("${myProperty}")
private String myString;

@Value("${myProperty.two}")
private String myStringTwo;

where some.properties looks something like this

myProperty = whatever
myProperty.two = something else\
that consists of multiline string

For java based config you can do this

@Configuration
@PropertySource(value="classpath:some.properties")
public class SomeService {

And then just inject using @value as before

5 Comments

No properties are in text file: @PropertySource(name = "props", value = "classpath:/app-config.properties") I just want to replace .xml with java config which is available in Spring 3
it doesn't solve my problem. As I said it works with spring xml configuration. But I need solution for Java config with Value annotation as I wrote. I'm not looking for alternative solution.
I don't think I should annotate service with @Configuration. I tried to move @PropertySource directly to service but the error is the same
@coffy I'm looking for the exactly same thing. Do you remember what the solution was to this?
@matus, nope, it doesn't work like that (Spring 4.3.1).
3

Since Spring 4.3 RC2 using PropertySourcesPlaceholderConfigurer or <context:property-placeholder> is not needed anymore. We can use directly @PropertySource with @Value. See this Spring framework ticket

I have created a test application with Spring 5.1.3.RELEASE. The application.properties contains two pairs:

app.name=My application
app.version=1.1

The AppConfig loads the properties via @PropertySource.

package com.zetcode.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@PropertySource(value = "application.properties", ignoreResourceNotFound = true)
public class AppConfig {

}

The Application injects the properties via @Value and uses them.

package com.zetcode;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan(basePackages = "com.zetcode")
public class Application {

    private static final Logger logger = LoggerFactory.getLogger(Application.class);

    @Value("${app.name}")
    private String appName;

    @Value("${app.version}")
    private String appVersion;

    public static void main(String[] args) {

        var ctx = new AnnotationConfigApplicationContext(Application.class);
        var app = ctx.getBean(Application.class);

        app.run();

        ctx.close();
    }

    public void run() {

        logger.info("Application name: {}", appName);
        logger.info("Application version: {}", appVersion);
    }
}

The output is:

$ mvn -q exec:java
22:20:10.894 [com.zetcode.Application.main()] INFO  com.zetcode.Application - Application name: My application
22:20:10.894 [com.zetcode.Application.main()] INFO  com.zetcode.Application - Application version: 1.1

Comments

2

The thing is: as far as I get it, <util:propertes id="id" location="loc"/>, is just a shorthand for

<bean id="id" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
  <property name="location" value="loc"/>
</bean>

(see documentation of util:properties). Thus, when you use util:properties, a standalone bean is created.

@PropertySource, on the other hand, as documentation says is an

annotation providing a convenient and declarative mechanism for adding a PropertySource to Spring's Environment'.

(see @PropertySource doc). So it doesn't create any bean.

Then "#{a['something']}" is a SpEL expression (see SpEL), that means "get something from bean 'a'". When util:properties is used, the bean exists and the expression is meaningful, but when @PropertySource is used, there is no actual bean and the expression is meaningless.

You can workaround this either by using XML (which is the best way, I think) or by issuing a PropertiesFactoryBean by yourself, declaring it as a normal @Bean.

Comments

0

Another thing that may be happening: ensure your @Value annotated values are not static.

Comments

0

In my case, depends-on="bean1" was within property-placeholder was causing the issue. I removed that dependency and used @PostConstruct to achieve the same original functionality and was able to read the new values too.

Comments

0

If you are configuring with xml, after adding

<context:property-placeholder location="..."/>

Make sure your annotations are activated. In my case properties were not fetched for this reason:

<context:annotation-config/>

Comments

0

for me it worked

spring.cloud.config.server.git.default-label=main spring.cloud.config.server.native.searchLocations=file:///Users/${your username}/Projects/git-local-repositories/ spring.profiles.active=native

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.