【Spring】SSM框架配置Redis進行快取
阿新 • • 發佈:2018-12-08
此過程是在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中是否有快取,如果有,則直接取出資料,進行返回