shiro框架学习-8-shiro缓存

1. shiro进行认证授权时会查询数据库获取用户角色权限信息,每次登录都会去查询,这样对性能会又影响。可以设置缓存,查询时先去缓存中查找,缓存中没有再去数据库查询。

 

 从shiro的架构图中可以看到有一个CacheManager——缓存管理器,可以使用 redis, hashmap, ehcache等作为缓存,可以在CacheManager中自定义。

shiro中提供了对认证信息和授权信息的缓存,默认是关闭认证信息缓存的,对于授权信息的缓存shiro默认开启的(因为授权的数据量大)。AuthenticatingRealm 及 AuthorizingRealm 分别提供了对AuthenticationInfo 和 AuthorizationInfo 信息的缓存。自定义的Realm继承了AuthorizingRealm,  最终会继承到CachingRealm:

 

 

 查看 AuthenticatingRealm源码,可以看到它持有了CacheManager的一个 引用

public abstract class AuthenticatingRealm extends CachingRealm implements Initializable {
    private static final Logger log = LoggerFactory.getLogger(AuthenticatingRealm.class);
    private static final AtomicInteger INSTANCE_COUNT = new AtomicInteger();
    private static final String DEFAULT_AUTHORIZATION_CACHE_SUFFIX = ".authenticationCache";
    private CredentialsMatcher credentialsMatcher;
    private Cache<Object, AuthenticationInfo> authenticationCache;
    private boolean authenticationCachingEnabled;
    private String authenticationCacheName;
    private Class<? extends AuthenticationToken> authenticationTokenClass;

    public AuthenticatingRealm() {
        this((CacheManager)null, new SimpleCredentialsMatcher());
    }

    public AuthenticatingRealm(CacheManager cacheManager) {
        this(cacheManager, new SimpleCredentialsMatcher());
    }
public AuthenticatingRealm(CredentialsMatcher matcher) {
this((CacheManager)null, matcher);
}

public AuthenticatingRealm(CacheManager cacheManager, CredentialsMatcher matcher) {
this.authenticationTokenClass = UsernamePasswordToken.class;
// 认证的缓存默认是关闭的,因为登录次数不会很频繁
this.authenticationCachingEnabled = false;
int instanceNumber = INSTANCE_COUNT.getAndIncrement();
this.authenticationCacheName = this.getClass().getName() + ".authenticationCache";
if (instanceNumber > 0) {
this.authenticationCacheName = this.authenticationCacheName + "." + instanceNumber;
}

if (cacheManager != null) {
this.setCacheManager(cacheManager);
}

if (matcher != null) {
this.setCredentialsMatcher(matcher);
}

}
 

而CacheManager 仅仅是一个接口,它默认有三个实现类,而自定义shiro缓存,就是去继承 抽象类 AbstractCacheManager实现缓存管理。

 

来看下授权的类中的构造器:

public abstract class AuthorizingRealm extends AuthenticatingRealm implements Authorizer, Initializable, PermissionResolverAware, RolePermissionResolverAware {
    private static final Logger log = LoggerFactory.getLogger(AuthorizingRealm.class);
    private static final String DEFAULT_AUTHORIZATION_CACHE_SUFFIX = ".authorizationCache";
    private static final AtomicInteger INSTANCE_COUNT = new AtomicInteger();
    private boolean authorizationCachingEnabled;
    private Cache<Object, AuthorizationInfo> authorizationCache;
    private String authorizationCacheName;
    private PermissionResolver permissionResolver;
    private RolePermissionResolver permissionRoleResolver;

    public AuthorizingRealm() {
        this((CacheManager)null, (CredentialsMatcher)null);
    }

    public AuthorizingRealm(CacheManager cacheManager) {
        this(cacheManager, (CredentialsMatcher)null);
    }

    public AuthorizingRealm(CredentialsMatcher matcher) {
        this((CacheManager)null, matcher);
    }

    public AuthorizingRealm(CacheManager cacheManager, CredentialsMatcher matcher) {
        if (cacheManager != null) {
            this.setCacheManager(cacheManager);
        }

        if (matcher != null) {
            this.setCredentialsMatcher(matcher);
        }
        // 授权默认开启了缓存
        this.authorizationCachingEnabled = true;
        this.permissionResolver = new WildcardPermissionResolver();
        int instanceNumber = INSTANCE_COUNT.getAndIncrement();
        this.authorizationCacheName = this.getClass().getName() + ".authorizationCache";
        if (instanceNumber > 0) {
            this.authorizationCacheName = this.authorizationCacheName + "." + instanceNumber;
        }

    }

 

posted @ 2019-12-24 07:37  清风拂来  阅读(652)  评论(0编辑  收藏  举报