SpringBoot配置Redis自定義過期時(shí)間操作
SpringBoot配置Redis自定義過期時(shí)間
Redis配置依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
<version>1.4.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.8.1.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
SpringBoot-Reids配置文件
package com.regs.tms.common.redis;
@Configuration
@EnableCaching// 啟用緩存,這個(gè)注解很重要
@ConfigurationProperties(prefix = "spring.redis")
@Data
public class RedisCacheConfig extends CachingConfigurerSupport {
private String host;
private Integer port;
private Integer database;
private String password;
@Bean("redisTemplate")
public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(factory);
//使用Jackson2JsonRedisSerializer來序列化和反序列化redis的value值
Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
serializer.setObjectMapper(mapper);
template.setValueSerializer(serializer);
template.setHashValueSerializer(serializer);
// 設(shè)置鍵(key)的序列化采用StringRedisSerializer。
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
//打開事務(wù)支持
template.setEnableTransactionSupport(true);
template.afterPropertiesSet();
return template;
}
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) throws SQLException {
//配置事務(wù)管理器
return new DataSourceTransactionManager(dataSource);
}
@Bean("stringRedisTemplate")
public StringRedisTemplate stringRedisTemplate() {
Integer port = this.port == null ? 6379 : this.port;
JedisConnectionFactory jedis = new JedisConnectionFactory();
jedis.setHostName(host);
jedis.setPort(port);
if (StringUtils.isNotEmpty(password)) {
jedis.setPassword(password);
}
if (database != null) {
jedis.setDatabase(database);
} else {
jedis.setDatabase(0);
}
// 初始化連接pool
jedis.afterPropertiesSet();
// 獲取連接template
StringRedisTemplate temple = new StringRedisTemplate();
temple.setConnectionFactory(jedis);
return temple;
}
}
自定義失效注解
package com.regs.tms.common.redis.annotation;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface CacheDuration {
//Sets the expire time (in seconds).
public long duration() default 60;
}
自定義失效配置
package com.regs.tms.common.redis.annotation;
/**
* ExpireCacheManager,繼承自RedisCacheManager,
* 用于對@CacheExpire解析及有效期的設(shè)置
*/
public class RedisExpireCacheManager extends RedisCacheManager implements ApplicationContextAware, InitializingBean {
private ApplicationContext applicationContext;
public RedisExpireCacheManager(RedisTemplate redisTemplate) {
super(redisTemplate);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public void afterPropertiesSet() {
parseCacheExpire(applicationContext);
}
private void parseCacheExpire(ApplicationContext applicationContext) {
final Map<String, Long> cacheExpires = new HashMap<>(16);
//掃描有注解
String[] beanNames = applicationContext.getBeanNamesForAnnotation(Cacheable.class);
for (String beanName : beanNames) {
final Class clazz = applicationContext.getType(beanName);
addCacheExpires(clazz, cacheExpires);
}
//設(shè)置有效期
super.setExpires(cacheExpires);
}
private void addCacheExpires(final Class clazz, final Map<String, Long> cacheExpires) {
ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() {
@Override
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
ReflectionUtils.makeAccessible(method);
//根據(jù)CacheExpire注解獲取時(shí)間
CacheExpire cacheExpire = findCacheExpire(clazz, method);
if (cacheExpire != null) {
Cacheable cacheable = findAnnotation(method, Cacheable.class);
String[] cacheNames = isEmpty(cacheable.value()) ? new String[]{} : cacheable.value();
for (String cacheName : cacheNames) {
cacheExpires.put(cacheName, cacheExpire.expire());
}
}
}
}, new ReflectionUtils.MethodFilter() {
@Override
public boolean matches(Method method) {
return null != findAnnotation(method, Cacheable.class);
}
});
}
/**
* CacheExpire標(biāo)注的有效期,優(yōu)先使用方法上標(biāo)注的有效期
*
* @param clazz
* @param method
* @return
*/
private CacheExpire findCacheExpire(Class clazz, Method method) {
CacheExpire methodCache = findAnnotation(method, CacheExpire.class);
if (null != methodCache) {
return methodCache;
}
CacheExpire classCache = findAnnotation(clazz, CacheExpire.class);
if (null != classCache) {
return classCache;
}
return null;
}
}
spring boot 使用redis 超時(shí)時(shí)間重新設(shè)置
如果要計(jì)算每24小時(shí)的下單量,
通常的做法是,取出舊值,進(jìn)行加一在設(shè)置回去,
但是這樣就出現(xiàn)了一個(gè)問題
第二次設(shè)置值的時(shí)候,把超時(shí)時(shí)間重新設(shè)置成個(gè)24小時(shí)
這樣無疑的記錄24小時(shí)的數(shù)量是不準(zhǔn)確的
并且spring boot 中,默認(rèn)使用了spring 來操作redis ,使存在每個(gè)redis中的值,都會加前面加入一些東西
1) "\xac\xed\x00\x05t\x00\x0bREDISUALIST"
![]()
我們在查找每個(gè)值的時(shí)候,并不知道在key前面需要加點(diǎn)什么.
所以我們必須要用keys 這個(gè)命令 ,來匹配 我們需要查找的key,來取第一個(gè)
然后我們用 ttl 命令 返回指定key的剩余時(shí)間 ,重新設(shè)置回去,而不是設(shè)置24小時(shí),這樣就實(shí)現(xiàn)了24小時(shí)累加一次
在redisService 中,增加一個(gè)方法
/**
* 獲取指定key的剩余超時(shí)時(shí)間,key最好是唯一的,有特點(diǎn)的,最好不要匹配出多個(gè) 例子 *111 取出 "\xac\xed\x00\x05t\x00\x0b111"
* 返回剩余秒數(shù)
* @param key
* @return
* create by jcd
*/
public Long ttlByKey(@NotNull String key){
Set<byte[]> keys = redisTemplate.getConnectionFactory().getConnection().keys(key.getBytes());
byte[] bytes = keys.stream().findFirst().get();
Long ttl = redisTemplate.getConnectionFactory().getConnection().ttl(bytes);
return ttl;
}
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)于Idea使用git時(shí)commit特別慢的問題及解決方法
這篇文章主要介紹了關(guān)于Idea使用git時(shí)commit特別慢的問題及解決方法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10
SpringBoot項(xiàng)目配置數(shù)據(jù)庫密碼加密相關(guān)代碼
這篇文章主要介紹了SpringBoot項(xiàng)目配置數(shù)據(jù)庫密碼加密的相關(guān)資料,本文介紹了在Springboot項(xiàng)目中配置數(shù)據(jù)庫連接時(shí)存在的安全問題,即用戶名和密碼以明文形式存儲,容易泄露,提出了一種簡單的加密方案,需要的朋友可以參考下2024-11-11
Java?ObjectMapper的使用和使用過程中遇到的問題
在Java開發(fā)中,ObjectMapper是Jackson庫的核心類,用于將Java對象序列化為JSON字符串,或者將JSON字符串反序列化為Java對象,這篇文章主要介紹了Java?ObjectMapper的使用和使用過程中遇到的問題,需要的朋友可以參考下2024-07-07
idea導(dǎo)入springboot項(xiàng)目沒有maven的解決
這篇文章主要介紹了idea導(dǎo)入springboot項(xiàng)目沒有maven的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04
談?wù)凧ava中整數(shù)類型(short int long)的存儲方式
在java中的整數(shù)類型有四種,分別是byte short in long,本文重點(diǎn)給大家介紹java中的整數(shù)類型(short int long),由于byte只是一個(gè)字節(jié)0或1,在此就不多說了,對java中的整數(shù)類型感興趣的朋友一起學(xué)習(xí)吧2015-11-11

