解决SpringBoot整合Shiro在@Autowired出现的空指针异常

前言

今天涛哥在做项目时,在filter类里出现了一个问题。发现总是在实例化单例对象报空指针异常

调试debug了好久都为null,错误信息如下

错误信息

部分代码

    /**
     * redis缓存工具类
     * */
    @Autowired
    private RedisCache redisCache;

    /**
     * 退出后重定向的地址
     */
    private String loginUrl;

    private Cache<String, Deque<Serializable>> cache;

    public String getLoginUrl()
    {
        return loginUrl;
    }

    public void setLoginUrl(String loginUrl)
    {
        this.loginUrl = loginUrl;
    }

    @Override
    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception
    {
        try
        {
            Subject subject = getSubject(request, response);
            String redirectUrl = getRedirectUrl(request, response, subject);
            try
            {
                SysUser user = ShiroUtils.getSysUser();
                if (StringUtils.isNotNull(user))
                {
                    String loginName = user.getLoginName();
                    // 记录用户退出日志
                    AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginName, Constants.LOGOUT, MessageUtils.message("user.logout.success")));
                    // 清理缓存
                    removeUserCache(loginName, ShiroUtils.getSessionId());
                    boolean isClean = redisCache.deleteObject("shiro:session:" + ShiroUtils.getSessionId());
                    if (isClean){
                        System.out.println("redis清除成功");
                    }
                }
                // 退出登录
                subject.logout();
            }
            catch (SessionException ise)
            {
                log.error("logout fail.", ise);
            }
            issueRedirect(request, response, redirectUrl);
        }
        catch (Exception e)
        {
            log.error("Encountered session exception during logout.  This can generally safely be ignored.", e);
        }
        return false;
    }

    public void removeUserCache(String loginName, String sessionId)
    {
        Deque<Serializable> deque = cache.get(loginName);
        if (StringUtils.isEmpty(deque) || deque.size() == 0)
        {
            return;
        }
        deque.remove(sessionId);
        cache.put(loginName, deque);
    }

分析原因

因为在配置shiro核心配置时,没有保证过滤器过滤单例

解决方法

通过反射的原理,交给spring容器去管理

    public static <T> T getBean(Class<T> clz) throws BeansException {
        T result = (T) beanFactory.getBean(clz);
        return result;
    }
阅读剩余
THE END