如何在SPRING中同时管理本地缓存和分布式缓存? - techblog


添加@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抽象的大部分内容,但有时我们还是必须自己处理特殊情况。