美文网首页shiroshiro
在Shiro框架内使用缓存注解失效的解决办法

在Shiro框架内使用缓存注解失效的解决办法

作者: 后端技术学习分享 | 来源:发表于2018-09-05 17:32 被阅读4次

    这个问题困扰了我好多天

    问题

    1. ServiceImpl类里的方法上有缓存注解,用于将返回的实体类存入redis,下次调用时就不需要通过数据库获取实体类信息。
    2. Shiro框架内由于自定义了Ream,需要注入Service来获取用户实体类信息。
    3. 而后运行时,发现缓存注解并没有起作用,两次调用Service方法,都进入了方法,而不是读取缓存。
    • 自定义Ream
    /**
     * 用来给shiro注入认证信息和授权信息
     */
    @Component("userRealm")
    public class UserRealm extends AuthorizingRealm{
    
        /**
         * shiro内注入bean时,需要加入lazy注解,否则bean可能不能正常运行(比如缓存注解)
         * 参考:https://blog.csdn.net/elonpage/article/details/78965176
         */
        @Autowired
        @Lazy
        private UserService userService;
    
        /**
         * 授权处理
         * 登录时不检查用户权限
         * @param principals
         * @return
         */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            return null;
        }
    
        /**
         * 身份认证
         *
         * @param authenticationToken
         * @return
         * @throws AuthenticationException
         */
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
            // 获取用户 - 这里调用了Service方法
            String account = (String) authenticationToken.getPrincipal();
            User user = userService.getUserByAccount(account,
                    DatabaseConst.STATUS_ENABLE,
                    DatabaseConst.IS_DETETED_NO);
            if (user  == null) {
                return null;
            }
    
            return new SimpleAuthenticationInfo(
                    user,
                    user.getPassword().toCharArray(),
                    ByteSource.Util.bytes("salt-sdwbhx23i"),//盐,可自定义
                    getName()
            );
        }
    }
    
    • Service方法
    @Service
    public class UserServiceImpl implements UserService{
        // 使用了缓存注解的方法,第二次执行时,应该直接从缓存中读取User实体信息
        @Cacheable(value = RedisConst.USER_INFO ,key = "#account")
        public User getUserByAccount(String account,int isEnable,int isDeleted) {
            //这里模拟从数据库中读取数据
            User user = new User();
            user.setAccount(account);
            user.setIsDeleted(isDeleted);
            user.setStatus(isEnable);
            return userMapper.selectOne(user);
        }
    }
    
    

    解决办法

    在Shiro框架内注入bean时,除了 @Autowired 注解外,再加入 @Lazy 注解。
    这样会使得注入到Shiro框架的Bean延时加载(即在第一次使用的时候加载)

    原因

    spring boot整合shiro后,部分注解(Cache缓存、Transaction事务等)失效的问题
    简单来说,就是Shiro框架初始化比Spring框架的某些部件早,导致使用@Autowire注入Shiro框架的某些类不能被Spring正确初始化。

    相关文章

      网友评论

        本文标题:在Shiro框架内使用缓存注解失效的解决办法

        本文链接:https://www.haomeiwen.com/subject/ykxzwftx.html