理解缓存抽象
其核心在于,缓存抽象将缓存机制应用于Java方法,从而根据缓存中的信息减少方法的执行次数。也就是说,每次调用某个方法时,该抽象会检查该方法是否已经针对给定的参数被调用过。如果已经调用过,则直接返回缓存结果,而无需再实际调用该方法;如果尚未调用过,则会执行该方法,并将结果缓存起来以便下次调用时能够直接返回缓存结果。通过这种方式,对于那些计算复杂(无论是依赖CPU运算还是I/O操作)的方法,即使针对相同的参数组合也只需调用一次,之后就可以重用缓存结果,而无需再次实际调用该方法。这种缓存逻辑的实现是透明的,不会对调用者造成任何干扰。
这种方法仅适用于那些无论被调用多少次,对于给定的输入(或参数)都能保证返回相同输出(结果)的方法。
缓存抽象提供了其他与缓存相关的操作,例如更新缓存内容或删除一个或所有条目的能力。如果缓存处理的数据在应用程序运行过程中可能会发生变化,这些功能就非常有用。
与Spring框架中的其他服务一样,缓存服务也是一种抽象(而不是缓存实现),它需要使用实际的存储来保存缓存数据——也就是说,这种抽象让你不必编写缓存逻辑,但不提供实际的数据存储机制。这种抽象通过org.springframework.cache CACHE和org.springframework.cache.CacheManager接口得以实现。
缓存抽象对多线程和多进程环境没有特殊的处理方式,因为这些特性是由缓存实现来处理的。
如果你拥有一个多进程环境(即,一个部署在多个节点上的应用程序),你需要相应地配置你的缓存提供者。根据你的使用场景,可能在几个节点上复制相同的数据就足够了。然而,如果你在应用程序运行过程中更改了数据,你可能需要启用其他的数据传播机制。
缓存某个特定项目,相当于程序化缓存交互中常见的“如果没有找到则继续执行,最终再put”的代码块。在这种情况下不会应用任何锁机制,因此多个线程可以同时尝试加载同一个项目。驱逐(eviction)操作也是如此。如果多个线程同时尝试更新或驱逐数据,那么就可能会导致使用到过时的数据。某些缓存提供者在这方面提供了更高级的功能。有关更多详细信息,请查阅你所使用的缓存提供者的文档。
要使用缓存抽象,你需要处理两个方面:
- 缓存声明:确定需要缓存的方法及其缓存策略。
- 缓存配置:存储数据并从中读取数据的后端缓存。