有时候我们的@Value获取yml值需要是静态的,但是静态的@Value获取一直是null,这时候有就可以用set或者@PostConstruct方式,但是这种方式有个bug,那就是如果其他类bean定义的时候用到该静态变量的话,使用的时候依然还没赋值,这时候就需要手动读取了。
@Component
public class MailInfo{
@Value("${mail.name:admin@163.com}")
public String preMailName;
@Value("${mail.pwd:admin123}")
public String preMailPwd;
public static String mailName;
public static String mailPwd;
@PostConstruct
public void init(){
mailName = preMailName;
mailPwd = preMailPwd;
}
}
@Component
public class MailInfo{
public static String mailName;
public static String mailPwd;
@Value("${mail.name:admin@163.com}")
public void setMailName(String name){
mailName = name;
}
@Value("${mail.pwd:admin123}")
public void setMailPwd(String pwd){
mailPwd = pwd;
}
}
如果出现下面情况的话上面两种方案就不生效了
@Component
public class Test{
@Bean
public Queue testQueue() {
return new Queue(MqUtil.mName, true);
//不论是这种还是@PostConstruct 方式,获取出来都是null
}
}
@Component
public class MqUtil{
public static String mName;
@Value("${test.name}")
public void setMailName(String name){
mName= name;
}
}
解决
用代码直接去读取,其他地方用到的时候就调用getName方法就行了
@Component
public class MqUtil {
public static String name;
public static String getName() {
if (StringUtils.isEmpty(name)) {
Yaml yaml = new Yaml();
URL url = RabbitMqUtil.class.getClassLoader().getResource("config/application.yml");
if (url != null) {
try {
Map map = (Map) yaml.load(new FileInputStream(url.getFile()));
Map test= (Map) map.get("test");
String name= (String) spring.get("name");
} catch (FileNotFoundException e) {
return "";
}
}else{
return "";
}
}
return name;
}