代码如下:
public boolean checkCarInBlackListByCache(String carNumber, String projectCode, Long parkingAreaId) {
Object o = redisUtil.get(getCarNumberCacheKey(carNumber, projectCode));
if (Objects.isNull(o)) {
ParkingBlackListQuery query = new ParkingBlackListQuery();
query.setCarNumber(carNumber);
query.setProjectCode(projectCode);
List<ParkingBlackListBO> list = list(query);
if (CheckUtils.isEmpty(list)) {
return false;
}
ParkingBlackListBO parkingBlackListBO = list.get(0);
redisUtil.set(getCarNumberCacheKey(carNumber, projectCode), parkingBlackListBO.getId());
Date date = new Date();
boolean valid = date.after(parkingBlackListBO.getEffectiveTimeBegin()) && date.before(parkingBlackListBO.getEffectiveTimeEnd());
return valid && parkingBlackListBO.getParkingArea().contains(parkingAreaId.toString());
}
Long id = (Long) o;
ParkingBlackListBO parkingBlackListBO = get(id);
if (Objects.isNull(parkingBlackListBO)) {
return false;
}
Date date = new Date();
boolean valid = date.after(parkingBlackListBO.getEffectiveTimeBegin()) && date.before(parkingBlackListBO.getEffectiveTimeEnd());
return valid && parkingBlackListBO.getParkingArea().contains(parkingAreaId.toString());
}
@Override
@Transactional(readOnly = true, rollbackFor = Throwable.class)
@Cacheable(value = "ParkingBlackListBOCache", key = "#id", unless = "#result == null")
public ParkingBlackListBO get(Long id) {
if (id == null) {
throw new RuntimeException("参数id不能为空");
}
// 查询数据之前的业务扩展
getBefore(id);
ParkingBlackListBO bo;
try {
// 执行数据库查询操作
bo = getDao(id);
} catch (Exception e) {
throw new RuntimeException("持久化操作异常", e);
}
// 数据查询之后的扩展
getAfter(bo);
// 数据查询成功之后的扩展
return getSuccess(bo);
}
当调用checkCarInBlackListByCache 该方法时,根据日志,发现每次还调用数据库查询。然后分析具体日志,发现调用get方法时,还是调用了数据库。判断是缓存注解没有起作用。
通过debug,跟踪源代码知道调用了缓存拦截器的方法org.springframework.cache.interceptor.CacheInterceptor#invoke
然后调用,切面注解支持方法进行具体的缓存注解处理org.springframework.cache.interceptor.CacheAspectSupport#execute(org.springframework.cache.interceptor.CacheOperationInvoker, java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
从这里看出,是通过调用代理对象进行增强处理的。
而在当在checkCarInBlackListByCache 方法里面调用get方法时,依然是旧对象,还不是代理对象,因此需要重新注入新的代理对象调用。才能保证get方法可以获取到缓存的数据。最终通过引入新的注入对象,进行调用
ParkingBlackListBO parkingBlackListBO = parkingBlackListService.get(id);
问题得到解决










