看过我第一篇介绍spring boot redis的文章的同行们可能发现了一个问题,那就是redis中的value并没有设置过期时间,之前我也是为这个苦恼了半天,发现现成的注解并没有提供过期时间的相关入口,后来经过各种搜索终于找到了解决方法,本篇我们就来介绍如何设置过期时间。
过期时间的设置目前我找到了两个方法:1.通过redis管理器集中配置不同区域下的过期时间;2.通过扩展redis管理器来进行额外传参的方式进行设置,好了废话不多说直接上代码。
1.通过redis管理器集中配置不同区域下的过期时间
2.通过扩展redis管理器来进行额外传参的方式进行设置
2.1编写redis管理器(RedisCacheManager)的扩展类并继承RedisCacheManager,具体代码如下
package com.zxl.examples.catche;
import org.springframework.cache.Cache;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.core.RedisOperations;
/**
* Created by Administrator on 2017/7/25.
*/
public class RedisCacheManagerExtend extends RedisCacheManager {
public RedisCacheManagerExtend(RedisOperations redisOperations) {
super(redisOperations);
}
/**
* 缓存参数的分隔符
* 数组元素0=缓存的名称
* 数组元素1=缓存过期时间TTL
* 数组元素2=缓存在多少秒开始主动失效来强制刷新
*/
private String separator = "#";
/**
* 缓存主动在失效前强制刷新缓存的时间
* 单位:秒
*/
private long preloadSecondTime=0;
@Override
public Cache getCache(String name) {
String[] cacheParams=name.split(this.getSeparator());
String cacheName = cacheParams[0];
if(cacheName==null || "".equals(cacheName.trim())){
return null;
}
Long expirationSecondTime = this.computeExpiration(cacheName);
if(cacheParams.length>1) {
expirationSecondTime=Long.parseLong(cacheParams[1]);
this.setDefaultExpiration(expirationSecondTime);
}
if(cacheParams.length>2) {
this.setPreloadSecondTime(Long.parseLong(cacheParams[2]));
}
Cache cache = super.getCache(cacheName);
if(null==cache){
return null;
}
return cache;
// logger.info("expirationSecondTime:"+expirationSecondTime);
// CustomizedRedisCache redisCache= new CustomizedRedisCache(
// cacheName,
// (this.isUsePrefix() ? this.getCachePrefix().prefix(cacheName) : null),
// this.getRedisOperations(),
// expirationSecondTime,
// preloadSecondTime);
// return redisCache;
}
public String getSeparator() {
return separator;
}
public void setSeparator(String separator) {
this.separator = separator;
}
public long getPreloadSecondTime() {
return preloadSecondTime;
}
public void setPreloadSecondTime(long preloadSecondTime) {
this.preloadSecondTime = preloadSecondTime;
}
}
2.2 将redis配置类中的redis管理器生成模式改为new此扩展类,如下图:
2.3 使用的时候在注解传按照以#分隔模式传参,如下图:
就是如此简单,以上两种方式皆可设置redis的过期时间,稍后将贴出整个完整的代码,之前的一章层介绍过@Caching注解的用法,此注解中可传入多个参数使得程序看上去比较复杂,如下图:
对于此种情况我们可以自定义封装成各种业务模式的注解,使得看起来比较轻便,如下图:
以上所有介绍的完整代码如下:
package com.zxl.examples.catche.customannotation;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Caching;
import java.lang.annotation.*;
/**
* Created by Administrator on 2017/7/26.
*/
@Caching(
put={
@CachePut(value = "userCache", key = "'user:'+#user.id"),
@CachePut(value = "userCache", key = "'user:'+#user.username")
}
)
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface UserSaveCache {
}
package com.zxl.examples.service;
import com.zxl.examples.catche.customannotation.UserSaveCache;
import com.zxl.examples.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* Created by Administrator on 2017/7/24.
*/
@Service("userSerivce")
public class UserSerivceImpl {
@Autowired
UserRepository userRepository;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Autowired
private RedisTemplate redisTemplate;
@Transactional
public void addMoreUsers(){
User user1 = new User();
user1.setUsername("123");
user1.setName("123");
user1.setPassword("123");
userRepository.save(user1);
User user2 = new User();
user2.setUsername("234");
user2.setName("123");
user2.setPassword("123");
userRepository.save(user2);
}
public void addMoreList(){
List
userList = new ArrayList
();
User user1 = new User();
user1.setUsername("345");
user1.setName("123");
user1.setPassword("123");
userList.add(user1);
User user2 = new User();
user2.setUsername("456");
user2.setName("123");
user2.setPassword("123");
userList.add(user2);
userRepository.save(userList);
}
//unless-->用于否决缓存更新的,不像condition,该表达只在方法执行之后判断,此时可以拿到返回值result进行判断了
@Cacheable(value="userCache",key="'user:'+#username",unless = "#result==null")
public User getUserByUsername(String username){
User user = null;
List
userlist = userRepository.findByUsername(username);
if(userlist!=null && userlist.size()>0){
user = userlist.get(0);
}
return user;
}
// @Cacheable(value="userCache#120",key="'user:'+#username",unless = "#result==null")
// public User getUserByUsername(String username){
// User user = null;
// List
userlist = userRepository.findByUsername(username);
// if(userlist!=null && userlist.size()>0){
// user = userlist.get(0);
// }
// return user;
// }
//allEntries-->是否移除所有数据
//beforeInvocation-->是调用方法之前移除/还是调用之后移除
@CacheEvict(value = "userCache",key="'user:'+#user.username")
public void delUserById(User user){
userRepository.delete(user);
}
public String setUserInRedis(){
stringRedisTemplate.opsForValue().set("abc","123",60L, TimeUnit.SECONDS);
return stringRedisTemplate.opsForValue().get("abc");
// redisTemplate.opsForList();//可直接放入实现序列化的pojo
}
public void delUserInRedis(){
stringRedisTemplate.delete("abc");
}
//condition-->满足缓存条件的数据才会放入缓存,condition在调用方法之前和之后都会判断
@CachePut(value="userCache",key = "#user.username",condition = "#user.username<='100'")
public User save(User user){
userRepository.save(user);
return user;
}
@Caching(
put={
@CachePut(value = "userCache", key = "'user:'+#user.id"),
@CachePut(value = "userCache", key = "'user:'+#user.username")
}
)
public User addUser(User user){
userRepository.save(user);
return user;
}
@UserSaveCache
public User addUser2(User user){
userRepository.save(user);
return user;
}
@Cacheable(value="userCache",key="'user:'+#username",condition = "#root.target.canCache()",unless = "#result==null")
public User getUserByUsername2(String username){
User user = null;
List
userlist = userRepository.findByUsername(username); if(userlist!=null && userlist.size()>0){ user = userlist.get(0); } return user; } @Cacheable(value="userCache",key="'user:'+#username",condition = "#root.target.notCache()") public User getUserByUsername3(String username){ User user = null; List
userlist = userRepository.findByUsername(username); if(userlist!=null && userlist.size()>0){ user = userlist.get(0); } return user; } public boolean canCache(){ return true; } public boolean notCache(){ return false; } }