步骤一:引入 spring-boot-starter-cache 依赖
<!-- 引入Spring缓存依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency>
步骤二:启动类上使用注解 @EnableCaching 开启缓存
package com.haitaiinc.clinicpathservice; import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; @SpringBootApplication @MapperScan("com.haitaiinc.clinicpathservice.mapper") @EnableAutoConfiguration(exclude={DruidDataSourceAutoConfigure.class}) @EnableCaching public class ClinicPathServiceApplication { public static void main(String[] args) { SpringApplication.run(ClinicPathServiceApplication.class, args); } }
步骤三:使用缓存注解
@Service @CacheConfig(cacheNames = "switchCfgCache")//抽取缓存的公共配置 public class SwitchProjService { @Autowired SwitchProjDao switchProjDao; @Cacheable() public List<SwitchProj> getAllSwitchProj(){ return switchProjDao.getAllSwitchProj(); } @Cacheable(key = "#id") public SwitchProj getSwitchProjById(String id){ return switchProjDao.getSwitchProjById(id); } }
Spring Boot Cache 存在以下问题:
- 生成 key 过于简单,容易冲突 switchCfgCache::3
- 无法设置过期时间,默认过期时间为永久不过期
- 无法配置序列化方式,默认的序列化是 JDK Serialazable
那么为了解决以上问题,我们可以新增配置类,增加一些方法
package com.haitaiinc.clinicpathservice.config; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.CacheManager; 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 org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; import java.time.Duration; import java.util.HashMap; import java.util.Map; @Configuration @EnableCaching public class RedisConfiguration { @Bean public RedisTemplate<String,String> redisTemplate(RedisConnectionFactory redisConnectionFactory){ RedisTemplate<String,String> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); return redisTemplate; } @Bean public KeyGenerator simpleKeyGenerator() { return (o, method, objects) -> { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append(o.getClass().getSimpleName()); stringBuilder.append("."); stringBuilder.append(method.getName()); stringBuilder.append("["); for (Object obj : objects) { stringBuilder.append(obj.toString()); } stringBuilder.append("]"); return stringBuilder.toString(); }; } @Bean public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { return new RedisCacheManager( RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory), this.getRedisCacheConfigurationWithTtl(600), // 默认策略,未配置的 key 会使用这个 this.getRedisCacheConfigurationMap() // 指定 key 策略 ); } private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap() { Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>(); redisCacheConfigurationMap.put("SwitchCfgList", this.getRedisCacheConfigurationWithTtl(100)); return redisCacheConfigurationMap; } private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds) { Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig(); redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith( RedisSerializationContext .SerializationPair .fromSerializer(jackson2JsonRedisSerializer) ).entryTtl(Duration.ofSeconds(seconds)); return redisCacheConfiguration; } }
然后对我们的代码进行修改,注意配置类中标红的部分和代码修改后的内容(上面配置类中会被代码编辑器标出一些红色,但不影响编译运行)
@Service @CacheConfig(cacheNames = "switchCfgCache")//抽取缓存的公共配置 public class SwitchProjService { @Autowired SwitchProjDao switchProjDao; @Cacheable(value="SwitchCfgList", keyGenerator = "simpleKeyGenerator") public List<SwitchProj> getAllSwitchProj(){ return switchProjDao.getAllSwitchProj(); } @Cacheable(keyGenerator = "simpleKeyGenerator") public SwitchProj getSwitchProjById(String id){ return switchProjDao.getSwitchProjById(id); } }
下图显示的是效果:
也可以查看到缓存的有效时间
Redis 实现分布式集群配置 sessionId 过程
步骤一:引入依赖
<dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency>
步骤二:启动类增加注解 @EnableRedisHttpSession(maxInactiveIntervalInSeconds= 50)
@EnableRedisHttpSession 开启 Redis Session 缓存
maxInactiveIntervalInSeconds 指定缓存的时间 spring:session:sessions:expires:+‘sessionId’ 的过期时间
步骤三:测试
@RestController public class TestController { @GetMapping("/setSession") public Map<String, Object> setSession (HttpServletRequest request){ Map<String, Object> map = new HashMap<>(); request.getSession().setAttribute("request Url", request.getRequestURL()); map.put("request Url", request.getRequestURL()); return map; } @GetMapping("/getSession") public Object getSession (HttpServletRequest request){ Map<String, Object> map = new HashMap<>(); map.put("sessionIdUrl",request.getSession().getAttribute("request Url")); map.put("sessionId", request.getSession().getId()); return map; } }
效果如下图所示:
官方说明:
https://docs.spring.io/spring/docs/5.2.3.RELEASE/spring-framework-reference/integration.html#cache
参考博文:
https://blog.csdn.net/weixin_43907332/article/details/91610493