快上网专注成都网站设计 成都网站制作 成都网站建设
成都网站建设公司服务热线:028-86922220

网站建设知识

十年网站开发经验 + 多家企业客户 + 靠谱的建站团队

量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决

Springcache@Cacheable的使用-创新互联

@Cacheable的使用
  • 1.@Cacheable
    • 1.1 cacheNames value
    • 1.2 关联多个缓存名
    • 1.3 key 和 keygenerator
    • 1.4 CacheManager CacheResolver
    • 1.5 sync
    • 1.6 condition
    • 1.7 unless
  • 2.@CachePut 放置缓存
  • 3.@CacheEvict 删除缓存
  • 4.测试代码
  • 5.默认缓存和redis缓存
  • 6.过程中的问题

建网站原本是网站策划师、网络程序员、网页设计师等,应用各种网络程序开发技术和网页设计技术配合操作的协同工作。创新互联建站专业提供网站制作、成都网站设计,网页设计,网站制作(企业站、成都响应式网站建设、电商门户网站)等服务,从网站深度策划、搜索引擎友好度优化到用户体验的提升,我们力求做到极致!1.@Cacheable

注解在方法上,表明方法的返回结果会缓存。相同的参数对应相同的返回缓存。以后相同的参数进行调用时,并不会执行方法,而是使用返回缓存中的值。

1.1 cacheNames value

@Cacheable提供两个参数来指定缓存名
cacheNames value
调用方法时,检查缓存,如果缓存中有数据,不会执行方法。

@Cacheable("menu")
public Menu findById(String id){}
1.2 关联多个缓存名

可以关联多个缓存名,执行方法时,关联的缓存都会检查,只要其中一个缓存命中,这个缓存的值就会返回。

@Cacheable({"menu","menu2"})
public Menu findById(String id){}
1.3 key 和 keygenerator

一个缓存名对应一个注解方法,但是一个方法传入不同的参数,结果不通,区分用到key。
key可以显示指定,也可以通过keygenerator生成

不指定key则会采用keyGenerator进行自动生成

官方推荐显式的指定key,可以通过springEL表达式来解决不同入参的问题

@Cacheable(value={"menu"},key="#id")
public Menu findById(String id){}

@Cacheable(value={"menu"},key="'id-'+#menu.id")
public Menu findById(Menu menu){}

key和keyGenerator是互斥的,同时指定两个会导致异常

1.4 CacheManager CacheResolver

CacheManager 缓存管理器用来管理一级缓存。缓存管理器与缓存组件类型相关联的。
srping缓存抽象的目的是为使用不同的缓存组件类型提供提供统一的访问接口,以向开发者屏蔽各种缓存组件的差异。
CacheResolver 缓存解析器是用来管理缓存管理器的,CacheResolver保持CacheManager的引用,并用他来检索缓存。类似于keyGenerator和key

一般情况下,系统只会使用一种缓存,不需要显式的指定CacheManager和CacheResolver。同时配置多中缓存,需要指定,使用的是@cacheable中的参数

1.5 sync

是否同步,多线程环境下相同参数的访问是否进行对入口加锁,即只有一个线程计算操作的结果值,避免了n-1次数据库访问
sync=true 可以有效避免缓存击穿的问题

1.6 condition

调用前判断,缓存的条件。接受springEL表达式,为true进行缓存,否则直接调用

1.7 unless

springEL表达式,为ture不缓存,为false缓存

2.@CachePut 放置缓存

@CachePut和@Cacheable属性相同
@CachePut是执行方法体缓存结果
@Cacheable是查找缓存,有就返回,没有执行方法体,缓存结果

3.@CacheEvict 删除缓存
  • beforeInvocation 是否在方法执行前清除缓存 默认false
    true的时候,先删除缓存,删除数据失败,查询会直达数据库,造成压力;
    false,先删除数据库,删除缓存失败,会造成脏缓存。多线程,执行缓存删除,方法执行慢,此时其他线程获得了脏缓存
  • allEntries 是否删除整个缓存(value和cacheNames指定的)
4.测试代码

依赖

org.springframework.bootspring-boot-starter-data-redis

配置

spring.redis.host=127.0.0.1
spring.redis.password=123456
spring.redis.port=6379

启动类注解

@SpringBootApplication
@EnableCaching
public class RedisTestApplication {public static void main(String[] args) {SpringApplication.run(RedisTestApplication.class, args);
    }

}

请求入口

@RestController
public class CacheTestController {@Autowired
    private CacheTest cacheTest;

    @RequestMapping("putCache")
    public String testCachePut(){cacheTest.testCachePut();
        return "放置缓存成功";
    }

    @RequestMapping("testCacheable")
    public String testCacheable(){cacheTest.testCacheable();
        return "获取缓存";
    }

    @RequestMapping("deleteCache")
    public String testCacheEvict(){cacheTest.testCacheEvict();
        return  "删除缓存";
    }
}	

缓存

@Component
public class CacheTest {@Autowired
    CacheManager cacheManager;



    @CachePut(value = "test1",key = "'testCache1'")
    public Integer testCachePut(){System.out.println("放置缓存");
        return 1;
    }

    @Cacheable(value = "test1",key = "'testCache1'")
    public Integer testCacheable(){System.out.println("缓存测试");
        return 1;
    }

    @CacheEvict(value = "test1",key = "'testCache1'")
    public void testCacheEvict(){System.out.println("删除缓存");
        return ;
    }

    public void getCache(){//        System.out.println(redisCacheManager.getCache("test1"));
        System.out.println(cacheManager.getCache("test1"));
    }
}

在这里插入图片描述

在进行请求后会发现redis中多了对应key的数据

在这里插入图片描述

在删除缓存后进行获取缓存测试,会发现,在没有缓存的时候会执行一次方法,之后多次调用就不会调用方法,而是获取缓存。

在这里插入图片描述

删除缓存后刷新redis,已经找不到对应key的数据了

5.默认缓存和redis缓存

不引入redis依赖 使用的是spring的缓存
CacheManager在没有redis依赖时,getCache走的ConcurrentMapCacheManager类中的
拿到的cache对象为org.springframework.cache.concurrent.ConcurrentMapCache@8347d73
有redis依赖getCache走的是AbstractCacheManager类中的
拿到的cache对象为org.springframework.data.redis.cache.RedisCache@11e1d8da

默认缓存的生命周期和项目周期是一致的。
redis缓存的生命周期是和redis中的数据的生命周期是一致的。
项目发版(重启)默认缓存会丢失,但是redis缓存,只要redis数据没清除,就不需要重新获取缓存。
为什么要用redis做缓存?
1.redis可以用几十G的内存来做缓存
2.redis缓存可以持久化
3.redis是分布式缓存,默认缓存的生命周期随着jvm的销毁而结束,属于本地缓存,不具有一致性。
4.redis可以处理百万并发,专业的缓存服务
5.redis缓存有过期机制
6.redis有丰富的API

6.过程中的问题
  • 1.起初一直没有在redis中找到对应key的缓存
    发现引入依赖spring-boot-starter-data-redis解决,将相应的redis相关bean扫入spring容器
  • 2.在公司测试好使,回家复现发现缓存不生效,@Cacheable不生效
    在启动类中加入 @EnableCaching解决,并不是网上的那些引入什么aop依赖,通过@EnableCaching注解中的@import注解注入代理的相关类。奇怪的是公司项目的启动类中并没有。初步怀疑是spring版本的问题,等知道了回来补上答案

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


本文标题:Springcache@Cacheable的使用-创新互联
文章起源:http://6mz.cn/article/djigjj.html

其他资讯