Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Properties and env always null

Tags:

java

spring

I have a hard time loading properties from my properties file. I'm trying to load a property into my configuration class which is listed below.

package dk.fitfit.budget.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.Environment;


@Configuration
@PropertySource("classpath:application.properties")
public class ApplicationConfig {
    private static final Logger logger = LoggerFactory.getLogger(ApplicationConfig.class);

    @Autowired
    private Environment env;

    @Value("${snot:test}")
    private String snot;

    public ApplicationConfig() {
        logger.info("Application config loaded!");  // Displays as expected
        logger.info("snot: {}", snot);              // snot: null
        logger.info("env: {}", env);                // env: null
    }

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

}

If I change the name of the file (application.properties) or "@PropertySource("classpath:application.properties")" I get an error about the file not being present. So clearly it's being loaded (to some extend anyway).

I was at least expecting to see the default string "test" injected into the variable snot. But not even that is done. I'm not able to autowire Environment either... not sure if there is a relation.

The content of my application.properties is as below.

snot=snog

My application.properties file is placed in src/main/resources/.

Anyone got a clue about what I'm doing wrong?

like image 440
user672009 Avatar asked Jan 09 '23 14:01

user672009


2 Answers

The purpose of a constructor is to initialize a class instance. You have to construct and initialize the class instance before Spring can do anything to it. As such, you cannot expect the env and snot fields to have anything other than the default null value within the constructor.

like image 185
Sotirios Delimanolis Avatar answered Jan 20 '23 22:01

Sotirios Delimanolis


Spring (and all dependency-injection tools) can't inject fields before the instance is created with new, which is one reason why constructor injection should be preferred to field injection. Generally, you can use @Value on constructor parameters, but there are certain issues with @Configuration classes that make constructor injection impractical.

However, there's a solution meant for exactly this situation: @PostConstruct. This method will be called after the DI framework has done all its magic to the bean:

@PostConstruct
public void log() {
    logger.info("Application config loaded!");  // Displays as expected
    logger.info("snot: {}", snot);              // snot: null
    logger.info("env: {}", env);                // env: null
}
like image 42
chrylis -cautiouslyoptimistic- Avatar answered Jan 20 '23 20:01

chrylis -cautiouslyoptimistic-