2

When my SpringApplicationContext is being boostrapped together, I want to get some values for that out of a properties file. From what I've read, it's best to use PropertySourcesPlaceholderConfigurer for this. I'm creating that bean in my spring java config and it is properly resolving the properties.

The problem is when I'm trying to use those properties in the construction of my other spring beans, like in my hibernate config. In my hibernate config, I have the following field:

    @Value(value = "${myapp.database-access.url}")
    public static String DB_ACCESS_URL;

Then I use that property to declare the url to access the database in my datasource bean like this:

    @Bean
    public DataSource dataSource() {

        BasicDataSource dataSource = new BasicDataSource();

        dataSource.setDriverClassName(DRIVER_CLASS_NAME);
        dataSource.setUrl(DATABASE_URL);
        dataSource.setUsername(DATABASE_USERNAME);
        dataSource.setPassword(DATABASE_PASSWORD);

        return dataSource;
    }

Unfortunately the value is null at that point so my application bootstrapping fails. Post-construction the value is available, but apparently not mid-construction. Is there a way to get the @Value annotation to work for me in this circumstance, or do I have to use something else?

If I have to use something else, does anyone have any suggestions?

CorayThan
  • 17,174
  • 28
  • 113
  • 161
  • 2
    Spring does not allow injecting to static fields. See http://stackoverflow.com/questions/7253694/spring-how-to-inject-a-value-to-static-field. – devang May 30 '13 at 19:49
  • Thanks for pointing that out. I tried removing the "static" modifier and still got the same results though. – CorayThan May 30 '13 at 19:55
  • Not quite sure about it, but I'd use it like that: @Value(value = "#{myapp.database-access.url}") ($ vs. #) – PepperBob May 30 '13 at 19:56
  • Actually, the statics were the issue. I had another issue with concatenating two fields. @PepperBob Why the preference for SpEL when I'm not performing any logic? – CorayThan May 30 '13 at 20:00
  • Oh right, both would work but the implications are different. Well, seems I used it this way without being clear about the actual differences. – PepperBob May 30 '13 at 20:03
  • Try this: remove static keyword and change annotation to @Value("${myapp.database-access.url}") (remove the `value =`). – devang May 30 '13 at 20:30
  • @gotuskar You were right from the very beginning. I had an additional issue I didn't know about when I first removed the `static`, but removing the `static` keyword is the correct answer. – CorayThan May 30 '13 at 22:33
  • @CorayThan: Did you also remove `value=` from annotation? Or that did not matter. – devang May 30 '13 at 23:08
  • It seems having or not having `value=` does not matter. I will convert my comment into an answer. – devang May 30 '13 at 23:12

3 Answers3

3

Spring does not allow injecting to static fields.

One approach:

public class Config {

    public static String DB_ACCESS_URL;

    @Value(value = "${myapp.database-access.url}")
    public void setDbAccessUrl(String dbAccessUrl) {
        Config.DB_ACCESS_URL = dbAccessUrl;
    } 
}
devang
  • 5,376
  • 7
  • 34
  • 49
2

I think this is similar to the issue I was facing with the @PropertySource annotation where @Value wasn't injected in @Configuration POJOs. There are 2 ways I found to solve this:

1) Create a Spring XML config (if you don't have one already) which you'll refer to at your @Configuration class using @ImportResource and have in there a single entry: <context:property-placeholder />. That config should make @Value injection on the @Configuration class to work.

2) Don't use @Value in the @Configuration POJO but instead inject Environment and retrieve the props from there:

@Autowired Environment env;
//and further down at your dataSource bean retrieve the properties
//...
env.getProperty("myapp.database-access.url");
dimitrisli
  • 20,895
  • 12
  • 59
  • 63
0

This is late but you can simply use @Value with constructor injection public DataSource dataSource(@Value(value = "${myapp.database-access.url}"))

Pupusa
  • 167
  • 1
  • 3
  • 14