SpringBoot实现Redis缓存(SpringCache+Redis的整合)

您所在的位置:网站首页 怎么使用redis删除缓存 SpringBoot实现Redis缓存(SpringCache+Redis的整合)

SpringBoot实现Redis缓存(SpringCache+Redis的整合)

2024-05-31 15:48| 来源: 网络整理| 查看: 265

数据库的数据是存储在硬盘上的,频繁访问性能较低。如果将一些需要频繁查询的热数据放到内存的缓存中,可以大大减轻数据库的访问压力。

SpringCache

SpringCache提供基本的Cache抽象,并没有具体的缓存能力,需要配合具体的缓存实现来完成,目前SpringCache支持redis、ehcache、simple(基于内存)等方式来实现缓存。

org.springframework.boot spring-boot-starter-cache Spring常用的缓存注解

非常好的参考文章 SpringBoot基础系列-SpringCache使用 spring boot2 (28)-cache缓存 SpringBoot2.x—SpringCache(2)使用 通过继承CachingConfigurerSupport类自定义缓存管理器【与本文方式不同,值得一看】

@EnableCaching:开启缓存功能,一般使用在springboot的启动类或配置类上@Cacheable:使用缓存。在方法执行前Spring先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;没有则调用方法并将方法返回值放进缓存。 @Cacheable属性名用途备注cacheNames指定缓存空间的名称,不同缓存空间的数据是彼此隔离的key同一个cacheNames中通过key区别不同的缓存。如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合,如:@CachePut(value = “demo”, key = “‘user’+#user.id”),字符串中spring表达式意外的字符串部分需要用单引号SpringCache提供了与缓存相关的专用元数据,如target、methodMame、result、方法参数等,如:@CachePut(value = “demo”, key = “#result==null”)keyGenratorkey的生成策略,SpringCache默认使用SimpleKeyGenerator,默认情况下将参数值作为键,但是可能会导致key重复出现,因此一般需要自定义key的生成策略conditioncondition是在调用方法之前判断条件,满足条件才缓存@Cacheable(cacheNames=“book”, condition="#name.length() < 32")unlessunless是在调用方法之后判断条件,如果SpEL条件成立,则不缓存【条件满足不缓存】@Cacheable(cacheNames = “hello”,unless="#result.id.contains(‘1’)" )sync缓存过期之后,如果多个线程同时请求对某个数据的访问,会同时去到数据库,导致数据库瞬间负荷增高。Spring4.3为@Cacheable注解提供了一个新的参数“sync”(boolean类型,默认为false)。当设置它为true时,只有一个线程的请求会去到数据库,其他线程都会等待直到缓存可用。这个设置可以减少对数据库的瞬间并发访问。 @CachePut:更新缓存,将方法的返回值放到缓存中 //当返回值为null时,通过unless属性 @CachePut(key = “#id”, unless=”#result == null”) @CacheEvict:清空缓存@Caching:组合定义多种缓存功能@CacheConfig:用于标注在类上,可以存放该类中所有缓存的公有属性,比如设置缓存空间的名字cacheNames、key生成策略keyGenerator、缓存管理器cacheManager SpringCache采用Redis实现缓存 依赖 org.springframework.boot spring-boot-starter-cache 2.3.0.RELEASE org.springframework.boot spring-boot-starter-data-redis 2.3.0.RELEASE lettuce-core io.lettuce 配置yaml文件 spring: redis: database: 0 host: www.onething.top port: 6379 password: 123456nw #配置jedis客户端,这里也可以jedis替换为lettuce客户端,下级配置都一样 jedis: pool: # 连接池中的最大空闲连接 默认8 max-idle: 8 # 连接池中的最小空闲连接 默认0 min-idle: 0 # 连接池最大连接数 默认8 ,负数表示没有限制 max-active: 8 # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认-1 max-wait: -1 timeout: 3000 cache: type: redis # 指定使用的缓存类型 # redis: 当自定义ChacheManager时,就这里的配置不需要配置,配置了也不起作用 # use-key-prefix: true # key-prefix: "demo:" # time-to-live: 60000 #缓存超时时间 单位:ms # cache-null-values: false #是否缓存空值 cache-names: user cache: ttl: '{"user":60,"dept":30}' #自定义某些缓存空间的过期时间 自定义ChacheManager、缓存key的生成策略,将默认的jdk序列化策略修改为json序列化策略 @Configuration public class RedisConfiguration { // ${cache} 获取配置文件的配置信息 #{}是spring表达式,获取Bean对象的属性 @Value("#{${cache}}") private Map ttlParams; /** * @param redisConnectionFactory * @功能描述 redis作为缓存时配置缓存管理器CacheManager,主要配置序列化方式、自定义 *

* 注意:配置缓存管理器CacheManager有两种方式: * 方式1:通过RedisCacheConfiguration.defaultCacheConfig()获取到默认的RedisCacheConfiguration对象, * 修改RedisCacheConfiguration对象的序列化方式等参数【这里就采用的这种方式】 * 方式2:通过继承CachingConfigurerSupport类自定义缓存管理器,覆写各方法,参考: * https://blog.csdn.net/echizao1839/article/details/102660649 *

* 切记:在缓存配置类中配置以后,yaml配置文件中关于缓存的redis配置就不会生效,如果需要相关配置需要通过@value去读取 */ @Bean public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig(); redisCacheConfiguration = redisCacheConfiguration // 设置key采用String的序列化方式 .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(StringRedisSerializer.UTF_8)) //设置value序列化方式采用jackson方式序列化 .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer())) //当value为null时不进行缓存 .disableCachingNullValues() // 配置缓存空间名称的前缀 .prefixCacheNameWith("demo:") //全局配置缓存过期时间【可以不配置】 .entryTtl(Duration.ofMinutes(30L)); //专门指定某些缓存空间的配置,如果过期时间【主要这里的key为缓存空间名称】 Map map = new HashMap(); Set entries = ttlParams.entrySet(); for (Map.Entry entry : entries) { //指定特定缓存空间对应的过期时间 map.put("user", redisCacheConfiguration.entryTtl(Duration.ofSeconds(40))); map.put(entry.getKey(), redisCacheConfiguration.entryTtl(Duration.ofSeconds(entry.getValue()))); } return RedisCacheManager .builder(redisConnectionFactory) .cacheDefaults(redisCacheConfiguration) //默认配置 .withInitialCacheConfigurations(map) //某些缓存空间的特定配置 .build(); } /** * 自定义缓存的redis的KeyGenerator【key生成策略】 * 注意: 该方法只是声明了key的生成策略,需在@Cacheable注解中通过keyGenerator属性指定具体的key生成策略 * 可以根据业务情况,配置多个生成策略 * 如: @Cacheable(value = "key", keyGenerator = "cacheKeyGenerator") */ @Bean public KeyGenerator keyGenerator() { /** * target: 类 * method: 方法 * params: 方法参数 */ return (target, method, params) -> { //获取代理对象的最终目标对象 StringBuilder sb = new StringBuilder(); sb.append(target.getClass().getSimpleName()).append(":"); sb.append(method.getName()).append(":"); //调用SimpleKey的key生成器 Object key = SimpleKeyGenerator.generateKey(params); return sb.append(key); }; } /** * @param redisConnectionFactory:配置不同的客户端,这里注入的redis连接工厂不同: JedisConnectionFactory、LettuceConnectionFactory * @功能描述 :配置Redis序列化,原因如下: * (1) StringRedisTemplate的序列化方式为字符串序列化, * RedisTemplate的序列化方式默为jdk序列化(实现Serializable接口) * (2) RedisTemplate的jdk序列化方式在Redis的客户端中为乱码,不方便查看, * 因此一般修改RedisTemplate的序列化为方式为JSON方式【建议使用GenericJackson2JsonRedisSerializer】 */ @Bean public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) { GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = serializer(); RedisTemplate redisTemplate = new RedisTemplate(); // key采用String的序列化方式 redisTemplate.setKeySerializer(StringRedisSerializer.UTF_8); // value序列化方式采用jackson redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer); // hash的key也采用String的序列化方式 redisTemplate.setHashKeySerializer(StringRedisSerializer.UTF_8); //hash的value序列化方式采用jackson redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer); redisTemplate.setConnectionFactory(redisConnectionFactory); return redisTemplate; } /** * 此方法不能用@Ben注解,避免替换Spring容器中的同类型对象 */ public GenericJackson2JsonRedisSerializer serializer() { return new GenericJackson2JsonRedisSerializer(); } } 应用

(1)开启缓存功能

@EnableCaching //开启缓存的主键 @SpringBootApplication public class RedisDemoApplication { public static void main(String[] args) { SpringApplication.run(RedisDemoApplication.class, args); } }

(2)使用缓存

@Service @CacheConfig(cacheNames = "user",keyGenerator = "keyGenerator") public class RedisServiceImpl implements RedisService { @Cacheable(value = "user", key = "'list'") @Override public List list() { System.out.println("=========list"); User user1 = new User(); user1.setId(1); user1.setName("老大"); User user2 = new User(); user2.setId(2); user2.setName("老二"); List users = new ArrayList(); users.add(user1); users.add(user2); return users; } @CacheEvict(value = "user", key = "'list'") @Override public void del(Integer id) { System.out.println("************************************+id"); List users = new ArrayList(); Iterator iterator = users.iterator(); while (iterator.hasNext()) { User user = iterator.next(); if (user.getId().equals(id)) { iterator.remove(); break; } } } @CachePut(value = "demo", key = "#result==null") @Override public User select(Integer id) { System.out.println("===============dddd================"); if (id == 0) { return null; } User user = new User(); user.setId(100); user.setName("测试"); return user; } }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3