shiro緩存配置詳細說明

分享知識 傳遞快樂


shiro緩存的兩種方案:

1、ehcache-core

先在pom.xml文件中引入包:
<dependency>
	<groupId>net.sf.ehcache</groupId>
	<artifactId>ehcache-core</artifactId>
	<version>2.6.11</version>
</dependency>

spring-ehcache.xml文件配置

<!-- 配置 Spring 的 EhCacheManagerFactoryBean -->
<bean id="cacheManagerFactoryBean" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
	<property name="configLocation" value="classpath:cache/ehcache.xml" />
	<!-- <property name="shared" value="true" /> -->
</bean>

<!-- spring 封裝ehcache緩存管理器 -->
<bean id="springCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
	<property name="cacheManager" ref="cacheManagerFactoryBean" />
</bean>

<!-- 激活spring 緩存註解 -->
<cache:annotation-driven cache-manager="springCacheManager" />
spring-shiro.xml文件配置
<!--安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
	<!-- ......省略了其它配置 --> 
	<!--將緩存管理器,交給安全管理器(Spring提供的Ehcache實現的緩存管理器) -->
	<property name="cacheManager" ref="shiroSpringCacheManager" /> 
</bean>
<!-- 用戶授權信息Cache, 採用spring-cache, 具體請查看spring-ehcache.xml -->
<bean id="shiroSpringCacheManager" class="com.xh.activiti.commons.cache.ShiroSpringCacheManager">
	<!-- cacheManager在spring-ehcache.xml裏能找到 -->
	<property name="cacheManager" ref="springCacheManager" />
</bean>

此時還要兩個類

package com.xh.activiti.commons.cache;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.util.Destroyable;

/**
 * 
 * <p>Title: 使用spring-cache作爲shiro緩存 緩存管理器</p>
 * <p>Description: </p>
 * 
 * @author H.Yang
 * @date 2018年3月6日
 *
 */
public class ShiroSpringCacheManager implements CacheManager, Destroyable {
	private static final Logger LOGGER = LogManager.getLogger(ShiroSpringCacheManager.class);

	private org.springframework.cache.CacheManager cacheManager;

	public org.springframework.cache.CacheManager getCacheManager() {
		return cacheManager;
	}

	public void setCacheManager(org.springframework.cache.CacheManager cacheManager) {
		this.cacheManager = cacheManager;
	}

	public <K, V> Cache<K, V> getCache(String name) throws CacheException {
		if (LOGGER.isTraceEnabled()) {
			LOGGER.trace("Acquiring ShiroSpringCache instance named [" + name + "]");
		}
		org.springframework.cache.Cache cache = cacheManager.getCache(name);
		return new ShiroSpringCache<K, V>(cache);
	}

	public void destroy() throws Exception {
		cacheManager = null;
	}
}
package com.xh.activiti.commons.cache;

import java.util.Collection;
import java.util.Collections;
import java.util.Set;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.shiro.cache.CacheException;
import org.springframework.cache.Cache;
import org.springframework.cache.Cache.ValueWrapper;

/**
 * 
 * <p>Title: 使用spring-cache作爲shiro緩存</p>
 * <p>Description: </p>
 * 
 * @author H.Yang
 * @date 2018年3月6日
 * 
 * @param <K>
 * @param <V>
 */
public class ShiroSpringCache<K, V> implements org.apache.shiro.cache.Cache<K, V> {
	private static final Logger LOGGER = LogManager.getLogger(ShiroSpringCache.class);

	private final org.springframework.cache.Cache cache;

	public ShiroSpringCache(Cache cache) {
		if (cache == null) {
			throw new IllegalArgumentException("Cache argument cannot be null.");
		}
		this.cache = cache;
	}

	public V get(K key) throws CacheException {
		if (LOGGER.isTraceEnabled()) {
			LOGGER.trace("Getting object from cache [" + this.cache.getName() + "] for key [" + key + "]key type:" + key.getClass());
		}
		ValueWrapper valueWrapper = cache.get(key);
		if (valueWrapper == null) {
			if (LOGGER.isTraceEnabled()) {
				LOGGER.trace("Element for [" + key + "] is null.");
			}
			return null;
		}
		return (V) valueWrapper.get();
	}

