spring踩坑之静态变量注入
出现场景
系统中的一些常量、配置为了方便存储的数据库中动态额配置,但是这些数据在系统运行的时候比较频繁的使用,又不能一直去数据库中查询,于是就把这些数据动态的维护在一个缓存中,第一次拿常量的时候放入内存中,以后需要用到的时候就直接去内存中取。 于是就编写一个全局常量类
错误代码
因为项目中使用了spring,所以在使用的时候就直接使用注解@AutoWrite赋值了
@Component
public class GlobalConstant {
private static final Map<String,String> map = new ConcurrentHashMap<>();
@Autowired(required = false)
private static DictMapper dictMapper;
@SneakyThrows
public static String getConstantValue(String constKey){
if (map.containsKey(constKey.toUpperCase())){
return map.get(constKey);
}
String[] str = constKey.toUpperCase().split("_");
QueryWrapper<Dict> dictQueryWrapper = new QueryWrapper<>();
dictQueryWrapper.eq("property",str[0]);
dictQueryWrapper.eq("key",str[1]);
Dict dict = dictMapper.selectOne(dictQueryWrapper);
if (aa10==null){
throw new Exception("没有查询到常量值,请检查常量名称是否为[property_key]");
}
String key = aa10.getAaa100().toUpperCase()+aa10.getAaa106().toUpperCase();
map.put(key,aa10.getAaa102());
return aa10.getAaa102();
}
}
写完之后感觉针不戳,并且在编译期间程序也没有报啥子错,然后再运行的时候突然就出现问题,说缺少构造器。。。然后看了半天代码才看出来,由于我写的是一个工具类,所以属性是静态全局的。但是spring再初始化bean容器的时候并不支持给静态常量赋值。
解决
方法1:在构造方法上使用@autowrite
@Component
public class GlobalConstant {
private static final Map<String,String> map = new ConcurrentHashMap<>();
private static DictMapper dictMapper;
@Autowired(required = false)
public GlobalConstant(DictMapper dictMapper){
GlobalConstant.dictMapper = dictMapper;
}
...blabla
}
方法2:使用@postconstruct和非静态常量
@Component
public class GlobalConstant {
private static final Map<String,String> map = new ConcurrentHashMap<>();
private static DictMapper dictMapper;
@Resource
private DictMapper dictMapperProp;
@PostConstruct
public void init(){
this.dictMapper = this.dictMapperProp
}
...blabla
}
后续有新见解再做补充.-----2021.12.3晚🎃 the end~
|