spring踩坑之静态变量注入
出现场景
系统中的一些常量、配置为了方便存储的数据库中动态额配置,但是这些数据在系统运行的时候比较频繁的使用,又不能一直去数据库中查询,于是就把这些数据动态的维护在一个缓存中,第一次拿常量的时候放入内存中,以后需要用到的时候就直接去内存中取。
于是就编写一个全局常量类
错误代码
因为项目中使用了spring,所以在使用的时候就直接使用注解@AutoWrite赋值了
/**
* @author ffd
* @create 2021-11-17
* @Description 全局常量配置
*/
@Component
public class GlobalConstant {
//缓存常量 key值的格式为property_key 类别名称_类别内部名称的全大写形式
private static final Map<String,String> map = new ConcurrentHashMap<>();
@Autowired(required = false)
private static DictMapper dictMapper;
/**
* 获取全局常量的配置 如果缓存map中直接返回,没有就去数据库中找出然后备份一份
* @param constKey 类别名称_类别内部名称的全大写形式
* @return 对应value值
*/
@SneakyThrows
public static String getConstantValue(String constKey){
//region 如果缓存map中有就直接返回
if (map.containsKey(constKey.toUpperCase())){
return map.get(constKey);
}
//endregion
//region 从dict中查到对应的值并备份在缓存map中一份
String[] str = constKey.toUpperCase().split("_");
QueryWrapper<Dict> dictQueryWrapper = new QueryWrapper<>();
dictQueryWrapper.eq("property",str[0]);//字段名
dictQueryWrapper.eq("key",str[1]);//代码名称字母/key
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());
//endregion
return aa10.getAaa102();
}
}
写完之后感觉针不戳,并且在编译期间程序也没有报啥子错,然后再运行的时候突然就出现问题,说缺少构造器。。。然后看了半天代码才看出来,由于我写的是一个工具类,所以属性是静态全局的。但是spring再初始化bean容器的时候并不支持给静态常量赋值。
解决
方法1:在构造方法上使用@autowrite
@Component
public class GlobalConstant {
//缓存常量 key值的格式为property_key 类别名称_类别内部名称的全大写形式
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 {
//缓存常量 key值的格式为property_key 类别名称_类别内部名称的全大写形式
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~