Spring Boot-@Value注释不起作用

问题描述:

我尝试使用SmtpAuthenticator创建邮件服务.组件已正确启动,但用户名和密码字段中为空值.为什么呢?

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;
    }
}

您猜对了,只有在实例化对象之后,才会注入值.因为弹簧容器无法设置尚不存在的属性.因此,在构造器中,这些字段仍将为null.一种解决方案是,

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. 切换到构造函数注入,而不是setter注入(YMMV,已经测试了您的用例)
  1. Switch to constructer Injection instead of setter Injection (YMMV, havnt tested your usecase)

  1. 用带有@PostConstruct注释的方法替换构造函数.该方法将在注入过程之后执行.
  1. Replace the constructor with a method annotated with @PostConstruct. This method will be executed after the injection process.

例如

@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;
    }
}