前言
我们在工具类中引入spring ioc容器中,在static 方法中使用需要使用。放在该ioc容器上面报Non-static field ‘jedisCluster’ cannot be referenced from a static context 这种错误。这个是因为spring 初始化容器的速度,可能会慢于工具类报错的速度导致该方法调用失败。
实践
我们遇到这种问题,一般会有两种方案。第一个是将该对象作为方法调用传参使用。特别是当该工具类的使用普遍、方法比较多的情况显得很麻烦。第二种、通过调用的时候利用ApplicationContext.getBean() 的方式进行初始化。这个利用到spring ioc容器的时候调用勾子方法来对ApplicationContext 初始化。
我们这里就在ware 这个阶段调用ApplicationContext 对应勾子方法对其进行初始化。
代码:
@Component
public class SpringUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
@Override
public void setApplicationContext(@NonNull ApplicationContext applicationContext) {
SpringUtils.applicationContext = applicationContext;
}
public static Object getBean(String name) {
return applicationContext.getBean(name);
}
public static <T> T getBean(Class<T> requiredType) {
return applicationContext.getBean(requiredType);
}
public static <T> T getBean(String name, Class<T> requiredType) {
return applicationContext.getBean(name, requiredType);
}
public static boolean containsBean(String name) {
return applicationContext.containsBean(name);
}
public static boolean isSingleton(String name) {
return applicationContext.isSingleton(name);
}
public static Class<?> getType(String name) {
return applicationContext.getType(name);
}
/**
* 获取当前环境
*
* @return String
*/
public static String getActiveProfile() {
String[] activeProfiles = getActiveProfiles();
return ArrayUtil.isNotEmpty(activeProfiles) ? activeProfiles[0] : null;
}
/**
* 获取当前环境
*
* @return String[]
*/
public static String[] getActiveProfiles() {
return applicationContext.getEnvironment().getActiveProfiles();
}
}
这里是一个使用的例子,在使用的时候通过内部类的方式来获取RedisTemplate 对象
@Slf4j
public class RedisUtil {
private static class SingletonRestTemplate {
static RedisTemplate<String, Object> instance = (RedisTemplate<String, Object>) SpringUtils.getBean("redisTemplate");
}
private RedisUtil() {}
public static RedisTemplate<String, Object> getInstance() {
return SingletonRestTemplate.instance;
}
/**
* 枷锁
*
*/
public static boolean deleteExclusionLock(String key) {
if (RedisUtil.getInstance().delete(key)) {
return true;
}
log.info("delete {}'s lock fail!", key);
return false;
}
/**
* 枷锁
*
*/
public static boolean exclusionLock(String key,Long timeOut) {
log.info("try to get lock for {}", key);
if (RedisUtil.getInstance().opsForValue().setIfAbsent(key,"1",timeOut,TimeUnit.MILLISECONDS)) {
return true;
}
return false;
}
/**
* 普通缓存获取
* @param key 键
* @return 值
*/
public static Object get(String key) {
boolean hasKey = RedisUtil.getInstance().hasKey(key);
return hasKey ? RedisUtil.getInstance().opsForValue().get(key) : "";
}
/**
* 普通缓存放入
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public static boolean set(String key, Object value) {
try {
RedisUtil.getInstance().opsForValue().set(key, value);
return true;
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
}
}
public static boolean mset(Map<String,Object> map) {
try {
RedisUtil.getInstance().opsForValue().multiSet(map);
return true;
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
}
}
/**
* 普通缓存放入并设置时间
* @param key 键
* @param value 值
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
* @param unit 时间单位
* @return true成功 false 失败
*/
public static boolean set(String key, Object value, long time, TimeUnit unit) {
try {
if (time > 0) {
RedisUtil.getInstance().opsForValue().set(key, value, time, unit);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
}
}
/**
* 递增
* @param key 键
* @param delta 要增加几(大于0)
* @return
*/
public static long incr(String key, long delta) {
if (delta < 0) {
throw new BusinessException("递增因子必须大于0");
}
return RedisUtil.getInstance().opsForValue().increment(key, delta);
}
/**
* 递减
* @param key 键
* @param delta 要减少几(小于0)
* @return
*/
public static long decr(String key, long delta) {
if (delta < 0) {
throw new BusinessException("递减因子必须大于0");
}
return RedisUtil.getInstance().opsForValue().increment(key, -delta);
}
/**
* 判断key是否存在
* @param key 键
* @return true 存在 false不存在
*/
public static boolean hasKey(String key) {
try {
return RedisUtil.getInstance().hasKey(key);
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
}
}
}