1616
1717package org .springframework .cache .guava ;
1818
19- import java .io .Serializable ;
2019import java .util .concurrent .Callable ;
2120import java .util .concurrent .ExecutionException ;
2221
2322import com .google .common .cache .LoadingCache ;
2423import com .google .common .util .concurrent .UncheckedExecutionException ;
2524
26- import org .springframework .cache .Cache ;
27- import org .springframework .cache .support .SimpleValueWrapper ;
25+ import org .springframework .cache .support .AbstractValueAdaptingCache ;
2826import org .springframework .util .Assert ;
2927
3028/**
31- * Spring {@link Cache} adapter implementation on top of a
32- * Guava {@link com.google.common.cache.Cache} instance.
29+ * Spring {@link org.springframework.cache. Cache} adapter implementation
30+ * on top of a Guava {@link com.google.common.cache.Cache} instance.
3331 *
3432 * <p>Requires Google Guava 12.0 or higher.
3533 *
3634 * @author Juergen Hoeller
3735 * @author Stephane Nicoll
3836 * @since 4.0
3937 */
40- public class GuavaCache implements Cache {
41-
42- private static final Object NULL_HOLDER = new NullHolder ();
38+ public class GuavaCache extends AbstractValueAdaptingCache {
4339
4440 private final String name ;
4541
4642 private final com .google .common .cache .Cache <Object , Object > cache ;
4743
48- private final boolean allowNullValues ;
49-
5044
5145 /**
5246 * Create a {@link GuavaCache} instance with the specified name and the
@@ -67,11 +61,11 @@ public GuavaCache(String name, com.google.common.cache.Cache<Object, Object> cac
6761 * values for this cache
6862 */
6963 public GuavaCache (String name , com .google .common .cache .Cache <Object , Object > cache , boolean allowNullValues ) {
64+ super (allowNullValues );
7065 Assert .notNull (name , "Name must not be null" );
7166 Assert .notNull (cache , "Cache must not be null" );
7267 this .name = name ;
7368 this .cache = cache ;
74- this .allowNullValues = allowNullValues ;
7569 }
7670
7771
@@ -85,32 +79,23 @@ public final com.google.common.cache.Cache<Object, Object> getNativeCache() {
8579 return this .cache ;
8680 }
8781
88- public final boolean isAllowNullValues () {
89- return this .allowNullValues ;
90- }
91-
9282 @ Override
9383 public ValueWrapper get (Object key ) {
9484 if (this .cache instanceof LoadingCache ) {
9585 try {
9686 Object value = ((LoadingCache <Object , Object >) this .cache ).get (key );
97- return toWrapper (value );
87+ return toValueWrapper (value );
9888 }
9989 catch (ExecutionException ex ) {
10090 throw new UncheckedExecutionException (ex .getMessage (), ex );
10191 }
10292 }
103- return toWrapper ( this . cache . getIfPresent (key ) );
93+ return super . get (key );
10494 }
10595
10696 @ Override
107- @ SuppressWarnings ("unchecked" )
108- public <T > T get (Object key , Class <T > type ) {
109- Object value = fromStoreValue (this .cache .getIfPresent (key ));
110- if (value != null && type != null && !type .isInstance (value )) {
111- throw new IllegalStateException ("Cached value is not of required type [" + type .getName () + "]: " + value );
112- }
113- return (T ) value ;
97+ protected Object lookup (Object key ) {
98+ return this .cache .getIfPresent (key );
11499 }
115100
116101 @ Override
@@ -123,7 +108,7 @@ public ValueWrapper putIfAbsent(Object key, final Object value) {
123108 try {
124109 PutIfAbsentCallable callable = new PutIfAbsentCallable (value );
125110 Object result = this .cache .get (key , callable );
126- return (callable .called ? null : toWrapper (result ));
111+ return (callable .called ? null : toValueWrapper (result ));
127112 }
128113 catch (ExecutionException ex ) {
129114 throw new IllegalStateException (ex );
@@ -141,42 +126,6 @@ public void clear() {
141126 }
142127
143128
144- /**
145- * Convert the given value from the internal store to a user value
146- * returned from the get method (adapting {@code null}).
147- * @param storeValue the store value
148- * @return the value to return to the user
149- */
150- protected Object fromStoreValue (Object storeValue ) {
151- if (this .allowNullValues && storeValue == NULL_HOLDER ) {
152- return null ;
153- }
154- return storeValue ;
155- }
156-
157- /**
158- * Convert the given user value, as passed into the put method,
159- * to a value in the internal store (adapting {@code null}).
160- * @param userValue the given user value
161- * @return the value to store
162- */
163- protected Object toStoreValue (Object userValue ) {
164- if (this .allowNullValues && userValue == null ) {
165- return NULL_HOLDER ;
166- }
167- return userValue ;
168- }
169-
170- private ValueWrapper toWrapper (Object value ) {
171- return (value != null ? new SimpleValueWrapper (fromStoreValue (value )) : null );
172- }
173-
174-
175- @ SuppressWarnings ("serial" )
176- private static class NullHolder implements Serializable {
177- }
178-
179-
180129 private class PutIfAbsentCallable implements Callable <Object > {
181130
182131 private final Object value ;
0 commit comments