Reputation: 171
I have the following code in a sample Spring Boot Application
@Configuration
@PropertySource("classpath:second.properties")
public class PropertyConfig {
@Value("#{guru.username}")
String user;
@Value("#{guru.password}")
String password;
@Value("#{guru.url}")
String url;
@Bean
FakeDataSource getFakeDataSource() {
FakeDataSource fk = new FakeDataSource();
fk.setName(user);
fk.setPassword(password);
fk.setUrl(url);
return fk;
}
@Bean
PropertySourcesPlaceholderConfigurer getPropertySourcesPlaceholderConfigurer() {
PropertySourcesPlaceholderConfigurer placeholderConfigurer= new PropertySourcesPlaceholderConfigurer();
//placeholderConfigurer.setLocation(new ClassPathResource("second.properties"));
return placeholderConfigurer;
}
}
And FakeDataSource is a simple pojo with the name, passowrd, url properties.
Then my main application
@SpringBootApplication
public class SpringGuru101DependencyInjectionApplication {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(SpringGuru101DependencyInjectionApplication.class, args);
// Step 2: Make Class
FakeDataSource fakeDataSource = ctx.getBean(FakeDataSource.class);
System.out.println(fakeDataSource.getName());
}
}
but the sout statement is printing null, my second.properties file is present in my resources directory with following content
guru.username=Saurabh
guru.password=ido
guru.url=http://example.com
Upvotes: 1
Views: 1859
Reputation: 29
If you are using Spring-boot, you can use another method for reading configuration which is Spring boot recommended. This will help you get rid of all the @Value notations, allowing spring inject properties without additional hints.
You can potentially do something like:
@ConfigurationProperties("foo")
public class FooProperties {
private boolean enabled;
private InetAddress remoteAddress;
private final Security security = new Security();
public boolean isEnabled() { ... }
public void setEnabled(boolean enabled) { ... }
public InetAddress getRemoteAddress() { ... }
public void setRemoteAddress(InetAddress remoteAddress) { ... }
public Security getSecurity() { ... }
public static class Security {
private String username;
private String password;
private List<String> roles = new ArrayList<>(Collections.singleton("USER"));
public String getUsername() { ... }
public void setUsername(String username) { ... }
public String getPassword() { ... }
public void setPassword(String password) { ... }
public List<String> getRoles() { ... }
public void setRoles(List<String> roles) { ... }
}
}
The POJO above defines the following properties:
foo.enabled, false by default foo.remote-address, with a type that can be coerced from String foo.security.username, with a nested "security" whose name is determined by the name of the property. In particular the return type is not used at all there and could have been SecurityProperties foo.security.password foo.security.roles, with a collection of String
More details: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
Upvotes: 0
Reputation: 4009
There are two places should be corrected:
(1) As I said in the comment of your question, you should replace the wellhead sign (#) to dollar sign ($) for reading values from your configuration file. For example: @Value("${guru.username}")
.
(2) You missed public static
in front of the method getPropertySourcesPlaceholderConfigurer
.
And this modified method should be looked like as follows:
@Bean
public static PropertySourcesPlaceholderConfigurer getPropertySourcesPlaceholderConfigurer() {
PropertySourcesPlaceholderConfigurer placeholderConfigurer= new PropertySourcesPlaceholderConfigurer();
//placeholderConfigurer.setLocation(new ClassPathResource("second.properties"));
return placeholderConfigurer;
}
Upvotes: 1