0

I have a small class in my Spring-Boot project in which I am getting the some values from the application.properties file. My class is in src/main/java/com/company/package folder and my application properties file in src/main/resources/application.properties. This is my class:

@Component
@Configuration
@PropertySource("classpath:application.properties")
public class ElasticConnection {

private static final String INDEX = "index_name";
public static final String TYPE   = "type";

private String user;
private String password;

public ElasticConnection(@Value("${elasticsearch.user}")      String user,
                        @Value("${elasticsearch.password}") String password){
    this.user = user;
    this.password = password;
}

I am Autowiring this class to the Application class:

@Configuration
@SpringBootApplication
public class ElasticApplication {

@Autowired
ElasticConnection elastic;

public static void main(String[] args) {

    SpringApplication.run(ElasticApplication.class, args);
}

}

Now as soon as the constrctor of the ElasticConnection class is called user and password are set to null. I know the values are read properly because InteliJ is kind enough to show the value (until you click on @Value and shows the "${elasticsearch.user}" again)

EDIT: this is the application properties file.

# App config
server.port=8070

 # Local ElasticSearch instance configuration
 elasticsearch.clustername = elasticsearch
 elasticsearch.host = localhost
 elasticsearch.port = 9300

 #spring.main.allow-bean-definition-overriding=true


 # Elasticsearch Settings
  elasticsearch.user=test
  elasticsearch.password=test
Stefanos
  • 37
  • 3
  • 11
  • you've got a typo in `elastisearch.user` - I think that's just your example typing though, not the actual problem – David Lavender May 29 '19 at 11:27
  • Please, consider to provide a [Minimal, Reproducible Example](http://stackoverflow.com/help/minimal-reproducible-example) if possible. This way, it's more likely volunteers on SO can help you. i.e.: do you have a github repo with this code so we can test it? As I said before, I can't reproduce the issue: I created a Spring Boot app from scratch with your code and it works, the values for `user` and `password` are bind properly. – lealceldeiro May 29 '19 at 11:37
  • You might want to clean up your application. The `ElasticConnection` does not need the `PropertySource` and likely only the `Component` on it. Additionally remove the `Configuration` from your main application that is redundant. – Darren Forsythe May 29 '19 at 12:17
  • Is `ElasticApplication` and `ElasticConnection` in the same package? BTW com/company/package is not possible as `package` is reserved. – Guru May 29 '19 at 13:47
  • No need to mention property file location at spring boot if you are using application.prop at default location. also you need to read value from property file and need to assign to variable. after then only you can use variable value to further places in the class. @Value("${elasticsearch.user}") private String userVal; and have getter setter for this variable. – Dhrumil Shah May 30 '19 at 05:57

1 Answers1

0

If we want to use the @Value annotation for a constructor argument we must not forget to add the @Autowired annotation on the constructor as well.So your code should be :

@Component
@PropertySource("classpath:application.properties")
public class ElasticConnection {

private static final String INDEX = "index_name";
public static final String TYPE   = "type";

private String user;
private String password;

@Autowired
public ElasticConnection(@Value("${elasticsearch.user}")      String user,
                        @Value("${elasticsearch.password}") String password){
    this.user = user;
    this.password = password;
}

This enables spring to use constructor injection for your fields. Instead of injecting the values via the constructor you can also try the following in your code :

@Component
@PropertySource("classpath:application.properties")
public class ElasticConnection {

private static final String INDEX = "index_name";
public static final String TYPE   = "type";

@Value("${elasticsearch.user}") 
private String user;

@Value("${elasticsearch.password}") 
private String password;

//setters and getters
}

Or you can even use @ConfigurationProperties annotation to read values from the property files.

Related : Spring @Autowire on Properties vs Constructor

Ananthapadmanabhan
  • 5,706
  • 6
  • 22
  • 39