天天看點

在Shiro架構内使用緩存注解失效的解決辦法

這個問題困擾了我好多天

問題

  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正确初始化。