22
22
import java .lang .reflect .Method ;
23
23
import java .util .ArrayList ;
24
24
import java .util .Collection ;
25
+ import java .util .LinkedHashSet ;
26
+ import java .util .Set ;
25
27
26
28
import org .springframework .cache .interceptor .CacheEvictOperation ;
27
29
import org .springframework .cache .interceptor .CacheOperation ;
28
30
import org .springframework .cache .interceptor .CachePutOperation ;
29
31
import org .springframework .cache .interceptor .CacheableOperation ;
30
32
import org .springframework .core .annotation .AnnotatedElementUtils ;
31
33
import org .springframework .lang .Nullable ;
32
- import org .springframework .util .ObjectUtils ;
33
34
import org .springframework .util .StringUtils ;
34
35
35
36
/**
47
48
@ SuppressWarnings ("serial" )
48
49
public class SpringCacheAnnotationParser implements CacheAnnotationParser , Serializable {
49
50
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
+
50
61
@ Override
51
62
@ Nullable
52
63
public Collection <CacheOperation > parseCacheAnnotations (Class <?> type ) {
53
- DefaultCacheConfig defaultConfig = getDefaultCacheConfig (type );
64
+ DefaultCacheConfig defaultConfig = new DefaultCacheConfig (type );
54
65
return parseCacheAnnotations (defaultConfig , type );
55
66
}
56
67
57
68
@ Override
58
69
@ Nullable
59
70
public Collection <CacheOperation > parseCacheAnnotations (Method method ) {
60
- DefaultCacheConfig defaultConfig = getDefaultCacheConfig (method .getDeclaringClass ());
71
+ DefaultCacheConfig defaultConfig = new DefaultCacheConfig (method .getDeclaringClass ());
61
72
return parseCacheAnnotations (defaultConfig , method );
62
73
}
63
74
64
75
@ Nullable
65
76
private Collection <CacheOperation > parseCacheAnnotations (DefaultCacheConfig cachingConfig , AnnotatedElement ae ) {
66
77
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 ) {
68
79
// More than one operation found -> local declarations override interface-declared ones...
69
80
Collection <CacheOperation > localOps = parseCacheAnnotations (cachingConfig , ae , true );
70
81
if (localOps != null ) {
@@ -78,55 +89,28 @@ private Collection<CacheOperation> parseCacheAnnotations(DefaultCacheConfig cach
78
89
private Collection <CacheOperation > parseCacheAnnotations (
79
90
DefaultCacheConfig cachingConfig , AnnotatedElement ae , boolean localOnly ) {
80
91
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 ;
120
97
}
121
98
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 ));
122
108
return ops ;
123
109
}
124
110
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 ) {
128
113
129
- CacheableOperation parseCacheableAnnotation (AnnotatedElement ae , DefaultCacheConfig defaultConfig , Cacheable cacheable ) {
130
114
CacheableOperation .Builder builder = new CacheableOperation .Builder ();
131
115
132
116
builder .setName (ae .toString ());
@@ -146,7 +130,9 @@ CacheableOperation parseCacheableAnnotation(AnnotatedElement ae, DefaultCacheCon
146
130
return op ;
147
131
}
148
132
149
- CacheEvictOperation parseEvictAnnotation (AnnotatedElement ae , DefaultCacheConfig defaultConfig , CacheEvict cacheEvict ) {
133
+ private CacheEvictOperation parseEvictAnnotation (
134
+ AnnotatedElement ae , DefaultCacheConfig defaultConfig , CacheEvict cacheEvict ) {
135
+
150
136
CacheEvictOperation .Builder builder = new CacheEvictOperation .Builder ();
151
137
152
138
builder .setName (ae .toString ());
@@ -166,7 +152,9 @@ CacheEvictOperation parseEvictAnnotation(AnnotatedElement ae, DefaultCacheConfig
166
152
return op ;
167
153
}
168
154
169
- CacheOperation parsePutAnnotation (AnnotatedElement ae , DefaultCacheConfig defaultConfig , CachePut cachePut ) {
155
+ private CacheOperation parsePutAnnotation (
156
+ AnnotatedElement ae , DefaultCacheConfig defaultConfig , CachePut cachePut ) {
157
+
170
158
CachePutOperation .Builder builder = new CachePutOperation .Builder ();
171
159
172
160
builder .setName (ae .toString ());
@@ -185,48 +173,23 @@ CacheOperation parsePutAnnotation(AnnotatedElement ae, DefaultCacheConfig defaul
185
173
return op ;
186
174
}
187
175
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 ) {
191
178
192
179
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 ));
198
182
}
199
183
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 ));
205
186
}
206
187
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 ));
212
190
}
213
-
214
- return ops ;
215
191
}
216
192
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
- }
230
193
231
194
/**
232
195
* Validates the specified {@link CacheOperation}.
@@ -266,38 +229,44 @@ public int hashCode() {
266
229
/**
267
230
* Provides default settings for a given set of cache operations.
268
231
*/
269
- static class DefaultCacheConfig {
232
+ private static class DefaultCacheConfig {
270
233
271
- @ Nullable
272
- private final String [] cacheNames ;
234
+ private final Class <?> target ;
273
235
274
236
@ Nullable
275
- private final String keyGenerator ;
237
+ private String [] cacheNames ;
276
238
277
239
@ Nullable
278
- private final String cacheManager ;
240
+ private String keyGenerator ;
279
241
280
242
@ Nullable
281
- private final String cacheResolver ;
243
+ private String cacheManager ;
282
244
283
- public DefaultCacheConfig () {
284
- this (null , null , null , null );
285
- }
245
+ @ Nullable
246
+ private String cacheResolver ;
286
247
287
- private DefaultCacheConfig (@ Nullable String [] cacheNames , @ Nullable String keyGenerator ,
288
- @ Nullable String cacheManager , @ Nullable String cacheResolver ) {
248
+ private boolean initialized = false ;
289
249
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 ;
294
252
}
295
253
296
254
/**
297
255
* Apply the defaults to the specified {@link CacheOperation.Builder}.
298
256
* @param builder the operation builder to update
299
257
*/
300
258
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
+
301
270
if (builder .getCacheNames ().isEmpty () && this .cacheNames != null ) {
302
271
builder .setCacheNames (this .cacheNames );
303
272
}
0 commit comments