shiro教程:整合ehcache缓存
這個是在ssm的基礎上再去整合shiro和ehcache的,整合ehcache主要是為了減少后臺shiro攔截的次數,因為如果我們不使用緩存的話,后臺shiro的認證和授權的攔截器就會反復的進行攔截,導致系統的運行效率不高,因此使用緩存是一種很好的解決的方法,下面我們看看如何整合ehcache。
1、加入jar包pom.xml
在這之前,我們先加入shiro和ehcache的相關jar包
<!-- shiro --><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><exclusions><exclusion><artifactId>slf4j-api</artifactId><groupId>org.slf4j</groupId></exclusion></exclusions></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-ehcache</artifactId><exclusions><exclusion><artifactId>slf4j-api</artifactId><groupId>org.slf4j</groupId></exclusion></exclusions></dependency>2、配置ehcache.xml配置文件
在整合之前,我們需要配置一下ehcache的一些參數,設置好ehcache的環境。
<?xml version="1.0" encoding="UTF-8"?> <ehcache updateCheck="false" name="shiroCache"><diskStore path="C:\shiro\ehcache" /> <!-- <diskStore path="java.io.tmpdir"/> --><!-- eternal:緩存中對象是否為永久的,如果是,超時設置將被忽略,對象從不過期。 maxElementsInMemory:緩存中允許創建的最大對象數 overflowToDisk:內存不足時,是否啟用磁盤緩存。 timeToIdleSeconds:緩存數據的鈍化時間,也就是在一個元素消亡之前, 兩次訪問時間的最大時間間隔值,這只能在元素不是永久駐留時有效,如果該值是 0 就意味著元素可以停頓無窮長的時間。 timeToLiveSeconds:緩存數據的生存時間,也就是一個元素從構建到消亡的最大時間間隔值,這只能在元素不是永久駐留時有效,如果該值是0就意味著元素可以停頓無窮長的時間。 memoryStoreEvictionPolicy:緩存滿了之后的淘汰算法。 diskPersistent:設定在虛擬機重啟時是否進行磁盤存儲,默認為falsediskExpiryThreadIntervalSeconds: 屬性可以設置該線程執行的間隔時間(默認是120秒,不能太小1 FIFO,先進先出 2 LFU,最少被使用,緩存的元素有一個hit屬性,hit值最小的將會被清出緩存。 3 LRU,最近最少使用的,緩存的元素有一個時間戳,當緩存容量滿了,而又需要騰出地方來緩存新的元素的時候,那么現有緩存元素中時間戳離當前時間最遠的元素將被清出緩存。 --> <defaultCachemaxElementsInMemory="10000"eternal="false"timeToIdleSeconds="120"timeToLiveSeconds="120"overflowToDisk="false"diskPersistent="false"diskExpiryThreadIntervalSeconds="120"/><cache name="activeSessionCache"maxElementsInMemory="10000"eternal="true"overflowToDisk="false"diskPersistent="true"diskExpiryThreadIntervalSeconds="600"/><cache name="shiro.authorizationCache"maxElementsInMemory="100"eternal="false"timeToLiveSeconds="600"overflowToDisk="false"/></ehcache>3、整合spring
整合spring其實很簡單的,以前總覺得是一個很復雜的事情一樣,每次什么都要整合spring,其實spring就是一個容器,再說的直白點,就是一個map類似的容器,然后通過對容器的操作來實現,因此,如果我們需要讓spring來管理ehcache的話,我們只是需要將ehcache的配置文件交給spring來管理即可。
下面就是spring的配置文件applicationContext-ehcache.xml的ehcache的配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:cache="http://www.springframework.org/schema/cache"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/cachehttp://www.springframework.org/schema/cache/spring-cache.xsd "><!-- 安全管理器 --><bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><property name="realm" ref="userRealm" /><property name="cacheManager" ref="cacheManager"/></bean><!-- 緩存管理器 --><bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"><property name="cacheManagerConfigFile" value="classpath:shiro-ehcache.xml"/></bean> </beans>4、緩沖清空
當用戶權限修改后,用戶再次登陸shiro會自動調用realm從數據庫獲取權限數據,如果在修改權限后想立即清除緩存則可以調用realm的clearCache方法清除緩存。
realm中定義clearCached方法:
@Component public class ShiroDBRealm extends AuthorizingRealm {/*** * @Description: 權限修改生效后,立即刷新清空緩存,則可以實現用戶不退出生效新的權限* * @author sihai* @date 2017年9月29日 下午9:34:07*/public void clearCache() {PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();super.clearCache(principals);} }5、測試是否整合成功
@Component public class ShiroDBRealm extends AuthorizingRealm {@Autowiredprivate UserService userService; public ShiroDBRealm(CacheManager cacheManager) {super(cacheManager);}/*** 用于登錄認證*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {// 1. 從token中獲取用戶在表單中輸入的域,即 用戶名 以及 密碼,以此來和數據庫中的用戶真實數據進行匹配UsernamePasswordToken userToken = (UsernamePasswordToken)token;String username = userToken.getUsername(); // 用戶的登錄名String password = String.valueOf(userToken.getPassword()); // 用戶的密碼// 2. 根據用戶輸入的用戶名和數據庫進行匹配,查詢數據庫中的用戶,如果查詢不到,則返回一個nullSysUser user = userService.queryUserByUsername(username);// 3. 判斷數據庫中查詢出來的用戶是否存在,不存在代表用戶名密碼錯誤;如果存在,則返回 AuthenticationInfoif (user == null) {return null;}String dbPassword = user.getPassword();String dbSalt = user.getAuthSalt();String userPassword = ShiroPasswordUtil.getShiroPassword(password, dbSalt, 2);if (!userPassword.equals(dbPassword)) {// 拋出一個異常,密碼不正確throw new IncorrectCredentialsException();}ActiveUser activeUser = new ActiveUser();activeUser.setUserId(user.getId());activeUser.setUsername(user.getUsername());// 4. 返回AuthenticationInfo// 參數意義:// Object principal: 用戶對象,可以使一個對象類,或者一個字符串,存與session中 // Object credentials:密碼 // 題外話:我們目前直接根據用戶名密碼來查詢,所以這里直接放用戶輸入的密碼即可;但是,也可疑直接用用戶名來查詢數據庫中的用戶,再然后進行密碼的比對,如此則此處應該填寫用戶輸入的密碼// String realmName:當前我們自定義realm的名稱AuthenticationInfo info = new SimpleAuthenticationInfo(activeUser, password, getName());return info;}/*** 用于授權鑒權*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {// 從principals中獲取當前用戶ActiveUser sessionUser = (ActiveUser)principals.getPrimaryPrincipal();String userid = sessionUser.getUserId();// 模擬從數據庫中獲取用戶的權限(資源權限字符串)List<SysPermission> permissionList = null;try {permissionList = userService.findPermissionListByUserId(userid);} catch (Exception e) {e.printStackTrace();}List<String> percodeList = new ArrayList<String>();for (SysPermission p : permissionList) {percodeList.add(p.getPercode());}SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();simpleAuthorizationInfo.addStringPermissions(percodeList);return simpleAuthorizationInfo;} }上面登錄認證和授權的代碼,當我們沒有加入ehcache緩存的時候,我們前臺每次授權認證的時候,我們都會訪問這段代碼,如果當我們只會第一次訪問,后面不再訪問的時候,說明整合成功了。
總結
以上是生活随笔為你收集整理的shiro教程:整合ehcache缓存的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java.lang.NoClassDef
- 下一篇: shiro教程:session管理