001/* 002 * Copyright 2002-2016 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.cache; 018 019import java.util.concurrent.Callable; 020 021/** 022 * Interface that defines common cache operations. 023 * 024 * <b>Note:</b> Due to the generic use of caching, it is recommended that 025 * implementations allow storage of <tt>null</tt> values (for example to 026 * cache methods that return {@code null}). 027 * 028 * @author Costin Leau 029 * @author Juergen Hoeller 030 * @author Stephane Nicoll 031 * @since 3.1 032 */ 033public interface Cache { 034 035 /** 036 * Return the cache name. 037 */ 038 String getName(); 039 040 /** 041 * Return the underlying native cache provider. 042 */ 043 Object getNativeCache(); 044 045 /** 046 * Return the value to which this cache maps the specified key. 047 * <p>Returns {@code null} if the cache contains no mapping for this key; 048 * otherwise, the cached value (which may be {@code null} itself) will 049 * be returned in a {@link ValueWrapper}. 050 * @param key the key whose associated value is to be returned 051 * @return the value to which this cache maps the specified key, 052 * contained within a {@link ValueWrapper} which may also hold 053 * a cached {@code null} value. A straight {@code null} being 054 * returned means that the cache contains no mapping for this key. 055 * @see #get(Object, Class) 056 */ 057 ValueWrapper get(Object key); 058 059 /** 060 * Return the value to which this cache maps the specified key, 061 * generically specifying a type that return value will be cast to. 062 * <p>Note: This variant of {@code get} does not allow for differentiating 063 * between a cached {@code null} value and no cache entry found at all. 064 * Use the standard {@link #get(Object)} variant for that purpose instead. 065 * @param key the key whose associated value is to be returned 066 * @param type the required type of the returned value (may be 067 * {@code null} to bypass a type check; in case of a {@code null} 068 * value found in the cache, the specified type is irrelevant) 069 * @return the value to which this cache maps the specified key 070 * (which may be {@code null} itself), or also {@code null} if 071 * the cache contains no mapping for this key 072 * @throws IllegalStateException if a cache entry has been found 073 * but failed to match the specified type 074 * @since 4.0 075 * @see #get(Object) 076 */ 077 <T> T get(Object key, Class<T> type); 078 079 /** 080 * Return the value to which this cache maps the specified key, obtaining 081 * that value from {@code valueLoader} if necessary. This method provides 082 * a simple substitute for the conventional "if cached, return; otherwise 083 * create, cache and return" pattern. 084 * <p>If possible, implementations should ensure that the loading operation 085 * is synchronized so that the specified {@code valueLoader} is only called 086 * once in case of concurrent access on the same key. 087 * <p>If the {@code valueLoader} throws an exception, it is wrapped in 088 * a {@link ValueRetrievalException} 089 * @param key the key whose associated value is to be returned 090 * @return the value to which this cache maps the specified key 091 * @throws ValueRetrievalException if the {@code valueLoader} throws an exception 092 * @since 4.3 093 */ 094 <T> T get(Object key, Callable<T> valueLoader); 095 096 /** 097 * Associate the specified value with the specified key in this cache. 098 * <p>If the cache previously contained a mapping for this key, the old 099 * value is replaced by the specified value. 100 * @param key the key with which the specified value is to be associated 101 * @param value the value to be associated with the specified key 102 */ 103 void put(Object key, Object value); 104 105 /** 106 * Atomically associate the specified value with the specified key in this cache 107 * if it is not set already. 108 * <p>This is equivalent to: 109 * <pre><code> 110 * Object existingValue = cache.get(key); 111 * if (existingValue == null) { 112 * cache.put(key, value); 113 * return null; 114 * } else { 115 * return existingValue; 116 * } 117 * </code></pre> 118 * except that the action is performed atomically. While all out-of-the-box 119 * {@link CacheManager} implementations are able to perform the put atomically, 120 * the operation may also be implemented in two steps, e.g. with a check for 121 * presence and a subsequent put, in a non-atomic way. Check the documentation 122 * of the native cache implementation that you are using for more details. 123 * @param key the key with which the specified value is to be associated 124 * @param value the value to be associated with the specified key 125 * @return the value to which this cache maps the specified key (which may be 126 * {@code null} itself), or also {@code null} if the cache did not contain any 127 * mapping for that key prior to this call. Returning {@code null} is therefore 128 * an indicator that the given {@code value} has been associated with the key. 129 * @since 4.1 130 */ 131 ValueWrapper putIfAbsent(Object key, Object value); 132 133 /** 134 * Evict the mapping for this key from this cache if it is present. 135 * @param key the key whose mapping is to be removed from the cache 136 */ 137 void evict(Object key); 138 139 /** 140 * Remove all mappings from the cache. 141 */ 142 void clear(); 143 144 145 /** 146 * A (wrapper) object representing a cache value. 147 */ 148 interface ValueWrapper { 149 150 /** 151 * Return the actual value in the cache. 152 */ 153 Object get(); 154 } 155 156 157 /** 158 * Wrapper exception to be thrown from {@link #get(Object, Callable)} 159 * in case of the value loader callback failing with an exception. 160 * @since 4.3 161 */ 162 @SuppressWarnings("serial") 163 class ValueRetrievalException extends RuntimeException { 164 165 private final Object key; 166 167 public ValueRetrievalException(Object key, Callable<?> loader, Throwable ex) { 168 super(String.format("Value for key '%s' could not be loaded using '%s'", key, loader), ex); 169 this.key = key; 170 } 171 172 public Object getKey() { 173 return this.key; 174 } 175 } 176 177}