springboot項目配置redis
application.yml文件redis配置
redis:
# 本地
# 數據庫(默認0)
database: 1
host: 127.0.0.1
port: 6379
password: XXX
pool:
max-active: 8
max-wait: -1
max-idle: 20
min-idle: 0
timeout: 30000
springboot項目maven配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.67</version>
</dependency>
redis配置
@Configuration
@EnableCaching //開啓註解式緩存
//繼承CachingConfigurerSupport,爲了自定義生成KEY的策略。可以不繼承。
public class RedisConfig extends CachingConfigurerSupport {
/**
* @Description: 生成key的策略 根據類名+方法名+所有參數的值生成唯一的一個key
* @Author: Mr.Jkx
* @date: 2020/3/24 13:16
*/
@Bean
@Override
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
/**
* @Description: 管理緩存
* @Author: Mr.Jkx
* @date: 2020/3/24 13:17
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
//通過Spring提供的RedisCacheConfiguration類,構造一個自己的redis配置類,從該配置類中可以設置一些初始化的緩存命名空間
// 及對應的默認過期時間等屬性,再利用RedisCacheManager中的builder.build()的方式生成cacheManager:
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig(); // 生成一個默認配置,通過config對象即可對緩存進行自定義配置
config = config.entryTtl(Duration.ofMinutes(1)) // 設置緩存的默認過期時間,也是使用Duration設置
.disableCachingNullValues(); // 不緩存空值
// 設置一個初始化的緩存空間set集合
Set<String> cacheNames = new HashSet<>();
cacheNames.add("my-redis-cache1");
cacheNames.add("my-redis-cache2");
// 對每個緩存空間應用不同的配置
Map<String, RedisCacheConfiguration> configMap = new HashMap<>();
configMap.put("my-redis-cache1", config);
configMap.put("my-redis-cache2", config.entryTtl(Duration.ofSeconds(120)));
RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory) // 使用自定義的緩存配置初始化一個cacheManager
.initialCacheNames(cacheNames) // 注意這兩句的調用順序,一定要先調用該方法設置初始化的緩存名,再初始化相關的配置
.withInitialCacheConfigurations(configMap)
.build();
return cacheManager;
}
/**
* @Description: 自定義序列化方式(使用alibaba >>> FastJsonRedisSerializer)
* @Author: Mr.Jkx
* @date: 2020/4/16 18:03
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
// 全局開啓AutoType
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
// 設置值(value)的序列化採用FastJsonRedisSerializer。
redisTemplate.setValueSerializer(fastJsonRedisSerializer);
redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);
// 設置鍵(key)的序列化採用StringRedisSerializer。
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
stringRedisTemplate.setConnectionFactory(factory);
return stringRedisTemplate;
}
}
redis數據過期事件處理
/**
* @program: youpin
* @description: redis過期事件的監聽類
* @author: Mr.Jkx
* @create: 2020-04-16 18:52
*/
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
private static final Logger LOGGER = (Logger) LoggerFactory.getLogger(RedisKeyExpirationListener.class);
public RedisKeyExpirationListener(RedisMessageListenerContainer container) {
super(container);
}
/**
* @Description: 針對redis數據失效事件,進行數據處理
* <p>
* 此處獲取的信息均爲未支付的過期訂單,支付過的訂單在支付回調中已經刪除了
* @Author: Mr.Jkx
* @date: 2020/4/16 18:58
*/
@Override
public void onMessage(Message message, byte[] pattern) {
//生效的key
String key = message.toString();
LOGGER.info("----redis listener get data key:{}----", key);
//從失效key中篩選代表訂單失效的key(startsWith:檢測字符串是否以指定的前綴開始)
if (key != null && key.startsWith("redis_")) {
//截取訂單主鍵id,查詢訂單
String orderId = key.substring(8);
// 根據主鍵id查詢數據進行業務邏輯處理 TODO
}
}
}
redis監聽信息配置
/**
* @program: youpin
* @description: redis 監聽配置
* @author: Mr.Jkx
* @create: 2020-04-16 18:37
*/
@Configuration
public class RedisListenerConfig {
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
//可以添加多個 messageListener,訂閱了一個叫“redisListener”的通道
container.addMessageListener(listenerAdapter, new PatternTopic("redisListener"));
return container;
}
/**
* 消息監聽器適配器,綁定消息處理器,利用反射技術調用消息處理器的業務方法
*
* @param redisReceiver
* @return
*/
@Bean
MessageListenerAdapter listenerAdapter(RedisReceiver redisReceiver) {
// 這個地方 是給messageListenerAdapter 傳入一個消息接受的處理器,利用反射的方法調用“receiveMessage”
// 也有好幾個重載方法,這邊默認調用處理器的方法 叫handleMessage 可以自己到源碼裏面看
return new MessageListenerAdapter(redisReceiver, "receiveMessage");
}
//使用默認的工廠初始化redis操作模板
@Bean
StringRedisTemplate template(RedisConnectionFactory connectionFactory) {
return new StringRedisTemplate(connectionFactory);
}
}
redis監聽消息處理
/**
* @program: youpin
* @description: 消息接收(消費)
* @author: Mr.Jkx
* @create: 2020-04-17 16:57
*/
@Component
public class RedisReceiver {
private static final Logger LOGGER = LoggerFactory.getLogger(RedisReceiver.class);
/**
* @Description: 消息消費
* @Author: Mr.Jkx
* @date: 2020/4/17 17:30
* 此方法是在“RedisListenerConfig”反射調用
*/
public void receiveMessage(String message) {
LOGGER.info("消息來了:" + message);
}
}
redis數據處理工具類
/**
* @program: youpin
* @description: redis
* @author: Mr.Jkx
* @create: 2020-03-24 13:13
*/
@Service
public class RedisService {
@Autowired
private RedisTemplate redisTemplate;
/**
* 寫入緩存
*
* @param key
* @param value
* @return
*/
public boolean set(final String key, Object value) {
boolean result = false;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 寫入緩存設置時效時間
*
* @param key
* @param value
* @return
*/
public boolean set(final String key, Object value, Long expireTime) {
boolean result = false;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 批量刪除對應的value
*
* @param keys
*/
public void remove(final String... keys) {
for (String key : keys) {
remove(key);
}
}
/**
* 批量刪除key
*
* @param pattern
*/
public void removePattern(final String pattern) {
Set<Serializable> keys = redisTemplate.keys(pattern);
if (keys.size() > 0) {
redisTemplate.delete(keys);
}
}
/**
* 刪除對應的value
*
* @param key
*/
public void remove(final String key) {
if (exists(key)) {
redisTemplate.delete(key);
}
}
/**
* 判斷緩存中是否有對應的value
*
* @param key
* @return
*/
public boolean exists(final String key) {
return redisTemplate.hasKey(key);
}
/**
* 讀取緩存
*
* @param key
* @return
*/
public Object get(final String key) {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
return operations.get(key);
}
/**
* 哈希 添加
*
* @param key
* @param hashKey
* @param value
*/
public void hmSet(String key, Object hashKey, Object value) {
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
hash.put(key, hashKey, value);
}
/**
* 哈希獲取數據
*
* @param key
* @param hashKey
* @return
*/
public Object hmGet(String key, Object hashKey) {
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
return hash.get(key, hashKey);
}
/**
* 哈希數據刪除
*
* @param key
* @param hashKey
* @return
*/
public Long hmDel(String key, Object hashKey) {
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
return hash.delete(key, hashKey);
}
/**
* 哈希數據加減計算
*
* @param key
* @param hashKey
* @param index
* @return
*/
public Long hmcompute(String key, Object hashKey, long index) {
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
return hash.increment(key, hashKey, index);
}
/**
* 列表添加
*
* @param k
* @param v
*/
public void rPush(String k, Object v) {
ListOperations<String, Object> list = redisTemplate.opsForList();
list.rightPush(k, v);
}
/**
* 獲取最左側的列表數據
*
* @param k
* @param timeout
* @param unit
* @return
*/
public Object leftPop(String k, long timeout, TimeUnit unit) {
ListOperations<String, Object> list = redisTemplate.opsForList();
return list.leftPop(k, timeout, unit);
}
/**
* 列表獲取
*
* @param k
* @param l
* @param l1
* @return
*/
public List<Object> lRange(String k, long l, long l1) {
ListOperations<String, Object> list = redisTemplate.opsForList();
return list.range(k, l, l1);
}
/**
* 集合添加
*
* @param key
* @param value
*/
public void add(String key, Object value) {
SetOperations<String, Object> set = redisTemplate.opsForSet();
set.add(key, value);
}
/**
* 集合獲取
*
* @param key
* @return
*/
public Set<Object> setMembers(String key) {
SetOperations<String, Object> set = redisTemplate.opsForSet();
return set.members(key);
}
/**
* 有序集合添加
*
* @param key
* @param value
* @param scoure
*/
public void zAdd(String key, Object value, double scoure) {
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
zset.add(key, value, scoure);
}
/**
* 有序集合獲取
*
* @param key
* @param scoure
* @param scoure1
* @return
*/
public Set<Object> rangeByScore(String key, double scoure, double scoure1) {
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
return zset.rangeByScore(key, scoure, scoure1);
}
/**
* @Description: redis 消息訂閱發佈,向通道發送消息的方法
* @Author: Mr.Jkx
* @date: 2020/4/17 17:09
*/
public void sendChannelMess(String channel, Object message) {
redisTemplate.convertAndSend(channel, message);
}
}