利用反射注册SpringCache的RedisCacheManager缓存信息

项目开发中,SpringCache是一个非常方便的工具,但是在配置信息注册时,用枚举方式可以满足遍历,但却无法应用在@Cacheable注解里,因此可以通过静态类的方式,借助反射完成缓存信息注册。

配置类如下:

package com.zora.cloud.demo.config;

import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import lombok.extern.slf4j.Slf4j;
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.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.lang.reflect.Field;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

/**
 * 

metaapp-gamex

*

com.metaapp.cloud.gamex.config

*

SpringCache配置

* * @author Yuhan.Ji * @since 2020.03.23 */ @Slf4j @Configuration public class CacheConfig { private String appName = "Demo"; /** * 当没有配置缓存失效时间情况下的默认ttl */ public static final int DEFAULT_EXPIRE_SECOND = 180; // 用于SpringBoot 2.0和2.1的配置方式 @Bean public RedisCacheManager builder(RedisConnectionFactory factory) { try { // 这里的参数填充对应的静态属性类 Map configMap = ReflectUtil.getCacheTtlConfigMap(Constants.class); RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.RedisCacheManagerBuilder .fromConnectionFactory(factory); if (!configMap.isEmpty()) { Map configurationMap = new HashMap<>(); for (String cacheName : configMap.keySet()) { configurationMap. put(cacheName, RedisCacheConfiguration .defaultCacheConfig() .computePrefixWith(name -> appName + ":" + name + ":") .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericFastJsonRedisSerializer())) .entryTtl(Duration.ofSeconds(configMap.get(cacheName)))); } builder.withInitialCacheConfigurations(configurationMap); log.info("MetaApp Spring Cache Redis : 缓存配置为:{}", configMap.toString()); } return builder.build(); } catch (IllegalAccessException illegalEx) { log.error("SpringCache RedisCacheManagerBuilderCustomizer配置失败,启动终止。请检查RedisCacheManagerBuilder类中ReflectUtil.getCacheTtlConfigMap()部分", illegalEx); System.exit(500); return null; } } // // 用于SpringBoot 2.2 的配置方式 // @Bean // public RedisCacheManagerBuilderCustomizer redisCacheManagerBuilderCustomizer() { // return builder -> { // try { // // 这里的参数填充对应的静态属性类 // Map configMap = ReflectUtil.getCacheTtlConfigMap(Constants.class); // if (!configMap.isEmpty()) { // Map configurationMap = new HashMap<>(); // for (String cacheName : configMap.keySet()) { // configurationMap. // put(cacheName, RedisCacheConfiguration // .defaultCacheConfig() // .computePrefixWith(name -> appName + ":" + name + ":") // .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) // .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericFastJsonRedisSerializer())) // .entryTtl(Duration.ofSeconds(configMap.get(cacheName)))); // } // builder.withInitialCacheConfigurations(configurationMap); // log.info("Redis缓存配置为:{}",configMap.toString()); // } // } catch (IllegalAccessException illegalEx) { // log.error("SpringCache RedisCacheManagerBuilderCustomizer配置失败,启动终止。请检查RedisCacheManagerBuilder类中ReflectUtil.getCacheTtlConfigMap()部分", illegalEx); // System.exit(500); // } // }; // } static class ReflectUtil { public static final String CACHE_NAME_PREFIX = "CACHE_NAME_"; public static final String CACHE_TTL_PREFIX = "CACHE_TTL_"; static Map getCacheTtlConfigMap(Class clazz) throws IllegalAccessException { Map cacheMapWithKeyTtl = new HashMap<>(); Field[] fields = clazz.getFields(); Map cacheNames = new HashMap<>(fields.length); // 配置cacheName for (Field field : fields) { if (field.getName().contains(CACHE_NAME_PREFIX)) { if (field.getType().equals(String.class)) { String lookingForTtlName = field.getName().replace(CACHE_NAME_PREFIX, CACHE_TTL_PREFIX); String value = (String) field.get(clazz); cacheNames.put(lookingForTtlName, value); } else { throw new IllegalAccessException("In constants configuration, the type of prefix of cache must be String. Illegal in " + clazz.getName() + "." + field.getName() + "."); } } } // 配置过期时间 for (Field field : fields) { if (field.getName().contains(CACHE_TTL_PREFIX)) { if (field.getType().equals(int.class) || field.getType().equals(Integer.class)) { if (cacheNames.containsKey(field.getName())) { cacheMapWithKeyTtl.put(cacheNames.get(field.getName()), field.getInt(clazz)); } } else { throw new IllegalAccessException("In constants configuration, the type of prefix of ttl must be int or Integer. Illegal in " + clazz.getName() + "." + field.getName() + "."); } } } // 配置默认过期时间 for (String cacheNameKey : cacheNames.keySet()) { String cacheName = cacheNames.get(cacheNameKey); if (!cacheMapWithKeyTtl.containsKey(cacheNames.get(cacheNameKey))) { log.warn("===========================Spring Cache Config 配置信息错误========================="); log.warn("Spring Cache Config 配置信息错误:{}文件中的缓存{}没有查询到对应失效时间的配置信息,将按默认值180秒执行。", clazz.getName(), cacheName); log.warn("=============================== Zora Cache Config ================================"); cacheMapWithKeyTtl.put(cacheName, DEFAULT_EXPIRE_SECOND); } } return cacheMapWithKeyTtl; } } }

你可能感兴趣的:(利用反射注册SpringCache的RedisCacheManager缓存信息)