Spring Boot - @Value annotation doesn't work

Viewed 16078

I try to create mail service using SmtpAuthenticator. The component is started correctly but null values are in username and password fields. Why is it?

@Component
public class SmtpAuthenticator extends Authenticator {

    private static final Logger LOG = 
    LogManager.getLogger(SmtpAuthenticator.class.getSimpleName());

    @Value("${spring.mail.username}")
    private String username;
    @Value("${spring.mail.password}")
    private String password;

    public SmtpAuthenticator() {
        LOG.info(SmtpAuthenticator.class.getSimpleName() + " started...");
        LOG.debug("username=" + username);
    }

    @Override
    protected PasswordAuthentication getPasswordAuthentication() {
        if (!StringUtils.isEmpty(username) && !StringUtils.isEmpty(password)) {
            LOG.debug("Username and password are correct...");
            return new PasswordAuthentication(username, password);
        }
    LOG.error("Not correct mail login data!");
    return null;
    }
}
2 Answers

You guessed it right, the values will get injected only after the objects gets instantiated; because the spring container cannot set a property of something which doesn't exist yet. So while in constructer, those fields will still be null. One solution is, either

  1. Switch to constructer Injection instead of setter Injection (YMMV, havnt tested your usecase)

Or

  1. Replace the constructor with a method annotated with @PostConstruct. This method will be executed after the injection process.

for example

@Component
public class SmtpAuthenticator extends Authenticator {
    private static final Logger LOG = 
    LogManager.getLogger(SmtpAuthenticator.class.getSimpleName());

    @Value("${spring.mail.username}")
    private String username;
    @Value("${spring.mail.password}")
    private String password;

    @PostConstruct
    public void init() {
        LOG.info(SmtpAuthenticator.class.getSimpleName() + " started...");
        LOG.debug("username=" + username);
    }

    @Override
    protected PasswordAuthentication getPasswordAuthentication() {
        if (!StringUtils.isEmpty(username) && !StringUtils.isEmpty(password)) {
            LOG.debug("Username and password are correct...");
            return new PasswordAuthentication(username, password);
        }
    LOG.error("Not correct mail login data!");
    return null;
    }
}
Related