All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.iherus.shiro.cache.redis.RedisCacheManager Maven / Gradle / Ivy

There is a newer version: 2.5.0
Show newest version
/**
 * Copyright (c) 2016-2019, Bosco.Liao ([email protected]).
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.iherus.shiro.cache.redis;

import static org.iherus.shiro.cache.redis.Constant.DEFAULT_CACHE_EXPIRATION;
import static org.iherus.shiro.cache.redis.Constant.DEFAULT_CACHE_KEY_PREFIX;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.shiro.ShiroException;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.util.Destroyable;
import org.apache.shiro.util.Initializable;
import org.iherus.shiro.cache.redis.AbstractRedisOperations.DefaultRedisOperations;
import org.iherus.shiro.cache.redis.connection.BatchOptions;
import org.iherus.shiro.cache.redis.connection.RedisConnectionFactory;
import org.iherus.shiro.cache.redis.connection.jedis.JedisConnectionFactory;
import org.iherus.shiro.cache.redis.connection.lettuce.LettuceConnectionFactory;
import org.iherus.shiro.cache.redis.connection.redisson.RedissonConnectionFactory;
import org.iherus.shiro.cache.redis.connection.spring.CompatibleRedisConnectionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 

缓存管理器

*

Description:管理缓存池的初始化、获取当前缓存对象和销毁缓存池

* * @author Bosco.Liao * @since 1.0.0 */ public class RedisCacheManager implements CacheManager, Initializable, Destroyable { private static final Logger logger = LoggerFactory.getLogger(RedisCacheManager.class); @SuppressWarnings("rawtypes") private static final ConcurrentHashMap LOCAL_CACHE = new ConcurrentHashMap<>(); @SuppressWarnings("serial") private static final Map SCOPE_MAPPER = new HashMap() {{ put("Session", "session:"); put("Authorization", "authz:"); put("Authentication", "authc:"); }}; private final BatchOptions.Builder optionsBuilder = BatchOptions.builder(); /** * Set a Default key prefix for all caches. */ private String keyPrefix = DEFAULT_CACHE_KEY_PREFIX; /** * Cache object expiration time. */ private Duration expiration = DEFAULT_CACHE_EXPIRATION; /** * The cached object is stored in this database, but this property is invalid in {@literal Redis-Cluster}. */ private Integer database; /** * RedisConnectionFactory instance. * * @see JedisConnectionFactory * @see LettuceConnectionFactory * @see RedissonConnectionFactory * @see CompatibleRedisConnectionFactory */ private RedisConnectionFactory connectionFactory; public String getKeyPrefix() { return keyPrefix; } public void setKeyPrefix(String keyPrefix) { this.keyPrefix = keyPrefix; } public Duration getExpiration() { return expiration; } public void setExpiration(Duration expiration) { this.expiration = expiration; } public void setExpirationMillis(long expiration) { this.expiration = Duration.ofMillis(expiration); } public RedisConnectionFactory getConnectionFactory() { return connectionFactory; } protected RedisConnectionFactory getRequiredConnectionFactory() { RedisConnectionFactory factory = getConnectionFactory(); if (factory == null) { throw new CacheException("RedisConnectionFactory must not be null."); } return factory; } /** * Setting RedisConnectionFactory instance. * * @param connectionFactory RedisConnectionFactory instance. * * @see JedisConnectionFactory * @see LettuceConnectionFactory * @see CompatibleRedisConnectionFactory */ public void setConnectionFactory(RedisConnectionFactory connectionFactory) { this.connectionFactory = connectionFactory; } public Integer getDatabase() { return database; } /** * Sets shiro's cache to store the database. */ public void setDatabase(Integer database) { if (getRequiredConnectionFactory() instanceof CompatibleRedisConnectionFactory) { throw new UnsupportedOperationException( "CompatibleRedisConnectionFactory instance does not support this method."); } this.database = database; } public BatchOptions.Builder setScanBatchSize(int size) { return optionsBuilder.scanSize(size); } public BatchOptions.Builder setDeleteBatchSize(int size) { return optionsBuilder.deleteSize(size); } public BatchOptions.Builder setFetchBatchSize(int size) { return optionsBuilder.fetchSize(size); } @Override public void init() throws ShiroException { if (logger.isInfoEnabled()) { logger.info("Shiro CacheManager initializing..."); } RedisConnectionFactory factory = getRequiredConnectionFactory(); /** * Bug fixed. */ BatchOptions options = this.optionsBuilder.build(); if (!BatchOptions.defaulted.equals(options)) { factory.setBatchOptions(options); } try { if (connectionFactory instanceof org.iherus.shiro.cache.redis.connection.Initializable) { ((org.iherus.shiro.cache.redis.connection.Initializable) connectionFactory).init(); } } catch (Exception e) { throw new CacheException(e); } } @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public Cache getCache(String name) throws CacheException { Cache cache = LOCAL_CACHE.get(name); if (cache == null) { String scope = tryGetScope(); DefaultRedisOperations operations = new DefaultRedisOperations(getRequiredConnectionFactory()); cache = new RedisCache(name, operations, keyPrefix + scope, expiration, database); LOCAL_CACHE.put(name, cache); } return cache; } @Override public void destroy() throws Exception { if (logger.isInfoEnabled()) { logger.info("Shiro CacheManager destroying..."); } try { if (connectionFactory instanceof org.iherus.shiro.cache.redis.connection.Destroyable) { ((org.iherus.shiro.cache.redis.connection.Destroyable) connectionFactory).destroy(); } } catch (Exception e) { if (logger.isWarnEnabled()) { logger.warn("Unable to destroy connectionFactory instance gracefully and ignore it. (shutting down) "); } throw new CacheException(e); } } /** * Since 2.2.0 */ private static String tryGetScope() { StackTraceElement[] elements = Thread.currentThread().getStackTrace(); if (elements.length < 4) { return ""; } String methodName = elements[3].getMethodName(); for (Entry entry : SCOPE_MAPPER.entrySet()) { if (methodName.contains(entry.getKey())) { return entry.getValue(); } } return ""; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy