抽象缓存

从3.1版开始,Spring框架透明地向现有Spring应用程序添加缓存的支持。与事务支持类似,缓存抽象允许一致地使用各种缓存解决方案,对代码的影响最小。

从spring4.1开始,通过JSR-107注解和更多定制选项的支持,缓存抽象得到了显著的扩展。

一、理解抽象缓存

缓存与缓存区

“缓冲区”和“缓存”往往可以互换使用。但是请注意,它们代表不同的事物。传统上,缓冲区被用作快速实体和慢速实体之间数据的中间临时存储区。由于一方必须等待另一方(这会影响性能),缓冲区允许整个数据块同时移动,而不是以小块形式移动,从而缓解了这一问题。数据只从缓冲区写入和读取一次。

另一方面,根据定义,缓存是隐藏的,双方都不知道发生了缓存。它还可以提高性能,通过让相同的数据以快速的方式多次读取来实现。

缓存抽象将缓存应用于Java方法,从而根据缓存中可用的信息减少执行的数量。也就是说,每次调用目标方法时,抽象应用一个缓存行为,检查该方法是否已针对给定参数执行。如果已执行,则返回缓存的结果,而不必执行实际的方法。如果该方法尚未执行,则执行该方法,并将结果缓存并返回给用户,以便下次调用该方法时返回缓存的结果。这样,对于给定的一组参数,昂贵的方法(无论是CPU还是IO绑定)只能执行一次,结果可以重用,而不必再次实际执行该方法。缓存逻辑是透明地应用的,不会对调用程序造成任何干扰。

这种方法只适用于那些保证对给定输入(或参数)返回相同输出(结果)的方法,而不管它执行了多少次。

缓存抽象提供了其他与缓存相关的操作,例如更新缓存内容或删除一个或所有条目的能力。如果缓存处理在应用程序过程中可能更改的数据,则这些选项非常有用。

与Spring框架中的其他服务一样,缓存服务是一种抽象(不是缓存实现),需要使用实际存储来存储缓存数据 - 也就是说,抽象使您不必编写缓存逻辑,但不提供实际的数据存储。这种抽象是由org.springframework.cache.Cache和org.springframework.cache.CacheManager接口来实现的。

Spring提供了这种抽象的一些实现:基于缓存的JDK java.util.concurrent.ConcurrentMap、Ehcache 2.x、Gemfire cache、Caffeine和JSR-107兼容缓存(如Ehcache 3.x)。

缓存抽象对于多线程和多进程环境没有特殊处理,因为这些特性由缓存实现处理。

如果你有一个多进程环境(即部署在多个节点上的应用程序),则需要相应地配置缓存提供程序。根据你的用例,在多个节点上复制相同的数据就足够了。但是,如果在应用程序过程中更改数据,则可能需要启用其他传播机制。

要使用缓存抽象,需要注意两个方面:

  • 缓存声明:标识需要缓存的方法及其策略。
  • 缓存配置:存储数据和从中读取数据的备份缓存。
基于声明性注解的缓存

对于缓存声明,Spring的缓存抽象提供了一组Java注解:

  • @Cacheable:标记支持缓存。
  • @CacheEvict:标记清除缓存。
  • @CachePut:在不干扰方法执行的情况下更新缓存。
  • @Caching:重新组合要应用于方法的多个缓存操作。
  • @CacheConfig:在类级别共享一些与缓存相关的常见设置。

 

posted @ 2020-07-14 22:37  codedot  阅读(140)  评论(0编辑  收藏  举报