Search code examples
javaspringjavabeans

@Configuration class with empty @Value


I have a Maven Spring Boot application with an external configuration.

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.0.RELEASE</version>
</parent>

I have a config class with @PropertySource annotation, which uses both @Value and Environment:

@Configuration
@PropertySource("file:/etc/koshka/application.properties")
public class Config 
{
    @Autowired
    private Environment env;

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

    @Value("${socmess.pass}")
    private String pass;

    public String getUser() {
        return env.getProperty("socmess.user");
    }

    public String getPass() {
        return pass;
    }
}

In the nutshell, I need just @Value, but I tested Environment option as well.

I have configuration file in the appropriate folder:

$ cat /etc/koshka/application.properties 
socmess.user="testuser"
socmess.pass="testpass"

In the controller I'm instantiating the configuration:

@RestController
public class Sender {
    private final Logger logger;

    public Sender() 
    {
        logger = (Logger)LogManager.getLogger("KoshkaBot");
    }

    @GetMapping("/vk")
    @CrossOrigin(origins = "*")
    public ResponseEntity<String> vk(
        @RequestParam(value="username") String username,
        @RequestParam(value="password") String password
    ) {
        Config conf = new Config();

        logger.info(conf.getUser());
        logger.info(conf.getPass());

        return ResponseEntity.ok().body("OK");
    }
}

Unfortunately, I see nulls in the log.


Solution

  • Don't create new Config() object. This one is managed by spring container and as such you should, at most, inject it.

    Recap

    Spring is dependency injection framework, meaning that if you need some dependency, it is provided to you by the container and you shouldn't create it. Those dependencies are generally spring beans, objects that spring know how to create and manage.

    Back to us @Configuration is annotation that spring uses to define beans, through @Bean annotation that can be, later on, used by other components using the @Inject annotation. What I would do is define a pojo like:

    public class User(){
       private String username;
       private String password;
    
       //getters,setters etc ...
    }
    

    and then in the Config class define the bean like:

    @Bean
    public User getUser(){
       //..load user and password
       return new User(user, password);
    }
    

    and finally when you need to use the user you can do:

    @Inject User user;
    //now the properties will be not-null