shiro中部分SpringCache失效问题

1、问题抛出

今天在做Springboot和shiro集成时,发现一个严重的问题。部分service的缓存和事务失效,debug代码时,发现这些有问题的service实例都不是代理生成的,所以事务和缓存就失效了(事务和缓存依赖代理类实现)。继续查问题,发现这些有问题的service全部被shiro的realm所依赖,所以怀疑是shiro影响了

所以做一下测试:

shiro中用到的ResourceService

public class LocalRealmService extends RealmService {
    @Autowired
    private ResourceService resourceService;
    ...
}

controller也调用ResourceService

@RestController
@RequestMapping(value = "/test")
public class CacheController {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private ResourceService resourceService;
}

结果发现resourceService的实例如图:

发现问题:resourceService的实例不是代理即缓存注解和事务全部生效(缓存和事务都是代理完成的)

当我把resourceService从realm依赖中删除时,在controller引用时resourceService的实例就是“代理”即缓存和事务生效

结论:只要被shiro的realm所依赖的service,代理会全部失效(暂时没撸源码,还不知原理,知道的童鞋可以说下,谢了)

2、解决的方案

常用的解决方式有三种:

第一种:这是网上比较多的

就是realm中不要依赖service,依赖dao

第二种:在依赖的service上添加@Lazy注解

延迟加载,就是在实例化shiro的realm时,不去实例化service的bean,等到用的时候再从spring容器中去取对应的Bean

public class LocalRealmService extends RealmService {

    @Lazy
    @Autowired
    private ResourceService resourceService;
    ...
}

这种解决方案让我感觉到:这里是不是存在多个上下文,或者不是spring?这里有待后续考证。。。

第三种:shiro在实例化securityManager时,先不设置realm,等到容器加载完再设置

这种方式与第二种类似,只不过无需在每个service属性上增加@Lazy注解

SecurityMangaerd的实例化

/**
* 注释掉realm
*/
@Bean("securityManager")
public DefaultWebSecurityManager securityManager(/*@Qualifier("realm") BootRealm BootRealm,*/
                                                 SessionManager sessionManager,
                                                 CacheManager shiroCacheManager) {
    DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
    //注释掉
    //manager.setRealm(hyBootRealm);
}

容器加载完设置realm:这里有多重方案,主要列举两种

I、利用spring监听

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;

@Component
public class ShiroRealmListener implements ApplicationListener {
    @Autowired
    private DefaultWebSecurityManager securityManager;
    @Autowired
    private HyBootRealm realm;

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        securityManager.setRealm(realm);
    }
}

II、利用springboot的ApplicationRunner

import com.chyjr.hyboot.security.shiro.realm.HyBootRealm;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;

public class ShiroRealmRunner implements ApplicationRunner {

    @Autowired
    private DefaultWebSecurityManager securityManager;
    @Autowired
    private HyBootRealm realm;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        securityManager.setRealm(realm);
    }
}

注意:ShiroRealmRunner必须是spring的Bean,所以在配置管理类中要添加:

@Bean
public ShiroRealmRunner shiroRealmRunner(){
    return new ShiroRealmRunner();
}

总结:上述就是常用的解决方案,至于原理后续会抽时间研究....

原文地址:https://www.cnblogs.com/liruiloveparents/p/9392159.html

时间: 2024-08-29 00:50:30

shiro中部分SpringCache失效问题的相关文章

从零到实现Shiro中Authorization和Authentication的缓存

本文大纲 一.简介 二.缓存的概念 三.自定义实现缓存机制 四.什么是Ehcache 五.Ehcache怎么用 六.Spring对缓存的支持 七.Spring+Ehcache实现 八.Spring+Shiro+Ehcache实现 九.总结 一.简介 在项目中,用到Shiro来做验证授权的控制.但在实际使用的时候,发现用户每访问一个功能,都会重新到UserRealm中获取一次权限.这样子会花费大量的系统系统.此时就想到了使用缓存,查了一下,Shiro也确实支持Authorization和Authe

shiro中的reaml理解及实现机制

