本篇文章给大家分享的是有关springboot中怎么整合redis实现分布式锁,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。
总结:springboot整合redis简单而言是比较简单的,导包(导入redis pom文件), 在配置文件里面写redis的基本配置, 自定义一个redisTemplate(模板), 自己写一个工具类
其中注意的就是需要自己导入一个fastJson pom文件,为了方便对象的序列化的操作
第一:导入pom文件
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--fastJson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.56</version>
</dependency>
第二步:在配置文件中配置redis中的属性
redis:
database: 0
host: localhost
port: 6379
password:
pool:
max-active: 200
max-wait: -1 #连接池最大阻塞时间,负值表示没有限制
max-idle: 10
min-idle: 0 #最小空闲数
timeout: 1000
第三步:自定义模板类
/**
* 自定义一个redis模板并且实现序列化
* @param factory
* @return
*/
@Bean
@SuppressWarnings("all") //作用告诉编辑器不要在编译完成后出现警告信息
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory){
//引入原来的redisTemplate来实现注入
RedisTemplate<String, Object> template = new RedisTemplate<>();
//将工厂注入进stringTemplate中
template.setConnectionFactory(factory);
//采用了jackSon序列化对象
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
//对String进行序列化
StringRedisSerializer stringRedisTemplate = new StringRedisSerializer();
template.setKeySerializer(stringRedisTemplate);
template.setHashKeySerializer(stringRedisTemplate);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashKeySerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
第四步:自己编写一个工具类
@Component
public class RedisUtil {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 给指定的key指定失效时间
* @param key
* @param time
* @return
*/
public boolean expire(String key, long time){
try{
if (time > 0){
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
}catch (Exception e){
e.printStackTrace();
return false;
}
}
/**
* 获取到指定的key失效时间
* @param key
* @return
*/
public long getExpire(String key){
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* 判断是否key存在
* @param key
* @return
*/
public boolean hasKey(String key){
return redisTemplate.hasKey(key);
}
/**
* 删除多个key
* @param key
*/
public void delete(String... key){
//对key值进行判断
if (key != null && key.length > 0){
if (key.length == 1){
redisTemplate.delete(key[0]);
}else{
redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
}
}
}
/**
* 获取到key值对应的值大小
* @param key
* @return
*/
public Object get(String key){
return key==null ? null : redisTemplate.opsForValue().get(key);
}
/**
* 存放key,value值
* @param key
* @param value
* @return
*/
public void set(String key, Object value){
redisTemplate.opsForValue().set(key, value);
}
/**
* 对key 存放一个有效值
* @param key
* @param value
* @param time
*/
public void set(String key, Object value, long time){
if (time > 0){
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
}else{
redisTemplate.opsForValue().set(key, value);
}
}
/**
* 对key递增dalta因素
* @param key
* @param dalta
* @return
*/
public long incr(String key, long dalta ){
if (dalta < 0){
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, dalta);
}
/**
* 对key进行递减多少个元素
* @param key
* @param delta
* @return
*/
public long decr(String key, long delta){
if (delta < 0){
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().decrement(key, delta);
}
/**
* hash取值
* @param key
* @param item
* @return
*/
public Object hget(String key, String item){
return redisTemplate.opsForHash().get(key, item);
}
/**
* 获取key下面的所有值
* @param key
* @return
*/
public Map<Object, Object> hmget(String key){
return redisTemplate.opsForHash().entries(key);
}
/**
* 将对象存储进hash中去
* @param key
* @param map
*/
public void hmset(String key, Map<String, Object> map){
redisTemplate.opsForHash().putAll(key, map);
}
/**
* 对其中的key进行设置时效时间
* @param key
* @param map
* @param time
*/
public void hmset(String key, Map<String, Object> map, long time){
redisTemplate.opsForHash().putAll(key, map);
if (time > 0){
expire(key, time);
}
}
/**
* 往一张表中注入一调数据
* @param key
* @param item
* @param value
*/
public void hset(String key, String item, Object value){
redisTemplate.opsForHash().put(key, item, value);
}
/**
* 对key设置一个过期时间
* @param key
* @param item
* @param value
* @param time
*/
public void hset(String key, String item, Object value, long time){
redisTemplate.opsForHash().put(key, item,value);
if (time > 0){
expire(key, time);
}
}
/**
* 删除hash中的值
* @param key
* @param item
*/
public void hdel(String key, Object... item){
redisTemplate.opsForHash().delete(key, item);
}
/**
* 判断hash表中是否存在
* @param key
* @param item
*/
public void hHashKey(String key, String item){
redisTemplate.opsForHash().hasKey(key, item);
}
/**
* 给存在的可以一个值,并存在则会创建并且给它增加值
* @param key
* @param item
* @param by
*/
public void hincr(String key, String item, double by){
redisTemplate.opsForHash().increment(key, item, by);
}
/**
* 给存在的key减少一个值
* @param key
* @param item
* @param by
*/
public void hdecr(String key, String item, double by){
redisTemplate.opsForHash().increment(key, item, -by);
}
/**
* 从set中获取值
* @param key
* @return
*/
public Set<Object> sGet(String key){
return redisTemplate.opsForSet().members(key);
}
// List
/**
* 从list中取值
* @param key
* @param start
* @param end
* @return
*/
public List<Object> lGet(String key, long start, long end){
return redisTemplate.opsForList().range(key, start, end);
}
/**
* 获取到list的长度
* @param key
* @return
*/
public long lGetLilstSize(String key){
return redisTemplate.opsForList().size(key);
}
/**
* 通过索引 获取list中的值
* @param key 键
* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
* @return
*/
public Object lGetIndex(String key, long index){
return redisTemplate.opsForList().index(key, index);
}
/**
* list中数据存放进缓存
* @param key
* @param value
*/
public void lSet(String key, Object value){
redisTemplate.opsForList().rightPush(key,value);
}
/**
* 对list中的key设置失效时间
* @param key
* @param value
* @param time
*/
public void lSet(String key, Object value, long time){
redisTemplate.opsForList().rightPush(key, value);
if (time > 0){
expire(key, time);
}
}
/**
* 将一整个List集合存进缓存
* @param key
* @param value
*/
public void lSet(String key, List<Object> value){
redisTemplate.opsForList().rightPushAll(key, value);
}
/**
* 对key值设置一个失效时间
* @param key
* @param value
* @param time
*/
public void lSet(String key, List<Object> value, long time){
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0){
expire(key, time);
}
}
/**
* 将一个value值存进到对应的index中去
* @param key
* @param index
* @param value
*/
public void lUpdateIndex(String key, long index, Object value){
redisTemplate.opsForList().set(key, index, value);
}
/**
* 删除对应的index位置的值
* @param key
* @param count
* @param value
* @return
*/
public void lRemove(String key, long count, Object value){
redisTemplate.opsForList().remove(key, count, value);
}
}
Redssion 实现分布式锁的流程主要是五个步骤
导入pom文件, 编写一个获取分布式锁接口, 定义一个分布式锁的管理接口, 定义一个类用来实现刚才定义分布式接口管理, 定义一个没有获取到分布式锁的异常
这部分代码是上面springboot整合redis基础实现的,导入的pom文件:
<!--redSesion-->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.7.0</version>
</dependency>
第二步:定义获取锁后
public interface AquiredLockWorker<T> {
/**
* 获取锁之后处理具体业务逻辑的方法
* @return
* @throws Exception
*/
T invokeAfterLockAquire() throws Exception;
第三步:分布式管理接口
public interface DistributedLocker {
/**
* 获取锁时需要填写的参数
* @param resourceName
* @param worker
* @param <T>
* @return
* @throws Exception
*/
<T> T lock(String resourceName, AquiredLockWorker<T> worker) throws Exception;
/**
* 获取锁时候的需要填写参数,同时设置了锁的有效期
* @param <T>
* @param resourceName
* @param worker
* @param time
* @throws Exception
*/
<T> T lock(String resourceName, AquiredLockWorker<T> worker, long time) throws Exception;
第四步:定义一个类—实现分布式接口的类
@Component
public class RedisLock implements DistributedLocker {
private final static String name = "redisLock";
@Autowired
private RedissonConnector redissonConnector;
@Override
public <T> T lock(String resourceName, AquiredLockWorker<T> worker) throws Exception {
return lock(resourceName, worker, 100);
}
@Override
public <T> T lock(String resourceName, AquiredLockWorker<T> worker, long time) throws Exception {
RedissonClient redissonClient = redissonConnector.getRedissonClient();
RLock lock = redissonClient.getLock(name + resourceName);
//等待100秒释放锁
boolean flag = lock.tryLock(100, time, TimeUnit.SECONDS);
if(flag){
//代码必须这样设计
try{
//拿取到锁之后执行的业务的方法
return worker.invokeAfterLockAquire();
}finally {
lock.unlock();
}
}
//没有拿取到锁时,会报没有拿取锁异常
throw new UnsupportedOperationException();
}
第五步:定义异常类
public class UnableToAquireLockException extends RuntimeException {
/**
* 定义一个无参构造
*/
public UnableToAquireLockException(){};
/**
* 打印出错误的信息
* @param message
*/
public UnableToAquireLockException(String message){
super(message);
}
/**
* 打印错误信息与异常类型
* @param message
* @param cause
*/
public UnableToAquireLockException(String message, Throwable cause){
super(message, cause);
}
调用下:
@RestController
public class RedisController {
@Autowired
private DistributedLocker distributedLocker;
@RequestMapping(value = "index")
public String index() throws Exception {
distributedLocker.lock("test", new AquiredLockWorker<Object>(){
@Override
public Object invokeAfterLockAquire() throws Exception {
System.out.println("这里直接进行逻辑处理");
Thread.sleep(100);
return null;
}
});
return "hello redis";
}
以上就是springboot中怎么整合redis实现分布式锁,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。