本文的所有实现均基于博客
Q:为啥要使用缓存? A:对于机器而言,每一次的访问,程序都会按照步骤去执行一遍。但是比如同一个请求,对于服务器而言每次反馈的内容都是一样的,为了避免这种资源的浪费,对于一些重复的操作,而且结果往往是稳定不变的,可以使用缓存。缓存操作就是将第一真实查询的结果进行存储,后续的操作,就直接返回结果,而不再去真正的查询。
CacheManager是用来配置cache缓存相关的信息。
@Bean
public CacheManager cacheManager(){
SimpleCacheManager simpleCacheManager=new SimpleCacheManager();
//name的作用,开的是工作空间
simpleCacheManager.setCaches(Collections.singletonList(new ConcurrentMapCache("models")));
return simpleCacheManager;
}
Controller用来测试缓存的赋予,删除以及更新。 重要注解解释: @Cacheable:缓存相关的内存,value指定的是上面我设定的(cacheNames也可以),condition可以设定缓存条件,key可以用来设置缓存的key值(默认为空,key的相关设置可以在解决的问题里面看) @CacheEvict:消除相关的缓存,特殊的键是allEntries,可以指定是不是全部消除 @CachePut:更新相关缓存 NOTE:三个相关的注解可以使用的键几乎相同,如果想了解更多可以去看看注解的相关源码或者查询相关东西哈
@GetMapping("/get")
// @Cacheable(key="#person.name")
@Cacheable(value="models",key="#person.name")
public Person getPerson(Person person){
System.out.println("Person.address:"+person.getAddress());
return person;
}
// 无条件全部cache,不带key,默认是空?这个测试过了,没有设置过的value会报错的
@PostMapping("/get/new")
@Cacheable(value="new")
public Person getNewCache(Person Person){
Person.setName(Person.getName().toUpperCase());
return Person;
}
//删除cache
@DeleteMapping("/delete/{name}")
@CacheEvict(value="models",key="#name")
public String deleteCache(@PathVariable("name") String name){
System.out.println("system input name:"+name);
return "delete Cache success!";
}
@PutMapping("/put")
@CachePut(value="models",key="#person.name")
public Person putCache(Person person){
System.out.println("key:"+person.getName()+","+"address:"+person.getAddress());
return person;
}
每次都需要手动删除的话,很麻烦的,所以定制了一个定时任务,默认删除所有的key值。
@Scheduled(fixedRate=10000)
@CacheEvict(value="models", allEntries = true)
public void cacheRemove(){
}
使用SimpleCacheManager中的cache(hashmap或者是ConcurrentHashMap)会存储会出现一个问题,那就是在缓存一直在变多的时候内存一直会增长,那就可能会crash掉了;解决这个的办法就是自己remove掉,调用或者是schedule都可以。 解决的办法:使用GuavaCache,可以自定义内存使用多少个键值和过期时间等,具体使用看博客
redis的序列化和反序列化的技术和是实现方式。
这个现在只是copy其他博客的一些实现,暂时还没有自己理解redis的序列化和反序列化的东西,这个需要以后研究一下(可能是下一篇博客吧) 主要实现的代码:
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory){
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
Set<String> cacheName=new HashSet<>();
// 一定要有cacheName,不然存储不了
cacheName.add("models1");
cacheName.add("models2");
cacheName.add("models");
//解决查询缓存转换异常的问题
// ObjectMapper om = new ObjectMapper();
// om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
// jackson2JsonRedisSerializer.setObjectMapper(om);
//配置序列化
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMillis(10)) //设置时间10分钟
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
.disableCachingNullValues()
.disableKeyPrefix();
RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory)
.initialCacheNames(cacheName)
.cacheDefaults(config)
.build();
return cacheManager;
这是重写cacheConfig就可以实现,这个等有需求再实现吧。 有看博客的小伙伴如果需要我实现的话,我也可以去试试,哈哈哈。(起码要用动力,你说是不?)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。