/*
 * Copyright 2002-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.cache.support;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.lang.Nullable;

Composite CacheManager implementation that iterates over a given collection of delegate CacheManager instances.

Allows NoOpCacheManager to be automatically added to the end of the list for handling cache declarations without a backing store. Otherwise, any custom CacheManager may play that role of the last delegate as well, lazily creating cache regions for any requested name.

Note: Regular CacheManagers that this composite manager delegates to need to return null from getCache(String) if they are unaware of the specified cache name, allowing for iteration to the next delegate in line. However, most CacheManager implementations fall back to lazy creation of named caches once requested; check out the specific configuration details for a 'static' mode with fixed cache names, if available.

Author:Costin Leau, Juergen Hoeller
See Also:
Since:3.1
/** * Composite {@link CacheManager} implementation that iterates over * a given collection of delegate {@link CacheManager} instances. * * <p>Allows {@link NoOpCacheManager} to be automatically added to the end of * the list for handling cache declarations without a backing store. Otherwise, * any custom {@link CacheManager} may play that role of the last delegate as * well, lazily creating cache regions for any requested name. * * <p>Note: Regular CacheManagers that this composite manager delegates to need * to return {@code null} from {@link #getCache(String)} if they are unaware of * the specified cache name, allowing for iteration to the next delegate in line. * However, most {@link CacheManager} implementations fall back to lazy creation * of named caches once requested; check out the specific configuration details * for a 'static' mode with fixed cache names, if available. * * @author Costin Leau * @author Juergen Hoeller * @since 3.1 * @see #setFallbackToNoOpCache * @see org.springframework.cache.concurrent.ConcurrentMapCacheManager#setCacheNames */
public class CompositeCacheManager implements CacheManager, InitializingBean { private final List<CacheManager> cacheManagers = new ArrayList<>(); private boolean fallbackToNoOpCache = false;
Construct an empty CompositeCacheManager, with delegate CacheManagers to be added via the "cacheManagers" property.
/** * Construct an empty CompositeCacheManager, with delegate CacheManagers to * be added via the {@link #setCacheManagers "cacheManagers"} property. */
public CompositeCacheManager() { }
Construct a CompositeCacheManager from the given delegate CacheManagers.
Params:
  • cacheManagers – the CacheManagers to delegate to
/** * Construct a CompositeCacheManager from the given delegate CacheManagers. * @param cacheManagers the CacheManagers to delegate to */
public CompositeCacheManager(CacheManager... cacheManagers) { setCacheManagers(Arrays.asList(cacheManagers)); }
Specify the CacheManagers to delegate to.
/** * Specify the CacheManagers to delegate to. */
public void setCacheManagers(Collection<CacheManager> cacheManagers) { this.cacheManagers.addAll(cacheManagers); }
Indicate whether a NoOpCacheManager should be added at the end of the delegate list. In this case, any getCache requests not handled by the configured CacheManagers will be automatically handled by the NoOpCacheManager (and hence never return null).
/** * Indicate whether a {@link NoOpCacheManager} should be added at the end of the delegate list. * In this case, any {@code getCache} requests not handled by the configured CacheManagers will * be automatically handled by the {@link NoOpCacheManager} (and hence never return {@code null}). */
public void setFallbackToNoOpCache(boolean fallbackToNoOpCache) { this.fallbackToNoOpCache = fallbackToNoOpCache; } @Override public void afterPropertiesSet() { if (this.fallbackToNoOpCache) { this.cacheManagers.add(new NoOpCacheManager()); } } @Override @Nullable public Cache getCache(String name) { for (CacheManager cacheManager : this.cacheManagers) { Cache cache = cacheManager.getCache(name); if (cache != null) { return cache; } } return null; } @Override public Collection<String> getCacheNames() { Set<String> names = new LinkedHashSet<>(); for (CacheManager manager : this.cacheManagers) { names.addAll(manager.getCacheNames()); } return Collections.unmodifiableSet(names); } }