@Configuration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({LettuceConnectionConfiguration.class})
public class RedisConfig {
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate
重写RedisCacheManager:
public class MyRedisCacheManager extends RedisCacheManager implements ApplicationContextAware, InitializingBean {
private static final Logger LOGGER = LoggerFactory.getLogger(MyRedisCacheManager.class);
private ApplicationContext applicationContext;
private Map initialCacheConfiguration = new LinkedHashMap<>();
/**
* key serializer
*/
public static final StringRedisSerializer STRING_SERIALIZER = new StringRedisSerializer();
/**
* value serializer
*
* 使用 FastJsonRedisSerializer 会报错:java.lang.ClassCastException
* FastJsonRedisSerializer fastSerializer = new FastJsonRedisSerializer<>(Object.class);
*
*/
public static final GenericFastJsonRedisSerializer FASTJSON_SERIALIZER = new GenericFastJsonRedisSerializer();
/**
* key serializer pair
*/
public static final RedisSerializationContext.SerializationPair STRING_PAIR = RedisSerializationContext
.SerializationPair.fromSerializer(STRING_SERIALIZER);
/**
* value serializer pair
*/
public static final RedisSerializationContext.SerializationPair FASTJSON_PAIR = RedisSerializationContext
.SerializationPair.fromSerializer(FASTJSON_SERIALIZER);
public MyRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {
super(cacheWriter, defaultCacheConfiguration);
}
@Override
public Cache getCache(String name) {
Cache cache = super.getCache(name);
return new RedisCacheWrapper(cache);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public void afterPropertiesSet() {
String[] beanNames = applicationContext.getBeanNamesForType(Object.class);
for (String beanName : beanNames) {
final Class clazz = applicationContext.getType(beanName);
add(clazz);
}
super.afterPropertiesSet();
}
@Override
protected Collection loadCaches() {
List caches = new LinkedList<>();
for (Map.Entry entry : initialCacheConfiguration.entrySet()) {
caches.add(super.createRedisCache(entry.getKey(), entry.getValue()));
}
return caches;
}
private void add(final Class clazz) {
ReflectionUtils.doWithMethods(clazz, method -> {
ReflectionUtils.makeAccessible(method);
CacheExpire cacheExpire = AnnotationUtils.findAnnotation(method, CacheExpire.class);
if (cacheExpire == null) {
return;
}
Cacheable cacheable = AnnotationUtils.findAnnotation(method, Cacheable.class);
if (cacheable != null) {
add(cacheable.cacheNames(), cacheExpire);
return;
}
Caching caching = AnnotationUtils.findAnnotation(method, Caching.class);
if (caching != null) {
Cacheable[] cs = caching.cacheable();
if (cs.length > 0) {
for (Cacheable c : cs) {
if (cacheExpire != null && c != null) {
add(c.cacheNames(), cacheExpire);
}
}
}
} else {
CacheConfig cacheConfig = AnnotationUtils.findAnnotation(clazz, CacheConfig.class);
if (cacheConfig != null) {
add(cacheConfig.cacheNames(), cacheExpire);
}
}
}, method -> null != AnnotationUtils.findAnnotation(method, CacheExpire.class));
}
private void add(String[] cacheNames, CacheExpire cacheExpire) {
for (String cacheName : cacheNames) {
if (cacheName == null || "".equals(cacheName.trim())) {
continue;
}
long expire = cacheExpire.expire();
LOGGER.info("cacheName: {}, expire: {}", cacheName, expire);
if (expire >= 0) {
// 缓存配置
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(expire))
.disableCachingNullValues()
// .prefixKeysWith(cacheName)
.serializeKeysWith(STRING_PAIR)
.serializeValuesWith(FASTJSON_PAIR);
initialCacheConfiguration.put(cacheName, config);
} else {
LOGGER.warn("{} use default expiration.", cacheName);
}
}
}
protected static class RedisCacheWrapper implements Cache {
private final Cache cache;
RedisCacheWrapper(Cache cache) {
this.cache = cache;
}
@Override
public String getName() {
// LOGGER.info("name: {}", cache.getName());
try {
return cache.getName();
} catch (Exception e) {
LOGGER.error("getName ---> errmsg: {}", e.getMessage(), e);
return null;
}
}
@Override
public Object getNativeCache() {
// LOGGER.info("nativeCache: {}", cache.getNativeCache());
try {
return cache.getNativeCache();
} catch (Exception e) {
LOGGER.error("getNativeCache ---> errmsg: {}", e.getMessage(), e);
return null;
}
}
@Override
public ValueWrapper get(Object o) {
// LOGGER.info("get ---> o: {}", o);
try {
return cache.get(o);
} catch (Exception e) {
LOGGER.error("get ---> o: {}, errmsg: {}", o, e.getMessage(), e);
return null;
}
}
@Override
public T get(Object o, Class aClass) {
// LOGGER.info("get ---> o: {}, clazz: {}", o, aClass);
try {
return cache.get(o, aClass);
} catch (Exception e) {
LOGGER.error("get ---> o: {}, clazz: {}, errmsg: {}", o, aClass, e.getMessage(), e);
return null;
}
}
@Override
public T get(Object o, Callable callable) {
// LOGGER.info("get ---> o: {}", o);
try {
return cache.get(o, callable);
} catch (Exception e) {
LOGGER.error("get ---> o: {}, errmsg: {}", o, e.getMessage(), e);
return null;
}
}
@Override
public void put(Object o, Object o1) {
// LOGGER.info("put ---> o: {}, o1: {}", o, o1);
try {
cache.put(o, o1);
} catch (Exception e) {
LOGGER.error("put ---> o: {}, o1: {}, errmsg: {}", o, o1, e.getMessage(), e);
}
}
@Override
public ValueWrapper putIfAbsent(Object o, Object o1) {
// LOGGER.info("putIfAbsent ---> o: {}, o1: {}", o, o1);
try {
return cache.putIfAbsent(o, o1);
} catch (Exception e) {
LOGGER.error("putIfAbsent ---> o: {}, o1: {}, errmsg: {}", o, o1, e.getMessage(), e);
return null;
}
}
@Override
public void evict(Object o) {
// LOGGER.info("evict ---> o: {}", o);
try {
cache.evict(o);
} catch (Exception e) {
LOGGER.error("evict ---> o: {}, errmsg: {}", o, e.getMessage(), e);
}
}
@Override
public void clear() {
// LOGGER.info("clear");
try {
cache.clear();
} catch (Exception e) {
LOGGER.error("clear ---> errmsg: {}", e.getMessage(), e);
}
}
}
}