EnterpriseCacheSessionDAO
Shiro本身已经提供了一个SessionDAO的实现能保存企业级/分布式的缓存数据。这个实现就是EnterpriseCacheSessionDAO,可以在CacheManager中配置它来实现缓存机制。配置如下:
#This implementation would use your preferred distributed caching product's APIs:
activeSessionCache = my.org.apache.shiro.cache.CacheImplementation
securityManager.sessionManager.sessionDAO = $sessionDAO
虽然象上面介绍的方法你可要直接往SessionDAO里注入一个Cache实例,但还可以用一种更常见的方式可以为Shiro中所有需要用到缓存的地方配置一个通用的CacheManager。在这种方式中你可以告诉EnterpriseCacheSessionDAO一个Cache的名字,而这个Cache是用来存储活动的会话。
例如:
# This implementation would use your caching product's APIs:
cacheManager = my.org.apache.shiro.cache.CacheManagerImplementation
# Now configure the EnterpriseCacheSessionDAO and tell it what
# cache in the CacheManager should be used to store active sessions:
sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
# This is the default value. Change it if your CacheManager configured a different name:
sessionDAO.activeSessionsCacheName = shiro-activeSessionsCache
# Now have the native SessionManager use that DAO:
securityManager.sessionManager.sessionDAO = $sessionDAO
# Configure the above CacheManager on Shiro's SecurityManager
# to use it for all of Shiro's caching needs:
securityManager.cacheManager = $cacheManager
这种配置方法的特点是不论配置在什么地方,实际上是告诉SessionDAO实例都要使用Cache或CacheManager。那么SessionDAO是怎么使用分布式缓存呢?
当Shiro初始化SecurityManager时,它会检查SessionDAO是否实现了CacheManagerAware的接口。如果是的话,它会自动支持任何可用的全局配置的CacheManager。
当Shiro读到securityManager.cacheManager = $ cacheManager这一行时,它会发现EnterpriseCacheSessionDAO实现了CacheManagerAware的接口并且调用setCacheManager方法,将你配置的CacheManager作为方法参数。
然后在运行时,当EnterpriseCacheSessionDAO需要activeSessionsCache的时候将要求CacheManager实例化并返回它,使用activeSessionsCacheName做为查询的关键字来得到缓存实例。该高速缓存实例将被用于存储和检索会话所有的SessionDAO CRUD操作。
使用Ehcache + Terracotta
在Shiro中使用Enchache+Terracotta提供分布式缓存解决方案已相当成熟。在这个解决方案中象上面描述的Enchache会话缓存配置将不能正常工作,需要做一些Terracotta配置。配置信息要保存到一个enchance.xml文件,例如:
<ehcache>
<terracottaConfig url="localhost:9510"/>
<diskStore path="java.io.tmpdir/shiro-ehcache"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120">
<terracotta/>
</defaultCache>
<cache name="shiro-activeSessionCache"
maxElementsInMemory="10000"
eternal="true"
timeToLiveSeconds="0"
timeToIdleSeconds="0"
diskPersistent="false"
overflowToDisk="false"
diskExpiryThreadIntervalSeconds="600">
<terracotta/>
</cache>
<!-- Add more cache entries as desired, for example,
Realm authc/authz caching: -->
</ehcache>
你需要修改<terracottaConfig url="localhost:9510"/>的内容,写入相应的Terracotta服务器阵列的主机/端口。另请注意, activeSessionCache元素的diskPersistent或overflowToDisk属性都应该是false的,在群集配置中不支持true。
除此之外还需要在Shiro中进行配置:
sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
# This name matches a cache name in ehcache.xml:
sessionDAO.activeSessionsCacheName = shiro-activeSessionsCache
securityManager.sessionManager.sessionDAO = $sessionDAO
# Configure The EhCacheManager:
cacheManager = org.apache.shiro.cache.ehcache.EhCacheManager
cacheManager.cacheManagerConfigFile = classpath:ehcache.xml
# Configure the above CacheManager on Shiro's SecurityManager
# to use it for all of Shiro's caching needs:
securityManager.cacheManager = $cacheManager
请记住,顺序很重要。通过在SecurityManager最后配置CacheManager,我们能确保CacheManager可以传播到所有先前配置的CacheManagerAware组件(如EnterpriseCachingSessionDAO)中。