1.基于Spring Cache实现二级缓存(Caffeine+Redis)
2.Springboot应用缓存实践之:Ehcache加持
3.Spring三级缓存
4.SpringBoot 缓存之 @Cacheable 详细介绍
5.超级干货为什么spring一定要弄个三级缓存?
6.SpringBoot系列缓存注解@Cacheable @CacheEvit @CachePut使用姿势介绍
基于Spring Cache实现二级缓存(Caffeine+Redis)
在探索缓存优化之道时,缓存缓存硬编码使用缓存的源码原理方式显得不够优雅。面对查询效率的缓存缓存提升需求,我们通常会采用缓存策略。源码原理然而,缓存缓存这种方式在业务逻辑与缓存操作之间引入了不必要的源码原理谷歌开源码耦合,导致代码的缓存缓存复杂性和维护成本上升。Spring Cache的源码原理引入,为这一问题提供了优雅的缓存缓存解决方案。
Spring Cache是源码原理Spring-context包提供的组件,允许通过注解方式使用缓存。缓存缓存它定义了标准接口,源码原理如Cache和CacheManager,缓存缓存使得缓存的源码原理管理与业务逻辑分离,提高代码的缓存缓存可读性和可维护性。
Spring Cache的核心接口包括Cache和CacheManager。Cache接口定义了缓存的基本操作,如存储、读取和清理;CacheManager接口则负责创建Cache实现bean,并提供基于缓存名进行隔离的功能。
在Spring Cache中,常用注解有@Cacheable、@CacheEvict、@CachePut和@Caching。@Cacheable用于查询数据的方法,@CacheEvict用于清除缓存,@CachePut用于更新缓存,而@Caching则允许在一个方法上配置多种注解。
为了进一步提升性能,我们引入了二级缓存的概念。一级缓存通常位于应用内部,如使用Caffeine作为高速缓存,而二级缓存则利用像Redis这样的linux close 源码远程存储。这种设计通过减少对远程缓存的频繁访问,显著降低了网络开销。
实现二级缓存时,需要考虑一致性、空值存储、缓存预热、存储数量上限、过期策略等关键问题。Caffeine作为高性能缓存库,提供了一种简洁的解决方案。它支持手动、同步加载和异步加载的写入策略,以及基于大小、时间或引用的缓存值清理策略。
统计信息的记录、高效的缓存淘汰算法、底层数据存储采用ConcurrentHashMap(结合了JDK8的优化)都是Caffeine的关键特性。LRU、LFU和FIFO等算法被用于缓存淘汰,其中W-TinyLFU算法结合了LRU和LFU的优点,以实现高命中率和低内存占用。
在实际应用中,结合Spring Cache与Caffeine实现二级缓存时,还需考虑分布式节点的一致性问题。通过Redis的订阅/发布功能,可以实现对数据更新和删除操作的跨节点通知,从而确保缓存的一致性。引入Redis缓存,不仅简化了节点间通信的复杂性,还避免了依赖额外组件。
为了集成Caffeine缓存,可通过Maven引入相关依赖包,源码安装centos并在配置文件(如application.yml)中添加二级缓存相关配置。在启动类上使用@EnableCaching注解启用缓存功能,最后在需要缓存的方法上添加@Cacheable注解即可。
Springboot应用缓存实践之:Ehcache加持
本文共 字,阅读大约需要 3分钟!代码在文尾处!
在如今高并发的互联网应用中,缓存的地位举足轻重,对提升程序性能帮助不小。而3.x开始的 Spring也引入了对 Cache的支持,那对于如今发展得如火如荼的 Spring Boot来说自然也是支持缓存特性的。当然 Spring Boot默认使用的是 SimpleCacheConfiguration,即使用ConcurrentMapCacheManager 来实现的缓存。但本文将讲述如何将 Ehcache缓存应用到Spring Boot应用中。
「Ehcache」 是一个基于Java实现的开源缓存管理库,提供了用内存、磁盘文件存储、以及分布式存储等多种灵活的管理方案。使用方式和原理都有点类似于 Spring事务管理,配合各项注解可以很容易的上手。
下文就上手来摸一摸它,结合对数据库的操作,我们让 Ehcache作为本地缓存来看一下效果!
比如我这里准备了一张用户表,包含几条记录:
我们将通过模拟数据库的存取操作来看看 Ehcache缓存加入后的效果。
pom.xml 中添加如下依赖:
创建Ehcache的配置文件 ehcache.xml并置于项目 classpath下:
配置 application.properties编写操作数据库和 Ehcache缓存的业务代码
看得很明白了,我们在getUsersByName接口上添加了注解:@Cacheable。这是 Ehcache的使用注解之一,除此之外常用的还有 @CachePut和 @CacheEvit,分别简单介绍一下:
改造SpringBoot应用主类
主要是在启动类上通过 @EnableCaching注解来显式地开启 Ehcache缓存
最终完工的整个工程的结构如下:
通过多次向接口localhost/getusersbynamePOST数据来观察效果:
可以看到缓存的启用和失效时的效果(上文ehcache的配置文件中设置了缓存user的实效时间为s):
由于能力有限,若有错误或者不当之处,还请大家批评指正,修改flume源码一起学习交流! 本文实验代码在此
Spring三级缓存
Spring框架采用三级缓存策略来巧妙地解决循环依赖问题,特别针对AOP代理对象的复杂场景。常规的一级缓存并不足以处理这种情况,因为循环依赖可能涉及AOP代理后的对象,而非原始对象。
二级缓存的引入是为了解决这个问题。当B和C依赖于A时,通过二级缓存存储A的代理对象,确保在创建B和C时不会重复创建A的代理,从而保持单例性。这种策略避免了在对象初始化后立即进行AOP操作,以遵循bean的生命周期。
然而,二级缓存的使用也有其挑战。它需要提前将AOP操作后的代理对象放入缓存,但这可能会干扰对象的初始化过程,因为AOP通常在对象初始化后执行后置处理。这意味着在设计三级缓存时,需要对Spring的源码有深入理解,特别是涉及这几个重要集合的部分:
1. 单例Bean获取的源码
总结来说,Spring的三级缓存策略通过精细的缓存管理,巧妙地处理了循环依赖问题,确保了bean的正确生命周期和性能优化。同时,理解源码中的关键集合和操作对实现这种策略至关重要。
SpringBoot 缓存之 @Cacheable 详细介绍
开启基于注解的缓存使用@EnableCaching标记在SpringBoot主启动类上。 @Cacheable注解用于实现方法结果的缓存。其常用属性包括: cacheNames/value:指定缓存组件名称,可以指定多个缓存。 key:缓存数据时使用的键,默认使用方法参数值,3128固件源码也可使用SP EL表达式编写。 keyGenerator:指定键生成器,自定义键生成规则。 cacheManager:指定缓存管理器,用于从特定缓存管理器获取缓存。 condition:在满足特定条件时才缓存方法结果。 unless:在指定条件为真时,不缓存方法返回值。 sync:是否使用异步模式,默认同步执行。 通过@Cacheable注解结合上述属性,可实现基于方法的缓存功能。同时利用SP EL表达式编写键,提供更灵活的键生成机制。结合不同属性的合理配置,可以有效优化系统性能,减少数据重复计算和加载时间。超级干货为什么spring一定要弄个三级缓存?
在深入探讨为什么Spring需要实现三级缓存之前,我们首先回顾Spring创建bean的流程。Spring在获取bean时会经历两到三层缓存的检查,这在处理循环依赖问题时尤其关键。
具体来说,Spring创建bean时,如果不存在循环依赖,通常只会使用到第一层缓存。但当存在循环依赖时,第二层和第三层缓存则发挥了重要作用。它们通过缓存对象工厂的返回结果来避免不必要的计算,提高效率。
以一个简单的demo为例,我们假设有两个接口及其实现类相互引用。当创建其中一个实现类时,Spring会先从第一层缓存中查找bean实例。如果没有找到,则可能进入第二或第三层缓存检查。若仍然未找到,Spring会调用对象工厂的`getObject`方法。该方法会先执行`getEarlyBeanReference`,如果返回新对象,则此对象会被缓存以供后续使用。这样,当其他依赖于当前bean的bean需要初始化时,可以避免重复计算,大大提高性能。
现在,让我们回到问题的核心:为什么Spring需要三级缓存?答案在于代理类的引入。代理类可能在bean的初始化过程中被创建,以实现诸如事务管理等功能。Spring通过三级缓存确保了代理类的正确引用,即使在处理循环依赖时也能保持一致。这使得在bean实例的创建和初始化之间建立了一层保护,确保了正确的依赖关系。
假设我们仅使用第一层缓存,那么在bean实例创建后,即使需要代理类,也无法确保在循环依赖场景下代理类的正确引用。引入第二层缓存,使得当对象工厂返回新对象时,该对象可以被缓存以供循环依赖的bean引用。第三层缓存则进一步确保了循环依赖场景下,代理类引用的一致性,防止了在初始化完成前代理类引用的混乱。
总的来说,三级缓存的设计并非为了代理类的存在,而是为了处理循环依赖时的复杂性。通过这一设计,Spring能够在提供循环依赖支持的同时,保持高性能和代码的可维护性。
若想进一步深入理解Spring源码,推荐查阅Spring源码深度解析专栏,其中详细解读了Spring的核心机制和源码细节,帮助开发者全面理解Spring框架。
SpringBoot系列缓存注解@Cacheable @CacheEvit @CachePut使用姿势介绍
本文将深入介绍SpringBoot中常用的缓存注解:@Cacheable、@CacheEvit、@CachePut以及@Caching,并探讨其使用姿势和常见问题。
一、项目环境与依赖
本项目采用SpringBoot 2.2.1.RELEASE,搭配maven 3.5.3和IDEA进行开发。选择Redis 5.0作为缓存后端。无需密码,本地运行即可。
二、缓存注解详解
1. @Cacheable:用于方法或类上,优先从缓存中检索结果。若缓存命中,则直接返回,否则执行方法并更新缓存。关键参数包括缓存名称前缀(cacheNames)和条件设置(condition)。
示例:访问方法时,根据参数yihuihui设置缓存key为say::p_yihuihui。当age为偶数时,仅在命中缓存后返回数据。
2. @CachePut:无论缓存是否存在,都更新方法返回的结果到缓存。适用于缓存更新场景。
3. @CacheEvict:用于删除指定的缓存项。适用于数据变动后需要清除旧缓存的场景。
4. @Caching:用于组合使用多个缓存策略,解决数据变动时同时更新多个缓存的问题。
三、异常处理与测试
当方法抛出异常时,缓存策略如何表现?测试发现,当age为0时,@Cacheable与@CachePut的缓存操作均未执行成功。
四、失效缓存与综合测试
通过与@Cacheable配合使用,实现失效缓存的管理。其他测试类着重验证缓存注解的正确性与一致性。
五、缓存失效时间设置
关于缓存的失效时间设置,本文未详细说明。下篇将专门探讨如何为不同缓存设置特定的失效时间,满足业务需求。
六、项目链接与资源
本文作者的一灰灰Blog,记录了学习与工作的博客文章,欢迎关注。
本文旨在提供SpringBoot中缓存注解的基本使用方法与常见问题解答。如有任何疑问或建议,欢迎在作者的博客中提出,共同探讨和学习。
Spring中@Cacheable、@CacheEvict以及其他缓存相关注解的实用介绍
缓存管理器是 Spring 应用程序中缓存机制的核心。它负责管理缓存数据,确保有效存储、检索和逐出条目。设置缓存管理器对于实现高效缓存至关重要。常用的缓存管理器如ConcurrentMapCacheManager、Hazelcast、Redis、EhCache 和 Caffeine,它们提供不同的性能和功能,以满足不同场景的需求。通过实现CacheManager接口,开发者可以创建自定义缓存管理器,以适应特定的应用需求。配置和调整缓存管理器参数,如缓存大小、失效时间等,可进一步优化性能。监控缓存的性能是确保缓存发挥作用而不成为瓶颈的重要步骤。
使用@Cacheable注释,开发者可以指示 Spring 将方法的返回值存储在指定的缓存中。这使得后续使用相同参数调用此方法时,可以从缓存中获取结果,而无需执行方法。此功能减少了计算负担,提高了应用程序性能。通过配置@CacheEvict注释,开发者可以确保在特定操作后缓存数据的更新。这确保了缓存数据与应用程序数据的一致性,避免了过时的信息。组合注释@Cacheable和@CacheEvict提供了更高级的缓存策略,支持根据具体场景的需求进行灵活配置。
Spring 提供了更高级的缓存注释和属性,如@CacheConfig、@CachePut 和@CacheResolver,以提供对缓存行为的更精细控制。@CacheConfig允许在类级别配置缓存策略,@CachePut用于在更新操作后更新缓存,而@CacheResolver用于解析缓存键和条件。密钥生成、自定义缓存条件等特性进一步增强了缓存的灵活性和适应性。最佳实践包括了解业务需求、选择合适的缓存类型、注意缓存粒度、动态缓存管理和优雅地处理缓存故障。通过遵循这些最佳实践,开发者可以最大限度地发挥缓存的优势,同时避免潜在的问题。
Spring 的缓存注释提供了强大而灵活的机制,用于优化应用程序性能。通过合理配置和使用这些注释,开发者可以实现响应能力的显著提升和可扩展性。然而,正确使用和监控缓存策略对于确保其性能优势的同时避免潜在问题至关重要。深入理解缓存机制,遵循最佳实践,定期测试和评估,以及保持文档更新,是确保 Spring 应用程序高效利用缓存的关键。