	public V put(K key, V value) throws CacheException {
		if (LOGGER.isTraceEnabled()) {
			LOGGER.trace("Putting object in cache [" + this.cache.getName() + "] for key [" + key + "]key type:" + key.getClass());
		}
		V previous = get(key);
		cache.put(key, value);
		return previous;
	}

	public V remove(K key) throws CacheException {
		if (LOGGER.isTraceEnabled()) {
			LOGGER.trace("Removing object from cache [" + this.cache.getName() + "] for key [" + key + "]key type:" + key.getClass());
		}
		V previous = get(key);
		cache.evict(key);
		return previous;
	}

	public void clear() throws CacheException {
		if (LOGGER.isTraceEnabled()) {
			LOGGER.trace("Clearing all objects from cache [" + this.cache.getName() + "]");
		}
		cache.clear();
	}

	public int size() {
		return 0;
	}

	public Set<K> keys() {
		return Collections.emptySet();
	}

	public Collection<V> values() {
		return Collections.emptySet();
	}

	@Override
	public String toString() {
		return "ShiroSpringCache [" + this.cache.getName() + "]";
	}

}


2、shiro-ehcache

先在pom.xml文件中引入包:

<dependency>
	<groupId>org.apache.shiro</groupId>
	<artifactId>shiro-ehcache</artifactId>
	<version>1.4.0</version>
</dependency>
shiro-ehcache.xml文件配置
<!-- Shiro提供的Ehcache實現的緩存管理器 -->
<!-- 配置 shiro 的 ehcache 緩存相關,這個緩存只和 Realm 相關 -->
<bean id="shiroCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
	<property name="cacheManagerConfigFile" value="classpath:cache/ehcache.xml"/> 
</bean>

<!-- 配置SecurityManager的管理 --> 
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> 
    <!-- ......省略了其它配置 --> 
    <property name="cacheManager" ref="cacheManager"/> 
</bean>



附:

兩者結合使用

spring-ehcache.xml文件配置
<!-- 如果有多個ehcacheManager要在bean加上p:shared="true" --><!-- Shiro提供的Ehcache實現的緩存管理器 -->
<!-- 配置 shiro 的 ehcache 緩存相關,這個緩存只和 Realm 相關 -->
<bean id="shiroCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
	<property name="cacheManager" ref="cacheManagerFactoryBean" />
</bean>

<!-- Spring提供的Ehcache實現的緩存管理器 -->
<!-- 配置 Spring 的 EhCacheManagerFactoryBean -->
<bean id="cacheManagerFactoryBean" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
	<property name="configLocation" value="classpath:cache/ehcache.xml" />
	<!-- 如果有多個ehcacheManager要在bean加上p:shared="true" -->
	<!-- <property name="shared" value="true" /> -->
</bean>

<!-- spring 封裝ehcache緩存管理器 -->
<bean id="springCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
	<property name="cacheManager" ref="cacheManagerFactoryBean" />
</bean>


<!-- 激活spring 緩存註解 -->
<cache:annotation-driven cache-manager="springCacheManager" />

spring-shiro.xml文件配置

<!--安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
	<!-- ......省略了其它配置 --> 
	<!-- Shiro提供的Ehcache實現的緩存管理器 -->
	<property name="cacheManager" ref="shiroCacheManager" />
</bean>

這樣就不用類了。





注意:

如果創建多個CacheManager對象時報以下異常: 

Caused by: net.sf.ehcache.CacheException: Another unnamed CacheManager already exists in the same VM. Please provide unique names for each CacheManager in the config or do one of following:
1. Use one of the CacheManager.create() static factory methods to reuse same CacheManager with same name or create one if necessary
2. Shutdown the earlier cacheManager before creating new one with same name.

解決方法:

 如果有多個cacheManager要在bean加上

p:shared="true"

<bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
	<property name="configLocation" value="classpath:cache/ehcache.xml"/>
	<property name="shared" value="true" />
</bean>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章