您的位置:首页 > 数据库 > Redis

redis+spring注解方式实现配置缓存时间过期

2017-06-28 20:17 645 查看
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> 

  <!-- 最大连接数 -->
<property name="maxTotal" value="500" />

  <!-- 最大空闲连接数 -->

        <property name="maxIdle" value="30"></property> 

        <!-- 连接最小空闲时间 -->
  <property name="minEvictableIdleTimeMillis" value="300000"></property> 
  <!-- 每次释放连接的最大数目 -->
  <property name="numTestsPerEvictionRun" value="3"></property> 
  <!-- 释放连接的扫描间隔(毫秒) -->
  <property name="timeBetweenEvictionRunsMillis" value="1800000"></property>
  <!-- 连接空闲多久后释放, 当空闲时间>该值 且 空闲连接>最大空闲连接数 时直接释放 -->
<property name="softMinEvictableIdleTimeMillis" value="10000" />
<!-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 -->
<property name="maxWaitMillis" value="1500" />
<!-- 在获取连接的时候检查有效性, 默认false -->
<property name="testOnBorrow" value="true" />
<!-- 在空闲时检查有效性, 默认false -->
<property name="testWhileIdle" value="true" />
<!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true -->
<property name="blockWhenExhausted" value="false" />
</bean> 

  <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy"> 
  <property name="poolConfig" ref="jedisPoolConfig"></property> 
  <property name="hostName" value="127.0.0.1"></property> 
  <property name="port" value="6379"></property> 
  <property name="timeout" value="15000"></property> 
  <property name="usePool" value="true"></property> 

  </bean> 

  <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> 
  <property name="connectionFactory" ref="jedisConnectionFactory"></property> 
  <property name="keySerializer"> 
  <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/> 

  </property> 
  <property name="valueSerializer"> 
  <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/> 
  </property> 

  </bean> 

 

  <!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 -->    

    <cache:annotation-driven cache-manager="redisCacheManager" />    

    

    <bean id="redisCacheManager" class="com.douwong.manage.test.action.ExtendedRedisCacheManager"> 
   <!-- <constructor-arg ref="redisTemplate" />
是否使用前缀 默认:是
<property name="usePrefix" value="true" />
<property name="defaultExpiration" value="3600" /> -->

<constructor-arg name="redisOperations" ref="redisTemplate"/>

        <constructor-arg name="cacheNames">

            <set>

                <value>caiya_a</value>

                <value>caiya_test</value>

                <value>sampleCache1</value>

                <value>memoryCache</value>

                <value>scanCache</value>

                <value>padIndexCache</value>

                <value>sampleCache1</value>

                <value>sampleCache1</value>

            </set>

        </constructor-arg>

        <!-- 默认缓存名字 -->

        <property name="defaultCacheName" value="caiya_a"/>

        <!-- 是否在容器启动时初始化 -->

        <property name="loadRemoteCachesOnStartup" value="true"/>

        <!-- 是否使用前缀 -->

        <property name="usePrefix" value="true"/>

        <!-- 前缀命名,仅当usePrefix为true时才生效 -->

        <property name="cachePrefix">

            <bean class="org.springframework.data.redis.cache.DefaultRedisCachePrefix">

                <constructor-arg name="delimiter" value=":"/>

            </bean>

        </property>

        <!-- 缓存名字和有效期的分隔符 -->

        <property name="separator" value="#"/>

        <!-- 默认有效期1h -->

        <property name="defaultExpiration" value="3600"/>

        <!-- 多个缓存有效期,一般的单个工程可以省略此项 -->

        <!-- <property name="expires">

            <map>

                <entry key="caiya_a" value="1800"/>

            </map>

        </property> -->

    </bean>

package com.douwong.manage.test.action;

import java.util.Collection;

import java.util.Collections;

import java.util.regex.Pattern;

import javax.script.ScriptEngine;

import javax.script.ScriptEngineManager;

import javax.script.ScriptException;

