1. 程式人生 > >【Spring】SSM框架配置Redis進行快取

【Spring】SSM框架配置Redis進行快取

此過程是在SSM框架搭建完畢之後進行的擴充套件

首先引入redis依賴:

<!-- redis -->
<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
  <version>2.8.1</version>
  <type>jar</type>
</dependency>

準備對應的資料來源redis.properties

#redis快取配置
redis.host=127.0.0.1
redis.port=6379
redis.pass=密碼
redis.database=2
redis.timeout=3000

#redis連線池配置
redis.maxIdle=300
redis.maxActive=600
redis.maxWait=1000
redis.testOnBorrow=true
redis.connectionTimeout=5000

使用redis.xml載入資料來源

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<!--載入redis.properties-->
    <context:property-placeholder location="classpath:redis.properties" />

    <!--配置redis資料來源-->
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig" >
        <property name="maxIdle" value="${redis.maxIdle}" />
        <property name="maxTotal" value="${redis.maxActive}" />
        <property name="testOnBorrow" value="${redis.testOnBorrow}" />
    </bean>

    <!--配置ShardJedisPool-->
    <bean id="shardedJedisPool" class="redis.clients.jedis.ShardedJedisPool" scope="singleton">
        <constructor-arg index="0" ref="jedisPoolConfig" />
        <constructor-arg index="1">
            <list>
                <bean class="redis.clients.jedis.JedisShardInfo">
                    <constructor-arg name="host" value="${redis.host}" />
                    <constructor-arg name="port" value="${redis.port}"/>
                    <constructor-arg name="timeout" value="${redis.timeout}"/>
                    <property name="password" value="${redis.pass}" />
                    <property name="connectionTimeout" value="${redis.connectionTimeout}"/>
                </bean>
            </list>
        </constructor-arg>
    </bean>

</beans>

在applicationContext.xml中引入redis.xml

<!--引入redis.xml-->
<import resource="redis.xml" />

在service層配置ShardedJedisPool連線池

@Service("redisPool")
@Slf4j
public class RedisPool {
    @Resource(name = "shardedJedisPool")
    private ShardedJedisPool shardedJedisPool;

    /**
     * 建立例項
     * @return
     */
    public ShardedJedis instance(){
        return shardedJedisPool.getResource();
    }

    /**
     * 安全關閉
     * @param shardedJedis
     */
    public void safeClose(ShardedJedis shardedJedis){
        try {
            if (shardedJedis != null){
                shardedJedis.close();
            }
        }catch (Exception e){
            log.error("return redis resource exception",e);
        }
    }

}

編寫進行快取、獲取快取、生成快取key的方法

/**
 * @author evan_qb
 * @date 2018/9/11
 */
@Service
@Slf4j
public class SysCacheService {
    @Resource(name = "redisPool")
    private RedisPool redisPool;

    /**
     * 呼叫快取
     * @param toSaveValue
     * @param timeoutSeconds
     * @param prefix
     */
    public void saveCache(String toSaveValue, int timeoutSeconds, CacheKeyConstants prefix){
        saveCache(toSaveValue,timeoutSeconds,prefix,null);
    }

    /**
     * 進行快取
     * @param toSaveValue
     * @param timeoutSeconds
     * @param prefix
     * @param keys
     */
    public void saveCache(String toSaveValue, int timeoutSeconds, CacheKeyConstants prefix,String... keys){
        if (toSaveValue == null){
            return;
        }
        ShardedJedis shardedJedis = null;
        try {
            String cacheKey = generateCacheKey(prefix,keys);
            shardedJedis = redisPool.instance();
            shardedJedis.setex(cacheKey,timeoutSeconds,toSaveValue);
        }catch (Exception e){
            log.error("save cache exception,prefix:{},keys:{}",prefix.name(),JsonMapper.object2String(keys),e);
        }finally {
            redisPool.safeClose(shardedJedis);
        }
    }

    /**
     * 獲取快取
     * @param prefix
     * @param keys
     * @return
     */
    public String getFromCache(CacheKeyConstants prefix,String... keys){
        ShardedJedis shardedJedis = null;
        String cacheKey = generateCacheKey(prefix,keys);
        try {
            shardedJedis = redisPool.instance();
            String value = shardedJedis.get(cacheKey);
            return value;
        }catch (Exception e){
            log.error("get from cache exception,prefix:{},keys:{}",prefix.name(),JsonMapper.object2String(keys),e);
            return null;
        }finally {
            redisPool.safeClose(shardedJedis);
        }
    }


    /**
     * 生成快取的key
     * @param prefix
     * @param keys
     * @return
     */
    private String generateCacheKey(CacheKeyConstants prefix,String... keys){
        String key = prefix.name();
        if (keys != null && keys.length > 0){
            key += "_" + Joiner.on("_").join(keys);
        }
        return key;
    }
}

定義快取常用的key常量字首

/**
 * @author evan_qb
 * @date 2018/9/11
 * 快取常量
 */
@Getter
public enum  CacheKeyConstants {
    SYSTEM_ACLS,
    USER_ACLS
}

對快取場景進行分析,找出需要快取的資料

編寫程式碼將其進行快取

/**
 * 對當前使用者對應的許可權列表進行快取
 * @return
 */
public List<SysAcl> getCurrentUserAclListFromCache(){
    int userId = RequestHolder.getCurrentUser().getId();
    String cacheValue = sysCacheService.getFromCache(CacheKeyConstants.USER_ACLS,String.valueOf(userId));
    if (StringUtils.isBlank(cacheValue)){
        List<SysAcl> aclList = getCurrentuserAclList();
        if (CollectionUtils.isNotEmpty(aclList)){
            sysCacheService.saveCache(JsonMapper.object2String(aclList),600,
                    CacheKeyConstants.USER_ACLS,String.valueOf(userId));
        }
        return aclList;
    }
    return JsonMapper.string2Object(cacheValue, new TypeReference<List<SysAcl>>() {});
}

呼叫快取的方法

接下來進行測試:

第一次進入發現redis中沒有快取,先對其進行快取,然後將結果返回

第二次進入方法,先查詢redis中是否有快取,如果有,則直接取出資料,進行返回