1、pom依赖
org.springframework.boot
spring-boot-starter-data-redis
org.redisson
redisson-spring-boot-starter
3.10.2
org.redisson
redisson-spring-data-20
3.10.2
2、yml配置
spring:
cache:
type: redis
redis:
# redis库
database: 0
# #方式一: 集群
# cluster:
# nodes: 192.168.56.99:6379,192.168.59.100:6379
#方式二: 单机 二选一
port: 6379
host: 127.0.0.1
# redis 密码
password:
# 连接超时时间(毫秒)
timeout: 1000
jedis:
pool:
# 连接池最大链接数(负数表示没有限制)
max-active: 8
# 连接池最大阻塞等待时间(负数表示没有限制)
max-wait: 3000
# 连接池最大空闲连接数
max-idle: 8
# 连接池最小空闲连接数
min-idle: 0
3、config配置
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.cache.Cache;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import javax.annotation.Resource;
import java.time.Duration;
@Configuration
@EnableCaching
@Slf4j
@AllArgsConstructor
public class RedisConfig extends CachingConfigurerSupport {
@Resource
private final RedisProperties redisProperties;
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
// redisCacheManager构造器需要提供一个redisCacheWriter和一个redisCacheConfigurer
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);
// 配置cache 序列化为jsonSerializer
RedisSerializer
4、redis锁工具类
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@Component
public class RedissonUtil {
private static final Logger logger = LoggerFactory.getLogger(RedissonUtil.class);
public static final String SYS_LOCK_FLAG = "lock";
public static final String KEY_SPLIT = ":";
// 静态属性注入
private static RedissonClient redissonClient;
@Autowired
public void setRedisson(RedissonClient redissonClient) {
RedissonUtil.redissonClient = redissonClient;
}
public static boolean getLock(String lockName, long expiresTime,long waitTime) {
//最长等待时间
String key = getLockKey(lockName);
//获取锁对象
RLock lock = redissonClient.getLock(key);
//设置锁过期时间,防止死锁的产生
boolean flag = true;
try {
flag = lock.tryLock(waitTime,expiresTime, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
logger.info("获取锁成功,Redis Lock key: {}", key);
return flag;
}
public static void unlock(String lockName) {
String key = getLockKey(lockName);
//获取所对象
RLock lock = redissonClient.getLock(key);
// 释放锁,判断要解锁的key是否已被锁定并且是否被当前线程保持
if (lock.isLocked() && lock.isHeldByCurrentThread()) {
lock.unlock();
logger.info("释放Redis锁成功,key:{}", key);
}
}
private static String getLockKey(String key) {
return RedissonUtil.SYS_LOCK_FLAG + RedissonUtil.KEY_SPLIT + key;
}
}
5、缓存及锁示例
@Service
public class UserDemoService {
@Cacheable(cacheNames = "users",key = "#userName")
public UserDemo getByUserName(String userName){
UserDemo userDemo = new UserDemo();
userDemo.setUserName("zhangsan");
userDemo.setPwd("123456");
System.out.println("getByUserName:"+userDemo.toString());
return userDemo;
}
@CachePut(cacheNames = "users",key = "#userName")
public UserDemo updateUser(String userName, String pwd){
UserDemo userDemo = new UserDemo();
userDemo.setUserName(userName);
userDemo.setPwd(pwd);
System.out.println("updateUser:"+userDemo.toString());
return userDemo;
}
@CacheEvict(cacheNames = "users",key = "#userName")
public void delUser(String userName) {
System.out.println("delUser:"+userName);
}
@Cacheable(cacheNames = "users", key = "'allUsers'", unless = "#result==null")
public List allUsers() {
System.out.println("allUsers:");
List list = new ArrayList<>();
return list;
}
public void test(){
System.out.println("========开始=====");
if(RedissonUtil.getLock("mylock",5L,3L)){
try {
Thread.sleep(1000*5);
} catch (InterruptedException e) {
e.printStackTrace();
}
RedissonUtil.unlock("mylock");
System.out.println("解锁:"+System.currentTimeMillis());
}else {
System.out.println("未获得锁:"+System.currentTimeMillis());
}
}
}