1 Star 0 Fork 0

eason/SpringCacheDemo

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

SpringCache初窥

本文的所有实现均基于博客

引入

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,可以自定义内存使用多少个键值和过期时间等,具体使用看博客

解决的问题

  1. cache使用系统内存,默认存在CacheManager中;获取内容需要getNativeCache,这样才能取出数据
  2. springcache的加载机制:默认是用的SimpleCacheManager,使用的是ConcurrentHashMap
  3. spring-cache在spring-web程序中带有了重要的context包,本项目功能不需要重新maven加载,其他功能暂时不了解。
  4. spring-cache中key使用的是Spring Expression Language
  5. springcache中不存在的键,delete的时候会报错,需要handle????
  6. 用redis去做缓存后面实现了

遗留的问题

redis的序列化和反序列化的技术和是实现方式。

额外内容

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;

多cacheManager实现

这是重写cacheConfig就可以实现,这个等有需求再实现吧。 有看博客的小伙伴如果需要我实现的话,我也可以去试试,哈哈哈。(起码要用动力,你说是不?)

空文件

简介

取消

发行版

暂无发行版

贡献者

全部

近期动态

不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/eason93/SpringCacheDemo.git
git@gitee.com:eason93/SpringCacheDemo.git
eason93
SpringCacheDemo
SpringCacheDemo
master

搜索帮助