I have following configuration class:
@Configuration
@PropertySource(name = \"props\", value = \"classpath:/app-config.properties\")
@ComponentScan(\"service
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();
}
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
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.
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();
}
}
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.
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;
}