添加@Cacheable可让spring为您创建一些合理的默认值的缓存,但是如果你有多个缓存类型,一个用于本地缓存,一个用于分布式缓存,就不是那么简单了。
因此,面对这个问题,我不得不设计一种简单的机制,将某些缓存指定为“分布式”,将某些缓存指定为“本地”。单独使用CompositeCacheManager不会做到这一点,因此我扩展了分布式缓存管理器(在这种情况下为Hazelcast,但可以使用任何提供程序来完成):
/** * Hazelcast cache manager that handles only cache names with a specified prefix for distributed caches */ public class OptionalHazelcastCacheManager extends HazelcastCacheManager { private static final String DISTRIBUTED_CACHE_PREFIX = "d:"; public OptionalHazelcastCacheManager(HazelcastInstance hazelcast) { super(hazelcast); } @Override public Cache getCache(String name) { if (name == null || !name.startsWith(DISTRIBUTED_CACHE_PREFIX)) { return null; } return super.getCache(name); } }
|
以及相应的复合缓存管理器配置:
<bean id="cacheManager" class="org.springframework.cache.support.CompositeCacheManager"> <property name="cacheManagers"> <list> <bean id="hazelcastCacheManager" class="com.yourcompany.util.cache.OptionalHazelcastCacheManager"> <constructor-arg ref="hazelcast" /> </bean> <bean id="caffeineCacheManager" class="com.yourcompany.util.cache.FlexibleCaffeineCacheManager"> <property name="cacheSpecification" value="expireAfterWrite=10m"/> <property name="cacheSpecs"> <map> <entry key="statistics" value="expireAfterWrite=1h"/> </map> </property> </bean> </list> </property> </bean>
|
基本上,这意味着任何名称以d:(“ distributed” 开头)的缓存都应由分布式缓存管理器处理。否则,请转到下一个缓存管理器(在这种情况下为咖啡因)。因此,当您想定义一个具有可缓存结果的方法时,您必须确定它是@Cacheable("d:cachename")还是仅@Cacheable("cachename")
这可能是解决该问题的多种方法之一,但我喜欢它的简单性。缓存是很难的(分布式缓存更是如此),虽然我们很幸运能够拥有Spring抽象的大部分内容,但有时我们还是必须自己处理特殊情况。