前言
在上一篇文章中,我们写了相关shiro的权限管理,我们可以看到,用户权限的授予是通过自定义Realm中的授权方法doGetAuthorizationInfo(PrincipalCollection principals)实现的,这样虽然初步解决了权限的管理问题,但是用户在每一次对功能方法的访问都会调用这个授权方法去获取自己的权限,这样的重复查询访问数据库无疑降低了系统的运行效率。所以shiro整合ehcache迫在眉睫。
ehcache配置简要说明
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<!--timeToIdleSeconds 当缓存闲置n秒后销毁 -->
<!--timeToLiveSeconds 当缓存存活n秒后销毁 -->
<!--
缓存配置
name:缓存名称。
maxElementsInMemory:缓存最大个数。
eternal:对象是否永久有效,一但设置了,timeout将不起作用。
timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。
diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
maxElementsOnDisk:硬盘最大缓存个数。
diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
clearOnFlush:内存数量最大时是否清除。
-->
shiro整合ehcache
【1】下载jar包
com.springsource.net.sf.ehcache-1.6.2.jar
【2】配置ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
</ehcache>
【3】将缓存管理器注入spring
<!-- 注册缓存管理器 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<!-- 根据cache配置set注入 -->
<property name="cacheManagerConfigFile" value="classpath:ehcache.xml"></property>
</bean>
这里cacheManager的注入要读取缓存配置文件,根据配置注入进spring
【4】将缓存管理器托管给shiro的securityManager核心管理器管理
<!-- 注入 securityManager管理器-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!-- 将自定义realm注入给securityManager管理 -->
<property name="realm" ref="bosRealm"></property>
<!-- 将缓存管理器注入给控制器 -->
<property name="cacheManager" ref="cacheManager"></property>
</bean>
根据下图,我们可以知道securityManager是shiro的核心管理器,所有的认证器、授权器、realm、session已经缓存均由他管理,所以务必要将缓存管理器cacheManagerset注入给securityManager核心管理器。
好了,以上配置就完成了我们shiro与ehcache的整合,最后来一个shiro在spring中完整的配置
<!-- 配置工厂bean,用于创建shiro框架用到过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- 注入安全管理 -->
<property name="securityManager" ref="securityManager"></property>
<!-- 注入当前系统的登录页面 -->
<property name="loginUrl" value="/login.jsp"></property>
<!-- 注入成功页面 -->
<property name="successUrl" value="/index.jsp"></property>
<!-- 注入权限不足页面 -->
<property name="unauthorizedUrl" value="/unauthorizedUrl.jsp"/>
<!-- 注入url拦截规则 -->
<property name="filterChainDefinitions">
<value>
/css/** = anon
/images/** = anon
/js/** = anon
/login.jsp* = anon
/validatecode.jsp* = anon
/userAction_login.action = anon
/page_base_staff.action = perms["staff"]<!-- roles角色集,perms权限集 -->
/* = authc
</value>
<!--
/page_base_staff.action = roles["staff"]//要访问此action必须有staff这个角色
/page_base_staff.action = perms["staff"]//要访问此action必须有staff这个权限
-->
</property>
</bean>
<!-- 注册自定义realm -->
<bean id="bosRealm" class="com.itheima.bos.shiro.BOSRealm"></bean>
<!-- 注入 securityManager管理器-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!-- 将自定义realm注入给securityManager管理 -->
<property name="realm" ref="bosRealm"></property>
<!-- 将缓存管理器注入给控制器 -->
<property name="cacheManager" ref="cacheManager"></property>
</bean>
<!-- 注册缓存管理器 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<!-- 根据cache配置set注入 -->
<property name="cacheManagerConfigFile" value="classpath:ehcache.xml"></property>
</bean>
<!-- 开启shiro注解 -->
<bean id="defaultAdvisorAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
<!-- 强制使用cglib为Action创建代理对象() -->
<property name="proxyTargetClass" value="true"></property>
</bean>
<!-- 切面类 -->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"/>