翻车现场:在过滤器里要做一个刷新用户token时长的功能,引入redis操作对象时发生了报错,说这个bean对象是null。一般参数对象报空指针错误,倒是常见。但是方法对象报空指针错误第一次见,一时间没反应过来😂,其实说到底,他也是个bean对象。
问题原因:造成null的问题是因为拦截器、过滤器这些文件在加载的时候,是在springcontext创建之前完成的,没法直接通过@Autowired注解直接获取bean,所以在拦截器、过滤器中注入实体对象就会为null。
解决方法:通过spring上下文来获取IOC管理的实体类
public class AccessDeniedFilter {
@Autowired
private IRedisOperateDAO iRedisOperateDAO;
//十分钟
private static final Long MINUTES_10 = 10 * 60 * 1000L;
/**
* 校验时间
* 过期时间与当前时间对比,临近过期10分钟内的话,自动刷新缓存
*
* @param loginUser
* @return
*/
private void checkLoginTime(LoginUserDto loginUser) {
long expireTime = loginUser.getExpireTime();
long currentTime = System.currentTimeMillis();
if (expireTime - currentTime <= MINUTES_10) {
loginUser.setLoginTime(System.currentTimeMillis());
loginUser.setExpireTime(loginUser.getLoginTime() + 120 * 60 * 1000);
if(null==iRedisOperateDAO){
iRedisOperateDAO = SpringBeanFactoryUtils.getBean(IRedisOperateDAO.class);
}
//将需要的登入信息存至redis中
String Sign = "zjmjToken:token-" + loginUser.getToken();
iRedisOperateDAO.set(Sign, FastJsonUtil.toJSONString(loginUser),120*60);
}
}
}
spring上下文获取bean
/**
* bean未加载前获取bean
*/
@Component
public class SpringBeanFactoryUtils implements ApplicationContextAware {
private static ApplicationContext context = null;
//获取bean
public static <T> T getBean(Class<T> type) {
return context.getBean(type);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringBeanFactoryUtils.context == null) {
SpringBeanFactoryUtils.context = applicationContext;
}
}
}