spring应用启动时如何制作缓存依赖于其他缓存
Posted
技术标签:
【中文标题】spring应用启动时如何制作缓存依赖于其他缓存【英文标题】:How to make cache depends on other caches on startup of spring application 【发布时间】:2019-12-30 02:51:17 【问题描述】:在我们的多模块项目中,我们在不同的模块中存在不同的缓存。我们在@PostConstruct 中的服务器启动时填充所有这些缓存。 现在一些缓存依赖于其他可能存在于不同模块中的缓存。因此,它要求在依赖于该缓存的缓存之前填充一些缓存。 1. 我们如何在 Spring 中做到这一点?我可以利用任何设计模式吗? 2. 如果缓存更新了,我们如何将更新后的更改实时传播到那些依赖更新缓存的缓存?
module 1---
Cachce1
module 2--
Cache2
module 3--
Cache3
class Cache1
private ConcurrentMap<> cache;
@PostConstruct()
cache = filleCache();
class Cache2
@Autowired
private Cache1 cache1;
private ConcurrentMap<> cache;
@PostConstruct()
cache = cache1;
class Cache3
@Autowired
private Cache2 cache2;
private ConcurrentMap<> cache;
@PostConstruct()
cache = cache2;
【问题讨论】:
【参考方案1】:Dependencies:初始化顺序通常由 DI 框架正确完成。所以Cache2
post 构造在Cache1
完全初始化之后运行。如果您仅在 CuncurrentMap
中缓存完整的数据集,则可以使用 memoization,请参阅 https://dzone.com/articles/need-micro-caching-memoization
避免缓存堆叠。有时避免在中间层中缓存更简单。一种简单的方法是缓存数据的来源,例如持久层,然后缓存数据输出的位置,例如响应 sn-ps 或完整响应。由于无论如何都将完整的数据缓存在最顶层的缓存中,因此中间缓存也可能不会得到任何命中。
这在很大程度上取决于数据的类型以及它在下一层使用的频率。
我们如何传播这个更新的变化?
您有多种选择。如果 module1 知道它的依赖关系,您可以调用 module2 和 3 的重新加载。如果 module1 代码不应该依赖于它的客户端,则使用事件侦听器模式。根据您的数据来自哪里,已经有现有的机制。查找 Spring Data 事件、数据库的更改数据捕获功能、数据库或持久层的触发器。
您可以通过使用缓存条目的过期时间来保持简单,并在一段时间后简单地更新/重新加载您的数据。但是,过期和缓存堆叠本身就是一个问题。如果您使用 5 分钟的固定到期时间,则有效到期时间会累加每一层。所以对于三层,数据可能会在 5 或 15 分钟后刷新。为了避免这种情况,我们通过缓存层传播了一个到期时间点以及数据。
【讨论】:
以上是关于spring应用启动时如何制作缓存依赖于其他缓存的主要内容,如果未能解决你的问题,请参考以下文章
spring的循环依赖及使用三级缓存解决循环依赖;注入bean到spring容器中
0源码基础学习Spring源码系列——Spring如何解决循环依赖