import org.apache.commons.lang.StringUtils;

import org.apache.log4j.Logger;

import org.springframework.cache.Cache;

import org.springframework.data.redis.cache.RedisCache;

import org.springframework.data.redis.cache.RedisCacheManager;

import org.springframework.data.redis.cache.RedisCachePrefix;

import org.springframework.data.redis.core.RedisOperations;

//import lombok.extern.log4j.Log4j2;

/**

 * 扩展redis缓存管理器

 * <p>

 * 重写 RedisCacheManager createCache 方法

 * <p>

 * 在缓存名字上添加过期时间表达式 如:cachename#60*60

 * @author hbp

 */

public class ExtendedRedisCacheManager extends RedisCacheManager {

private static final Logger logger = Logger.getLogger(ExtendedRedisCacheManager.class);

    private static final ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("JavaScript");

    private static final Pattern pattern = Pattern.compile("[+\\-*/%]");

    private String defaultCacheName;

    private char separator = '#';

    public ExtendedRedisCacheManager(RedisOperations redisOperations) {

        this(redisOperations, Collections.<String>emptyList());

    }

    public ExtendedRedisCacheManager(RedisOperations redisOperations, Collection<String> cacheNames) {

        super(redisOperations, cacheNames);

    }

    @Override

    public Cache getCache(String name) {

        // try to get cache by name

        RedisCache cache = (RedisCache) super.getCache(name);

        if (cache != null) {

            return cache;

        }

        // there's no cache which has given name

        // find separator in cache name

        int index = name.lastIndexOf(getSeparator());

        if (index < 0) {

            return null;

        }

        // split name by the separator

        String cacheName = name.substring(0, index);

        if(StringUtils.isBlank(cacheName)){

            cacheName = defaultCacheName;

        }

        cache = (RedisCache) super.getCache(cacheName);

        if (cache == null) {

            return null;

        }

        // get expiration from name

        Long expiration = getExpiration(name, index);

        if (expiration == null || expiration < 0) {

            logger.warn("Default expiration time will be used for cache '{}' because cannot parse '{}', cacheName : " + cacheName + ", name : " + name);

            return cache;

        }

        return new RedisCache(cacheName, (isUsePrefix() ? getCachePrefix().prefix(cacheName) : null), getRedisOperations(), expiration);

    }

    public char getSeparator() {

        return separator;

    }

    /**

     * Char that separates cache name and expiration time, default: #.

     *

     * @param separator

     */

    public void setSeparator(char separator) {

        this.separator = separator;

    }

    private Long getExpiration(final String name, final int separatorIndex) {

        Long expiration = null;

        String expirationAsString = name.substring(separatorIndex + 1);

        try {

            // calculate expiration, support arithmetic expressions.

            if(pattern.matcher(expirationAsString).find()){

                expiration = (long) Double.parseDouble(scriptEngine.eval(expirationAsString).toString());

            }else{

                expiration = Long.parseLong(expirationAsString);

            }

        } catch (NumberFormatException ex) {

            logger.error(String.format("Cannnot separate expiration time from cache: '%s'", name), ex);

        } catch (ScriptException e) {

            logger.error(String.format("Cannnot separate expiration time from cache: '%s'", name), e);

        }

        return expiration;

    }

    @Override

    public void setUsePrefix(boolean usePrefix) {

        super.setUsePrefix(usePrefix);

    }

    @Override

    public void setCachePrefix(RedisCachePrefix cachePrefix) {

        super.setCachePrefix(cachePrefix);

    }

    public void setDefaultCacheName(String defaultCacheName) {

        this.defaultCacheName = defaultCacheName;

    }

}

注意:在引入相关jar包的时候,必须要用jedis_2.9.0.jar、spring-data-redis-1.6.0.RELEASE.jar,因为这些jar包的版本对整个项目影响很大的;

可以参考代码来源:https://my.oschina.net/wnjustdoit/blog/644311
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: