项目场景:
今天在做项目中碰到一个问题,有一个类的静态代码块中的参数是application.yml中动态注入的。
问题描述:
但是熟悉Spring项目的同学都知道,@Value只能注非静态变量,否则赋值是null.
该类代码如下:
public class Test{
private final static String url;
static{
url = ${变量};
}
}
原因分析:
因为在加载静态变量时,该类还没有实例化,导致@Value无法赋值。
解决方案:
增加获取上下文Bean的工具类
public class SpringContextUtilimplements ApplicationContextAware{
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext context)throws BeansException{
SpringContextUtil.context = context;
}
public static ApplicationContext getApplicationContext() {
return context;
}
public static Object getBean(String beanName) {
return context.getBean(beanName);
}
}
增加一个专门的配置类注入属性
@Component
@Data
public class Config{
private String url;
public static Config getInstence(){
SpringClontextUtils.getBean(Config.class);
}
}
在使用类中使用该变量
public class Test{
private final static String url;
static{
url = Config.getInstence().getUrl();
}
}
这样皆可以实现动态注入静态变量了.
知识扩展:
@PostConstruct 修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行。
因为这些都是在构造函数之后执行,所以无法给静态代码块赋值。