如何在SPRING中同時管理本地快取和分散式快取? - techblog

banq發表於2020-06-16

新增@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抽象的大部分內容,但有時我們還是必須自己處理特殊情況。
 

相關文章