shiro中的缓存的配置与使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/csujiangyu/article/details/49076531

shiro缓存

缓存是提供性能的重要手段。缓存适合那些经常不变动的数据,比如系统中用户的信息和权限不会经常改变,特别适合缓存起来供下次使用。这样减少了系统查询数据库的次数,提升了性能。shiro自身不实现缓存,而是提供缓存接口,让其他第三方实现,经常EHcache缓存。

shiro配置EHcache(spring-shiro-web.xml)

    <!-- 缓存管理器 使用Ehcache实现 -->
    <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManagerConfigFile" value="classpath:config/ehcache.xml" />
    </bean> 

    <!-- Realm实现 -->
    <bean id="userRealm" class="com.myweb.security.realm.UserRealm">
        <property name="credentialsMatcher" ref="credentialsMatcher" />
        <property name="cachingEnabled" value="true" />
        <property name="authenticationCachingEnabled" value="true" />
        <property name="authenticationCacheName" value="authenticationCache" />
        <property name="authorizationCachingEnabled" value="true" />
        <property name="authorizationCacheName" value="authorizationCache" />
    </bean> 

    <!-- 安全管理器 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="userRealm" />
        <property name="sessionManager" ref="sessionManager" />
        <property name="cacheManager" ref="cacheManager" />
        <property name="rememberMeManager" ref="rememberMeManager" />
    </bean> 

ehcache的配置

    <!-- 授权缓存 -->
    <cache name="authorizationCache"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>
    <!-- 认证缓存 -->
    <cache name="authenticationCache"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache> 

认证中缓存的使用(AuthenticatingRealm 类)

shiro主要使用AuthenticatingRealm 类进行认证,其中getAuthenticationInfo方法中使用了缓存。在getAuthenticationInfo中,首先判断是否有缓存记录,没有的话,再调用子类Ream的doGetAuthenticationInfo方法查询数据库,再将查询到数据缓存起来,下次就不用查询数据库。核心代码:

    public final AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //首先从缓存中获取记录
        AuthenticationInfo info = getCachedAuthenticationInfo(token);
        if (info == null) {
            //otherwise not cached, perform the lookup:
            info = doGetAuthenticationInfo(token);
            log.debug("Looked up AuthenticationInfo [{}] from doGetAuthenticationInfo", info);
            if (token != null && info != null) {
                  //将记录缓存起来
                cacheAuthenticationInfoIfPossible(token, info);
            }
        } else {
            log.debug("Using cached authentication info [{}] to perform credentials matching.", info);
        }
        if (info != null) {
            assertCredentialsMatch(token, info);
        } else {
            log.debug("No AuthenticationInfo found for submitted AuthenticationToken [{}].  Returning null.", token);
        }
        return info;
    } 

授权中缓存的使用(AuthorizingRealm类)

主要实现为AuthorizingRealm类中getAuthorizationInfo方法。过程和认证挺相似,首先找缓存,没有的话再去数据库找。核心代码如下:

    protected AuthorizationInfo getAuthorizationInfo(PrincipalCollection principals) {
        if (principals == null) {
            return null;
        }
        AuthorizationInfo info = null;
        if (log.isTraceEnabled()) {
            log.trace("Retrieving AuthorizationInfo for principals [" + principals + "]");
        }
        Cache<Object, AuthorizationInfo> cache = getAvailableAuthorizationCache();
        if (cache != null) {
            if (log.isTraceEnabled()) {
                log.trace("Attempting to retrieve the AuthorizationInfo from cache.");
            }
            Object key = getAuthorizationCacheKey(principals);
            info = cache.get(key);
            if (log.isTraceEnabled()) {
                if (info == null) {
                    log.trace("No AuthorizationInfo found in cache for principals [" + principals + "]");
                } else {
                    log.trace("AuthorizationInfo found in cache for principals [" + principals + "]");
                }
            }
        }
        if (info == null) {
            // Call template method if the info was not found in a cache
            info = doGetAuthorizationInfo(principals);
            // If the info is not null and the cache has been created, then cache the authorization info.
            if (info != null && cache != null) {
                if (log.isTraceEnabled()) {
                    log.trace("Caching authorization info for principals: [" + principals + "].");
                }
                Object key = getAuthorizationCacheKey(principals);
                cache.put(key, info);
            }
        }
        return info;
    } 

源码

托管在https://github.com/Jdoing/myweb

展开阅读全文

没有更多推荐了,返回首页