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;
}
}
答
你猜对了,只有在对象实例化后才会注入值;因为 spring 容器无法设置尚不存在的属性.因此,在构造函数中,这些字段仍将为空.一种解决方案是,要么
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
- 切换到 constructer Injection 而不是 setter Injection(YMMV,没有测试你的用例)
- Switch to constructer Injection instead of setter Injection (YMMV, havnt tested your usecase)
或
- 用
@PostConstruct
注释的方法替换构造函数.这个方法会在注入过程之后执行.
- 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;
}
}