001/* 002 * Copyright 2002-2019 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 021import org.springframework.lang.Nullable; 022 023/** 024 * Interface that defines common cache operations. 025 * 026 * <b>Note:</b> Due to the generic use of caching, it is recommended that 027 * implementations allow storage of <tt>null</tt> values (for example to 028 * cache methods that return {@code null}). 029 * 030 * @author Costin Leau 031 * @author Juergen Hoeller 032 * @author Stephane Nicoll 033 * @since 3.1 034 */ 035public interface Cache { 036 037 /** 038 * Return the cache name. 039 */ 040 String getName(); 041 042 /** 043 * Return the underlying native cache provider. 044 */ 045 Object getNativeCache(); 046 047 /** 048 * Return the value to which this cache maps the specified key. 049 * <p>Returns {@code null} if the cache contains no mapping for this key; 050 * otherwise, the cached value (which may be {@code null} itself) will 051 * be returned in a {@link ValueWrapper}. 052 * @param key the key whose associated value is to be returned 053 * @return the value to which this cache maps the specified key, 054 * contained within a {@link ValueWrapper} which may also hold 055 * a cached {@code null} value. A straight {@code null} being 056 * returned means that the cache contains no mapping for this key. 057 * @see #get(Object, Class) 058 * @see #get(Object, Callable) 059 */ 060 @Nullable 061 ValueWrapper get(Object key); 062 063 /** 064 * Return the value to which this cache maps the specified key, 065 * generically specifying a type that return value will be cast to. 066 * <p>Note: This variant of {@code get} does not allow for differentiating 067 * between a cached {@code null} value and no cache entry found at all. 068 * Use the standard {@link #get(Object)} variant for that purpose instead. 069 * @param key the key whose associated value is to be returned 070 * @param type the required type of the returned value (may be 071 * {@code null} to bypass a type check; in case of a {@code null} 072 * value found in the cache, the specified type is irrelevant) 073 * @return the value to which this cache maps the specified key 074 * (which may be {@code null} itself), or also {@code null} if 075 * the cache contains no mapping for this key 076 * @throws IllegalStateException if a cache entry has been found 077 * but failed to match the specified type 078 * @since 4.0 079 * @see #get(Object) 080 */ 081 @Nullable 082 <T> T get(Object key, @Nullable Class<T> type); 083 084 /** 085 * Return the value to which this cache maps the specified key, obtaining 086 * that value from {@code valueLoader} if necessary. This method provides 087 * a simple substitute for the conventional "if cached, return; otherwise 088 * create, cache and return" pattern. 089 * <p>If possible, implementations should ensure that the loading operation 090 * is synchronized so that the specified {@code valueLoader} is only called 091 * once in case of concurrent access on the same key. 092 * <p>If the {@code valueLoader} throws an exception, it is wrapped in 093 * a {@link ValueRetrievalException} 094 * @param key the key whose associated value is to be returned 095 * @return the value to which this cache maps the specified key 096 * @throws ValueRetrievalException if the {@code valueLoader} throws an exception 097 * @since 4.3 098 * @see #get(Object) 099 */ 100 @Nullable 101 <T> T get(Object key, Callable<T> valueLoader); 102 103 /** 104 * Associate the specified value with the specified key in this cache. 105 * <p>If the cache previously contained a mapping for this key, the old 106 * value is replaced by the specified value. 107 * <p>Actual registration may be performed in an asynchronous or deferred 108 * fashion, with subsequent lookups possibly not seeing the entry yet. 109 * This may for example be the case with transactional cache decorators. 110 * Use {@link #putIfAbsent} for guaranteed immediate registration. 111 * @param key the key with which the specified value is to be associated 112 * @param value the value to be associated with the specified key 113 * @see #putIfAbsent(Object, Object) 114 */ 115 void put(Object key, @Nullable Object value); 116 117 /** 118 * Atomically associate the specified value with the specified key in this cache 119 * if it is not set already. 120 * <p>This is equivalent to: 121 * <pre><code> 122 * ValueWrapper existingValue = cache.get(key); 123 * if (existingValue == null) { 124 * cache.put(key, value); 125 * } 126 * return existingValue; 127 * </code></pre> 128 * except that the action is performed atomically. While all out-of-the-box 129 * {@link CacheManager} implementations are able to perform the put atomically, 130 * the operation may also be implemented in two steps, e.g. with a check for 131 * presence and a subsequent put, in a non-atomic way. Check the documentation 132 * of the native cache implementation that you are using for more details. 133 * <p>The default implementation delegates to {@link #get(Object)} and 134 * {@link #put(Object, Object)} along the lines of the code snippet above. 135 * @param key the key with which the specified value is to be associated 136 * @param value the value to be associated with the specified key 137 * @return the value to which this cache maps the specified key (which may be 138 * {@code null} itself), or also {@code null} if the cache did not contain any 139 * mapping for that key prior to this call. Returning {@code null} is therefore 140 * an indicator that the given {@code value} has been associated with the key. 141 * @since 4.1 142 * @see #put(Object, Object) 143 */ 144 @Nullable 145 default ValueWrapper putIfAbsent(Object key, @Nullable Object value) { 146 ValueWrapper existingValue = get(key); 147 if (existingValue == null) { 148 put(key, value); 149 } 150 return existingValue; 151 } 152 153 /** 154 * Evict the mapping for this key from this cache if it is present. 155 * <p>Actual eviction may be performed in an asynchronous or deferred 156 * fashion, with subsequent lookups possibly still seeing the entry. 157 * This may for example be the case with transactional cache decorators. 158 * Use {@link #evictIfPresent} for guaranteed immediate removal. 159 * @param key the key whose mapping is to be removed from the cache 160 * @see #evictIfPresent(Object) 161 */ 162 void evict(Object key); 163 164 /** 165 * Evict the mapping for this key from this cache if it is present, 166 * expecting the key to be immediately invisible for subsequent lookups. 167 * <p>The default implementation delegates to {@link #evict(Object)}, 168 * returning {@code false} for not-determined prior presence of the key. 169 * Cache providers and in particular cache decorators are encouraged 170 * to perform immediate eviction if possible (e.g. in case of generally 171 * deferred cache operations within a transaction) and to reliably 172 * determine prior presence of the given key. 173 * @param key the key whose mapping is to be removed from the cache 174 * @return {@code true} if the cache was known to have a mapping for 175 * this key before, {@code false} if it did not (or if prior presence 176 * could not be determined) 177 * @since 5.2 178 * @see #evict(Object) 179 */ 180 default boolean evictIfPresent(Object key) { 181 evict(key); 182 return false; 183 } 184 185 /** 186 * Clear the cache through removing all mappings. 187 * <p>Actual clearing may be performed in an asynchronous or deferred 188 * fashion, with subsequent lookups possibly still seeing the entries. 189 * This may for example be the case with transactional cache decorators. 190 * Use {@link #invalidate()} for guaranteed immediate removal of entries. 191 * @see #invalidate() 192 */ 193 void clear(); 194 195 /** 196 * Invalidate the cache through removing all mappings, expecting all 197 * entries to be immediately invisible for subsequent lookups. 198 * @return {@code true} if the cache was known to have mappings before, 199 * {@code false} if it did not (or if prior presence of entries could 200 * not be determined) 201 * @since 5.2 202 * @see #clear() 203 */ 204 default boolean invalidate() { 205 clear(); 206 return false; 207 } 208 209 210 /** 211 * A (wrapper) object representing a cache value. 212 */ 213 @FunctionalInterface 214 interface ValueWrapper { 215 216 /** 217 * Return the actual value in the cache. 218 */ 219 @Nullable 220 Object get(); 221 } 222 223 224 /** 225 * Wrapper exception to be thrown from {@link #get(Object, Callable)} 226 * in case of the value loader callback failing with an exception. 227 * @since 4.3 228 */ 229 @SuppressWarnings("serial") 230 class ValueRetrievalException extends RuntimeException { 231 232 @Nullable 233 private final Object key; 234 235 public ValueRetrievalException(@Nullable Object key, Callable<?> loader, Throwable ex) { 236 super(String.format("Value for key '%s' could not be loaded using '%s'", key, loader), ex); 237 this.key = key; 238 } 239 240 @Nullable 241 public Object getKey() { 242 return this.key; 243 } 244 } 245 246}