package com.sunreal.distribute.util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.data.redis.core.types.Expiration;
import java.util.Arrays;
import java.util.UUID;
@Slf4j
public class RedisLock {
private static final RedisTemplate redisTemplate = SpringContext.getBean(StringRedisTemplate.class);
private String key;
private String value;
private int expireTime;
public RedisLock(String key, int expireTime) {
this.key = key;
this.value = UUID.randomUUID().toString();
this.expireTime = expireTime;
}
public Boolean getLock() {
RedisCallback<Boolean> redisCallback = redisConnection -> {
RedisStringCommands.SetOption setOption = RedisStringCommands.SetOption.ifAbsent();
Expiration expiration = Expiration.seconds(this.expireTime);
byte[] redisKey = redisTemplate.getKeySerializer().serialize(this.key);
byte[] redisValue = redisTemplate.getValueSerializer().serialize(this.value);
return redisConnection.set(redisKey, redisValue, expiration, setOption);
};
Boolean result = (Boolean) redisTemplate.execute(redisCallback);
log.info("Redis加锁的结果: [{}]", result);
return result;
}
public Boolean unLock() {
StringBuilder script = new StringBuilder(32);
script.append("if redis.call(\"get\", KEYS[1]) == ARGV[1] then ")
.append(" return redis.call(\"del\", KEYS[1]) ")
.append("else")
.append(" return 0 ")
.append("end");
RedisScript<Boolean> redisScript = RedisScript.of(script.toString(), Boolean.class);
Boolean result = (Boolean) redisTemplate.execute(redisScript, Arrays.asList(key), value);
log.info("Redis释放锁的结果: [{}]", result);
return result;
}
}
```java
package com.sunreal.core.redis;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.redisson.Redisson;
import org.redisson.config.Config;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
@Bean
@SuppressWarnings(value = {
"unchecked", "rawtypes"})
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(
LaissezFaireSubTypeValidator.instance,
ObjectMapper.DefaultTyping.NON_FINAL,
JsonTypeInfo.As.PROPERTY);
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
mapper.registerModule(new JavaTimeModule());
serializer.setObjectMapper(mapper);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(serializer);
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(serializer);
redisTemplate.setDefaultSerializer(serializer);
return redisTemplate;
}
@Bean
public Redisson redisson() {
Config config = new Config();
config.useSingleServer()
.setAddress("redis://x.x.x:6379")
.setPassword("xxx")
.setDatabase(0);
return (Redisson) Redisson.create(config);
}
}
文章评论