shiro中的reaml非常重要,所有的身份数据验证都在reaml中实现.可以把Realm看成DataSource,即安全数据源. Shiro从Realm获取安全数据(如用户.角色.权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法: 也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作. 下面以例子讲解其实现机制: 最开始用户.角色.权限都配置在shiro.ini配置文件中. 但实际项目中更多的是保存数

关于iOS7中UIView效果失效问题的解决

近期想做一个跑马灯的效果,于是写出了如下的跑马灯效果的代码...但是调试发现,在iOS6下动画是可以执行的,但是在iOS7下动画并不执行,没有达到预期的效果. [_scrollLabel sizeToFit]; CGRect frame = _scrollLabel.frame; frame.origin.x = 320; _scrollLabel.frame = frame; [UIView setAnimationsEnabled:YES]; [UIView beginAnimations:

shiro中CacheManager相关的类结构介绍,提供redis Cache实现

cacheManager主要用于对shiro中的session.realm中的认证信息.授权信息进行缓存. 1.类结构 2.接口及类介绍 CacheManager 提供根据名字获取cache的作用. AbstractCacheManager 本地提供并发map做缓存.提供抽象类给子类继承,子类只需要创建cache即可. MemoryConstrainedCacheManager 实现上面的抽象类.创建一个map作为缓存. 3.Cache相关介绍 Cache接口 主要提供缓存相关的增删改查方法.

Shiro中的Rememberme后出现浏览器500错误

问题详述:在Shiro中添加Remember me功能后,只要勾选Remember me选项为true的时候,浏览器就会跳转到一个不可达页面,并且在Chrome中显示HTTP 500错误. 问题追踪: 1. 设置Shiro的日志权限级别为DEBUG log4j设置 # Default Shiro logging log4j.logger.org.apache.shiro=DEBUG 2.点击登录按钮,查看日志输入: DEBUG - Authentication successful for to

项目一:第十三天 1、菜单数据管理 2、权限数据管理 3、角色数据管理 4、用户数据管理 5、在realm中动态查询用户权限,角色 6、Shiro中整合ehcache缓存权限数据

1 课程计划 菜单数据管理 权限数据管理 角色数据管理 用户数据管理 在realm中动态查询用户权限,角色 Shiro中整合ehcache缓存权限数据         2 菜单数据添加 2.1 使用combotree父菜单项数据     1. 页面:menu_add.jsp 2. 修改组件样式:easyui-combotree,修改url  树型表格treeGrid跟下来数combotree要求数据格式基本一致. Combotree通过text属性展示文本.   3. 使用treegrid组件的

jsp输出shiro中session信息

一.引用shiro标签 jsp页面头部引用<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>标签 二.shiro中存放的是用户名等字符串: <shiro:principal/> 三.shiro中存放的是用户对象,property是对象里面的属性,相当于user.getUserName() <shiro:principal property="userN

[转]教你修复win7中复制粘贴失效的问题

教你修复win7中复制粘贴失效的问题 发布时间:2018-01-17       使用win7系统的时候,我们经常需要对立面的内容进行复制粘贴来引用一些网站的内容,不过最近有网友在使用这个功能的时候,发现不能复制粘贴下来,对于这样的问题你了解是怎么回事吗?下面就让小编来给大家介绍下这样的问题怎样修复.       Win7下为什么不能复制粘贴 不能复制粘贴的主要症状: 1.无法复制粘贴文件和文件夹: 2.Ctrl+C和Ctrl+V键组合键失效. 不能复制粘贴时可能的潜在原因: 1.系统常用功能组

Shiro权限管理框架(三):Shiro中权限过滤器的初始化流程和实现原理

本篇是Shiro系列第三篇,Shiro中的过滤器初始化流程和实现原理.Shiro基于URL的权限控制是通过Filter实现的,本篇从我们注入的ShiroFilterFactoryBean开始入手,翻看源码追寻Shiro中的过滤器的实现原理. 初始化流程 ShiroFilterFactoryBean实现了FactoryBean接口,那么Spring在初始化的时候必然会调用ShiroFilterFactoryBean的getObject()获取实例,而ShiroFilterFactoryBean也在