Skip to content

RedisConfig keyGenerator 问题 #75

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
zhang0001 opened this issue Apr 25, 2019 · 4 comments
Closed

RedisConfig keyGenerator 问题 #75

zhang0001 opened this issue Apr 25, 2019 · 4 comments

Comments

@zhang0001
Copy link

RedisConfig keyGenerator 中target.getClass().getName() 获取到的可能是动态代理生成的类名,每次启动后可能不一致 ,造成同Class 同方法生成的key不一致。
aop:
proxy-target-class: false
的时候是相同的,如果为true ,getClass().getName()会有$$EnhancerBySpringCGLIB$$4a45e1b5 这样的类名出现。

@zhang0001
Copy link
Author

method.getDeclaringClass().getName() 可以获取定义方法的接口名,一般情况也可以适用,或者替换字符串$$EnhancerBySpringCGLIB$$4a45e1b5 中后面随机字符部分,这样处理。目前因为字典部分的缓存是不过期的,开发情况下这边的缓存会越来越多,正式环境也会有问题,如果是集群也是会无法命中缓存。

@zhangdaiscott
Copy link
Member

zhangdaiscott commented May 31, 2019

3q
默认缓存设置有效期1小时
key参考你的建议修改

@zhangdaiscott
Copy link
Member

@configuration
@EnableCaching // 开启缓存支持
public class RedisConfig extends CachingConfigurerSupport {

@Resource
private LettuceConnectionFactory lettuceConnectionFactory;

/**
 * @description 自定义的缓存key的生成策略 若想使用这个key
 *              只需要讲注解上keyGenerator的值设置为keyGenerator即可</br>
 * @return 自定义策略生成的key
 */
@Bean
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.getDeclaringClass().getName());
			Arrays.stream(params).map(Object::toString).forEach(sb::append);
			return sb.toString();
		}
	};
}

/**
 * RedisTemplate配置
 */
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
	// 设置序列化
	Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
	ObjectMapper om = new ObjectMapper();
	om.setVisibility(PropertyAccessor.ALL, Visibility.ANY);
	om.enableDefaultTyping(DefaultTyping.NON_FINAL);
	jackson2JsonRedisSerializer.setObjectMapper(om);
	// 配置redisTemplate
	RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
	redisTemplate.setConnectionFactory(lettuceConnectionFactory);
	RedisSerializer<?> stringSerializer = new StringRedisSerializer();
	redisTemplate.setKeySerializer(stringSerializer);// key序列化
	redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);// value序列化
	redisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化
	redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);// Hash value序列化
	redisTemplate.afterPropertiesSet();
	return redisTemplate;
}

/**
 * 缓存配置管理器
 */
@Bean
public CacheManager cacheManager(LettuceConnectionFactory factory) {
	// 以锁写入的方式创建RedisCacheWriter对象
	RedisCacheWriter writer = RedisCacheWriter.lockingRedisCacheWriter(factory);
	// 创建默认缓存配置对象
	RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(1)); //设置缓存默认有效期一小时;
	RedisCacheManager cacheManager = new RedisCacheManager(writer, config);
	return cacheManager;
}

}

@galaxist
Copy link

galaxist commented Jul 4, 2019

package org.jeecg.config;

import java.lang.reflect.Method;
import java.time.Duration;
import java.util.Arrays;

import javax.annotation.Resource;

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
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.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping;

import static java.util.Collections.singletonMap;

@Configuration
@EnableCaching // 开启缓存支持,这样无需在main类配置
public class RedisConfig extends CachingConfigurerSupport {

	@Resource
	private LettuceConnectionFactory lettuceConnectionFactory;

	/**
	 * @description 自定义的缓存key的生成策略 若想使用这个key
	 *              只需要讲注解上keyGenerator的值设置为keyGenerator即可</br>
	 * @return 自定义策略生成的key
	 */
	@Bean
	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.getDeclaringClass().getName());
				Arrays.stream(params).map(Object::toString).forEach(sb::append);
				return sb.toString();
			}
		};
	}

	/**
	 * RedisTemplate配置
	 */
	@Bean
	public RedisTemplate<String, Object> redisTemplate() {
		// 设置序列化
		Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
		ObjectMapper om = new ObjectMapper();
		om.setVisibility(PropertyAccessor.ALL, Visibility.ANY);
		om.enableDefaultTyping(DefaultTyping.NON_FINAL);
		jackson2JsonRedisSerializer.setObjectMapper(om);
		// 配置redisTemplate
		RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
		redisTemplate.setConnectionFactory(lettuceConnectionFactory);
		RedisSerializer<?> stringSerializer = new StringRedisSerializer();
		redisTemplate.setKeySerializer(stringSerializer);// key序列化
		redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);// value序列化
		redisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化
		redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);// Hash value序列化
		redisTemplate.afterPropertiesSet();
		return redisTemplate;
	}

	/**
	 * 缓存配置管理器
	 */
	@Bean
	public CacheManager cacheManager() {
		// 以锁写入的方式创建RedisCacheWriter对象
		RedisCacheWriter writer = RedisCacheWriter.lockingRedisCacheWriter(lettuceConnectionFactory);
		/**
		 * 设置CacheManager的Value序列化方式为JdkSerializationRedisSerializer,
		 * 但其实RedisCacheConfiguration默认就是使用 StringRedisSerializer序列化key,
		 * JdkSerializationRedisSerializer序列化value, 所以以下注释代码就是默认实现,没必要写,直接注释掉
		 */
		// RedisSerializationContext.SerializationPair pair =
		// RedisSerializationContext.SerializationPair.fromSerializer(new
		// JdkSerializationRedisSerializer(this.getClass().getClassLoader()));
		// RedisCacheConfiguration config =
		// RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(pair);
		// 创建默认缓存配置对象
//		RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(1)); // 设置缓存有效期一小时;
//		RedisCacheManager cacheManager = new RedisCacheManager(writer, config);
		/* 默认配置, 默认超时时间为30s */
		RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration
				.ofSeconds(30L)).disableCachingNullValues();
		/* 配置test的超时时间为120s*/
		RedisCacheManager cacheManager = RedisCacheManager.builder(RedisCacheWriter.lockingRedisCacheWriter
				(lettuceConnectionFactory)).cacheDefaults(defaultCacheConfig)
				.withInitialCacheConfigurations(singletonMap("TTL10S", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(10L)).disableCachingNullValues()))
				.withInitialCacheConfigurations(singletonMap("TTL10M", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(600L)).disableCachingNullValues()))
				.transactionAware().build();
		return cacheManager;
	}
}

我这里是修改的不对吗?怎么每次redis都是生成2个key
image

lexmeng added a commit to lexmeng/jeecg-boot that referenced this issue Jun 30, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants