2222import java .lang .reflect .Method ;
2323import java .util .ArrayList ;
2424import java .util .Collection ;
25+ import java .util .LinkedHashSet ;
26+ import java .util .Set ;
2527
2628import org .springframework .cache .interceptor .CacheEvictOperation ;
2729import org .springframework .cache .interceptor .CacheOperation ;
2830import org .springframework .cache .interceptor .CachePutOperation ;
2931import org .springframework .cache .interceptor .CacheableOperation ;
3032import org .springframework .core .annotation .AnnotatedElementUtils ;
3133import org .springframework .lang .Nullable ;
32- import org .springframework .util .ObjectUtils ;
3334import org .springframework .util .StringUtils ;
3435
3536/**
4748@ SuppressWarnings ("serial" )
4849public class SpringCacheAnnotationParser implements CacheAnnotationParser , Serializable {
4950
51+ private static final Set <Class <? extends Annotation >> CACHE_OPERATION_ANNOTATIONS = new LinkedHashSet <>(8 );
52+
53+ static {
54+ CACHE_OPERATION_ANNOTATIONS .add (Cacheable .class );
55+ CACHE_OPERATION_ANNOTATIONS .add (CacheEvict .class );
56+ CACHE_OPERATION_ANNOTATIONS .add (CachePut .class );
57+ CACHE_OPERATION_ANNOTATIONS .add (Caching .class );
58+ }
59+
60+
5061 @ Override
5162 @ Nullable
5263 public Collection <CacheOperation > parseCacheAnnotations (Class <?> type ) {
53- DefaultCacheConfig defaultConfig = getDefaultCacheConfig (type );
64+ DefaultCacheConfig defaultConfig = new DefaultCacheConfig (type );
5465 return parseCacheAnnotations (defaultConfig , type );
5566 }
5667
5768 @ Override
5869 @ Nullable
5970 public Collection <CacheOperation > parseCacheAnnotations (Method method ) {
60- DefaultCacheConfig defaultConfig = getDefaultCacheConfig (method .getDeclaringClass ());
71+ DefaultCacheConfig defaultConfig = new DefaultCacheConfig (method .getDeclaringClass ());
6172 return parseCacheAnnotations (defaultConfig , method );
6273 }
6374
6475 @ Nullable
6576 private Collection <CacheOperation > parseCacheAnnotations (DefaultCacheConfig cachingConfig , AnnotatedElement ae ) {
6677 Collection <CacheOperation > ops = parseCacheAnnotations (cachingConfig , ae , false );
67- if (ops != null && ops .size () > 1 && ae . getAnnotations (). length > 0 ) {
78+ if (ops != null && ops .size () > 1 ) {
6879 // More than one operation found -> local declarations override interface-declared ones...
6980 Collection <CacheOperation > localOps = parseCacheAnnotations (cachingConfig , ae , true );
7081 if (localOps != null ) {
@@ -78,55 +89,28 @@ private Collection<CacheOperation> parseCacheAnnotations(DefaultCacheConfig cach
7889 private Collection <CacheOperation > parseCacheAnnotations (
7990 DefaultCacheConfig cachingConfig , AnnotatedElement ae , boolean localOnly ) {
8091
81- Collection <CacheOperation > ops = null ;
82-
83- Collection <Cacheable > cacheables = (localOnly ? AnnotatedElementUtils .getAllMergedAnnotations (ae , Cacheable .class ) :
84- AnnotatedElementUtils .findAllMergedAnnotations (ae , Cacheable .class ));
85- if (!cacheables .isEmpty ()) {
86- ops = lazyInit (null );
87- for (Cacheable cacheable : cacheables ) {
88- ops .add (parseCacheableAnnotation (ae , cachingConfig , cacheable ));
89- }
90- }
91-
92- Collection <CacheEvict > evicts = (localOnly ? AnnotatedElementUtils .getAllMergedAnnotations (ae , CacheEvict .class ) :
93- AnnotatedElementUtils .findAllMergedAnnotations (ae , CacheEvict .class ));
94- if (!evicts .isEmpty ()) {
95- ops = lazyInit (ops );
96- for (CacheEvict evict : evicts ) {
97- ops .add (parseEvictAnnotation (ae , cachingConfig , evict ));
98- }
99- }
100-
101- Collection <CachePut > puts = (localOnly ? AnnotatedElementUtils .getAllMergedAnnotations (ae , CachePut .class ) :
102- AnnotatedElementUtils .findAllMergedAnnotations (ae , CachePut .class ));
103- if (!puts .isEmpty ()) {
104- ops = lazyInit (ops );
105- for (CachePut put : puts ) {
106- ops .add (parsePutAnnotation (ae , cachingConfig , put ));
107- }
108- }
109-
110- Collection <Caching > cachings = (localOnly ? AnnotatedElementUtils .getAllMergedAnnotations (ae , Caching .class ) :
111- AnnotatedElementUtils .findAllMergedAnnotations (ae , Caching .class ));
112- if (!cachings .isEmpty ()) {
113- ops = lazyInit (ops );
114- for (Caching caching : cachings ) {
115- Collection <CacheOperation > cachingOps = parseCachingAnnotation (ae , cachingConfig , caching );
116- if (cachingOps != null ) {
117- ops .addAll (cachingOps );
118- }
119- }
92+ Collection <? extends Annotation > anns = (localOnly ?
93+ AnnotatedElementUtils .getAllMergedAnnotations (ae , CACHE_OPERATION_ANNOTATIONS ) :
94+ AnnotatedElementUtils .findAllMergedAnnotations (ae , CACHE_OPERATION_ANNOTATIONS ));
95+ if (anns .isEmpty ()) {
96+ return null ;
12097 }
12198
99+ final Collection <CacheOperation > ops = new ArrayList <>(1 );
100+ anns .stream ().filter (ann -> ann instanceof Cacheable ).forEach (
101+ ann -> ops .add (parseCacheableAnnotation (ae , cachingConfig , (Cacheable ) ann )));
102+ anns .stream ().filter (ann -> ann instanceof CacheEvict ).forEach (
103+ ann -> ops .add (parseEvictAnnotation (ae , cachingConfig , (CacheEvict ) ann )));
104+ anns .stream ().filter (ann -> ann instanceof CachePut ).forEach (
105+ ann -> ops .add (parsePutAnnotation (ae , cachingConfig , (CachePut ) ann )));
106+ anns .stream ().filter (ann -> ann instanceof Caching ).forEach (
107+ ann -> parseCachingAnnotation (ae , cachingConfig , (Caching ) ann , ops ));
122108 return ops ;
123109 }
124110
125- private <T extends Annotation > Collection <CacheOperation > lazyInit (@ Nullable Collection <CacheOperation > ops ) {
126- return (ops != null ? ops : new ArrayList <>(1 ));
127- }
111+ private CacheableOperation parseCacheableAnnotation (
112+ AnnotatedElement ae , DefaultCacheConfig defaultConfig , Cacheable cacheable ) {
128113
129- CacheableOperation parseCacheableAnnotation (AnnotatedElement ae , DefaultCacheConfig defaultConfig , Cacheable cacheable ) {
130114 CacheableOperation .Builder builder = new CacheableOperation .Builder ();
131115
132116 builder .setName (ae .toString ());
@@ -146,7 +130,9 @@ CacheableOperation parseCacheableAnnotation(AnnotatedElement ae, DefaultCacheCon
146130 return op ;
147131 }
148132
149- CacheEvictOperation parseEvictAnnotation (AnnotatedElement ae , DefaultCacheConfig defaultConfig , CacheEvict cacheEvict ) {
133+ private CacheEvictOperation parseEvictAnnotation (
134+ AnnotatedElement ae , DefaultCacheConfig defaultConfig , CacheEvict cacheEvict ) {
135+
150136 CacheEvictOperation .Builder builder = new CacheEvictOperation .Builder ();
151137
152138 builder .setName (ae .toString ());
@@ -166,7 +152,9 @@ CacheEvictOperation parseEvictAnnotation(AnnotatedElement ae, DefaultCacheConfig
166152 return op ;
167153 }
168154
169- CacheOperation parsePutAnnotation (AnnotatedElement ae , DefaultCacheConfig defaultConfig , CachePut cachePut ) {
155+ private CacheOperation parsePutAnnotation (
156+ AnnotatedElement ae , DefaultCacheConfig defaultConfig , CachePut cachePut ) {
157+
170158 CachePutOperation .Builder builder = new CachePutOperation .Builder ();
171159
172160 builder .setName (ae .toString ());
@@ -185,48 +173,23 @@ CacheOperation parsePutAnnotation(AnnotatedElement ae, DefaultCacheConfig defaul
185173 return op ;
186174 }
187175
188- @ Nullable
189- Collection <CacheOperation > parseCachingAnnotation (AnnotatedElement ae , DefaultCacheConfig defaultConfig , Caching caching ) {
190- Collection <CacheOperation > ops = null ;
176+ private void parseCachingAnnotation (
177+ AnnotatedElement ae , DefaultCacheConfig defaultConfig , Caching caching , Collection <CacheOperation > ops ) {
191178
192179 Cacheable [] cacheables = caching .cacheable ();
193- if (!ObjectUtils .isEmpty (cacheables )) {
194- ops = lazyInit (null );
195- for (Cacheable cacheable : cacheables ) {
196- ops .add (parseCacheableAnnotation (ae , defaultConfig , cacheable ));
197- }
180+ for (Cacheable cacheable : cacheables ) {
181+ ops .add (parseCacheableAnnotation (ae , defaultConfig , cacheable ));
198182 }
199183 CacheEvict [] cacheEvicts = caching .evict ();
200- if (!ObjectUtils .isEmpty (cacheEvicts )) {
201- ops = lazyInit (ops );
202- for (CacheEvict cacheEvict : cacheEvicts ) {
203- ops .add (parseEvictAnnotation (ae , defaultConfig , cacheEvict ));
204- }
184+ for (CacheEvict cacheEvict : cacheEvicts ) {
185+ ops .add (parseEvictAnnotation (ae , defaultConfig , cacheEvict ));
205186 }
206187 CachePut [] cachePuts = caching .put ();
207- if (!ObjectUtils .isEmpty (cachePuts )) {
208- ops = lazyInit (ops );
209- for (CachePut cachePut : cachePuts ) {
210- ops .add (parsePutAnnotation (ae , defaultConfig , cachePut ));
211- }
188+ for (CachePut cachePut : cachePuts ) {
189+ ops .add (parsePutAnnotation (ae , defaultConfig , cachePut ));
212190 }
213-
214- return ops ;
215191 }
216192
217- /**
218- * Provides the {@link DefaultCacheConfig} instance for the specified {@link Class}.
219- * @param target the class-level to handle
220- * @return the default config (never {@code null})
221- */
222- DefaultCacheConfig getDefaultCacheConfig (Class <?> target ) {
223- CacheConfig annotation = AnnotatedElementUtils .findMergedAnnotation (target , CacheConfig .class );
224- if (annotation != null ) {
225- return new DefaultCacheConfig (annotation .cacheNames (), annotation .keyGenerator (),
226- annotation .cacheManager (), annotation .cacheResolver ());
227- }
228- return new DefaultCacheConfig ();
229- }
230193
231194 /**
232195 * Validates the specified {@link CacheOperation}.
@@ -266,38 +229,44 @@ public int hashCode() {
266229 /**
267230 * Provides default settings for a given set of cache operations.
268231 */
269- static class DefaultCacheConfig {
232+ private static class DefaultCacheConfig {
270233
271- @ Nullable
272- private final String [] cacheNames ;
234+ private final Class <?> target ;
273235
274236 @ Nullable
275- private final String keyGenerator ;
237+ private String [] cacheNames ;
276238
277239 @ Nullable
278- private final String cacheManager ;
240+ private String keyGenerator ;
279241
280242 @ Nullable
281- private final String cacheResolver ;
243+ private String cacheManager ;
282244
283- public DefaultCacheConfig () {
284- this (null , null , null , null );
285- }
245+ @ Nullable
246+ private String cacheResolver ;
286247
287- private DefaultCacheConfig (@ Nullable String [] cacheNames , @ Nullable String keyGenerator ,
288- @ Nullable String cacheManager , @ Nullable String cacheResolver ) {
248+ private boolean initialized = false ;
289249
290- this .cacheNames = cacheNames ;
291- this .keyGenerator = keyGenerator ;
292- this .cacheManager = cacheManager ;
293- this .cacheResolver = cacheResolver ;
250+ public DefaultCacheConfig (Class <?> target ) {
251+ this .target = target ;
294252 }
295253
296254 /**
297255 * Apply the defaults to the specified {@link CacheOperation.Builder}.
298256 * @param builder the operation builder to update
299257 */
300258 public void applyDefault (CacheOperation .Builder builder ) {
259+ if (!this .initialized ) {
260+ CacheConfig annotation = AnnotatedElementUtils .findMergedAnnotation (this .target , CacheConfig .class );
261+ if (annotation != null ) {
262+ this .cacheNames = annotation .cacheNames ();
263+ this .keyGenerator = annotation .keyGenerator ();
264+ this .cacheManager = annotation .cacheManager ();
265+ this .cacheResolver = annotation .cacheResolver ();
266+ }
267+ this .initialized = true ;
268+ }
269+
301270 if (builder .getCacheNames ().isEmpty () && this .cacheNames != null ) {
302271 builder .setCacheNames (this .cacheNames );
303272 }
0 commit comments