Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@Value annotation not working in constructor

Tags:

spring

I have an issue where Spring @Value annotation not working in the constructor.

I have this Email class that is reading some email related configuration.

In the constructor, if I put a break-point the values are empty

But if I call the sendEmail method, there are values.

The other class:

@Autowired
Email sender;

Email class:

@Component
public class Email{

    @Value("${TO_EMAIL}")
    private String toEmail;

    public Email() {        
        // Here toEmail is null 
    }

    public void sendEmail(String subject, String body) {
        // Here toEmail has value
    }
}
like image 291
JavaSheriff Avatar asked May 07 '19 21:05

JavaSheriff


People also ask

Can we use @value in constructor?

In this quick tutorial, we're going to have a look at the @Value Spring annotation. This annotation can be used for injecting values into fields in Spring-managed beans, and it can be applied at the field or constructor/method parameter level.

Where can I use @value annotation?

Spring @Value with methods If we want different values for different arguments then we can use @Value annotation directly with the argument.

Can we use @value in JUnit?

With the @ValueSource annotation, we can pass an array of literal values to the test method. As we can see, JUnit will run this test two times and each time assigns one argument from the array to the method parameter.

What does @value do in Java?

@Value is a Java annotation that is used at the field or method/constructor parameter level and it indicates a default value for the affected argument. It is commonly used for injecting values into configuration variables - which we will show and explain in the next part of the article.


2 Answers

As far I remember, the value injection occurs after the constructor call.

Try to change your constructor to this:

public Email(@Value("${TO_EMAIL}") String toEmail) { 
   this.toEmail = toEmail;
}
like image 148
cvdr Avatar answered Sep 21 '22 19:09

cvdr


The value injection occures after the constructor call, to solve this in your case, you can leave the constructor empty. And add a method annotated with "@PostConstructor". This way, the empty constructor will be called, then the values will be injected, then the @PostConstructor method will be called.

like image 43
Omar Smri Avatar answered Sep 18 '22 19:09

Omar Smri