springboot 学习之路 11(集成redis做缓存)
背景:
redis是nosql类型数据库的代码,下面进行与springboot的集成并作为缓存来使用
具体配置如下:
准备工作:想创建一个springboot项目,假设我已经创建好了,如图:

注意:现在我创建的是springboot2x系列的项目,在集成redis上和spring1x系列有点不同,在集成过程中我会特别说出:
创建包结构:

实体类和dao大致如下:

redis的配置情况如下:

主要的类有ApplicationContextHolder 和 RedisCache
ApplicationContextHolder :

RedisCache:

到这redis缓存的配置类已经完成,剩下的是怎么让其生效了
在启动类上配置dao的扫描,

在xml中配置二级缓存

查询验证:
第一次查询: hikarpool (这是在springboot2x系列默认的,springboot1系列是tomcat连接池,将会打印sql查询)

redis中就存在了

第二次查询就直接从redis中获取:(这步就没查询,直接返回,说明redis缓存成功)

集成springboot2.x 集成redis配置(方式2):
第一步:配置pom文件

第二步:配置redis信息:

第三步:RedisCacheConfig类 配置:
package com.huhy.redis2; import org.springframework.beans.factory.annotation.Autowired; 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.RedisConnectionFactory; import java.time.Duration; /** * @author : huhy on 2018/8/14. * @Project_name:springboot_self_gitlab * @LOCAL:com.huhy.redis2 * @description:redis配置信息 主要配置时间 */ @Configuration @EnableCaching //开启缓存支持 public class RedisCacheConfig extends CachingConfigurerSupport { @Autowired private RedisConnectionFactory redisConnectionFactory; @Bean @Override public KeyGenerator keyGenerator() { return (o, method, objects) -> { StringBuilder sb = new StringBuilder(32); sb.append(o.getClass().getSimpleName()); sb.append("."); sb.append(method.getName()); if (objects.length > 0) { sb.append("#"); } String sp = ""; for (Object object : objects) { sb.append(sp); if (object == null) { sb.append("NULL"); } else { sb.append(object.toString()); } sp = "."; } return sb.toString(); }; } @Bean @Override public CacheManager cacheManager() { // 初始化一个RedisCacheWriter RedisCacheWriter cacheManager = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory); // 设置默认过期时间:30 分钟 RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofSeconds(30)) .serializeKeysWith(TedisCacheManager.STRING_PAIR) .serializeValuesWith(TedisCacheManager.FASTJSON_PAIR); RedisCacheManager redisCacheManager = new RedisCacheManager(cacheManager, defaultCacheConfig); return redisCacheManager; } }
第四步:配置redis管理器的优化配置,,key value的值
package com.huhy.redis2; import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; import org.springframework.cache.Cache; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Caching; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.data.redis.cache.RedisCache; 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.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.util.ReflectionUtils; import java.time.Duration; import java.util.*; import java.util.concurrent.Callable; /** * @author : huhy on 2018/8/14. * @Project_name:springboot_self_gitlab * @LOCAL:com.huhy.redis2 * @description:{todo} */ @Slf4j public class TedisCacheManager extends RedisCacheManager implements ApplicationContextAware, InitializingBean { private ApplicationContext applicationContext; private Map<String, RedisCacheConfiguration> initialCacheConfiguration = new LinkedHashMap<>(); /** * key serializer */ public static final StringRedisSerializer STRING_SERIALIZER = new StringRedisSerializer(); /** * value serializer * <pre> * 使用 FastJsonRedisSerializer 会报错:java.lang.ClassCastException * FastJsonRedisSerializer<Object> fastSerializer = new FastJsonRedisSerializer<>(Object.class); * </pre> */ public static final GenericFastJsonRedisSerializer FASTJSON_SERIALIZER = new GenericFastJsonRedisSerializer(); /** * key serializer pair */ public static final RedisSerializationContext.SerializationPair<String> STRING_PAIR = RedisSerializationContext .SerializationPair.fromSerializer(STRING_SERIALIZER); /** * value serializer pair */ public static final RedisSerializationContext.SerializationPair<Object> FASTJSON_PAIR = RedisSerializationContext .SerializationPair.fromSerializer(FASTJSON_SERIALIZER); public TedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) { super(cacheWriter, defaultCacheConfiguration); } // public TedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, // Map<String, RedisCacheConfiguration> initialCacheConfigurations) { // super(cacheWriter, defaultCacheConfiguration, initialCacheConfigurations); // } @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<RedisCache> loadCaches() { List<RedisCache> caches = new LinkedList<>(); for (Map.Entry<String, RedisCacheConfiguration> 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(); log.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 { log.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() { // log.info("name: {}", cache.getName()); try { return cache.getName(); } catch (Exception e) { log.error("getName ---> errmsg: {}", e.getMessage(), e); return null; } } @Override public Object getNativeCache() { // log.info("nativeCache: {}", cache.getNativeCache()); try { return cache.getNativeCache(); } catch (Exception e) { log.error("getNativeCache ---> errmsg: {}", e.getMessage(), e); return null; } } @Override public ValueWrapper get(Object o) { // log.info("get ---> o: {}", o); try { return cache.get(o); } catch (Exception e) { log.error("get ---> o: {}, errmsg: {}", o, e.getMessage(), e); return null; } } @Override public <T> T get(Object o, Class<T> aClass) { // log.info("get ---> o: {}, clazz: {}", o, aClass); try { return cache.get(o, aClass); } catch (Exception e) { log.error("get ---> o: {}, clazz: {}, errmsg: {}", o, aClass, e.getMessage(), e); return null; } } @Override public <T> T get(Object o, Callable<T> callable) { // log.info("get ---> o: {}", o); try { return cache.get(o, callable); } catch (Exception e) { log.error("get ---> o: {}, errmsg: {}", o, e.getMessage(), e); return null; } } @Override public void put(Object o, Object o1) { // log.info("put ---> o: {}, o1: {}", o, o1); try { cache.put(o, o1); } catch (Exception e) { log.error("put ---> o: {}, o1: {}, errmsg: {}", o, o1, e.getMessage(), e); } } @Override public ValueWrapper putIfAbsent(Object o, Object o1) { // log.info("putIfAbsent ---> o: {}, o1: {}", o, o1); try { return cache.putIfAbsent(o, o1); } catch (Exception e) { log.error("putIfAbsent ---> o: {}, o1: {}, errmsg: {}", o, o1, e.getMessage(), e); return null; } } @Override public void evict(Object o) { // log.info("evict ---> o: {}", o); try { cache.evict(o); } catch (Exception e) { log.error("evict ---> o: {}, errmsg: {}", o, e.getMessage(), e); } } @Override public void clear() { // log.info("clear"); try { cache.clear(); } catch (Exception e) { log.error("clear ---> errmsg: {}", e.getMessage(), e); } } } }
第五步:加上注解时间(可选)
package com.huhy.redis2; import org.springframework.core.annotation.AliasFor; import java.lang.annotation.*; /** * @author : huhy on 2018/8/14. * @Project_name:springboot_self_gitlab * @LOCAL:com.huhy.redis2 * @description:{todo} */ @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface CacheExpire { /** * expire time, default 60s */ @AliasFor("expire") long value() default 60L; /** * expire time, default 60s */ @AliasFor("value") long expire() default 60L; }
第六步:开启缓存,我已经在redisConfig文件上加了,就不在启动类上加了
第七步:测试即可
本文来自博客园,作者:huhy,转载请注明原文链接:https://www.cnblogs.com/huhongy/p/9182238.html

浙公网安备 33010602011771号