法上的注解,并解析出来。
首先看到 org.springframework.cache.annotation.SpringCacheAnnotationParser 类:
protected Collection<CacheOperation> parseCacheAnnotations(DefaultCacheConfig cachingConfig, AnnotatedElement ae) {
Collection<CacheOperation> ops = null;
Collection<Cacheable> cacheables = AnnotatedElementUtils.getAllMergedAnnotations(ae, Cacheable.class);
if (!cacheables.isEmpty()) {
ops = lazyInit(ops);
for (Cacheable cacheable : cacheables) {
ops.add(parseCacheableAnnotation(ae, cachingConfig, cacheable));
}
}
Collection<CacheEvict> evicts = AnnotatedElementUtils.getAllMergedAnnotations(ae, CacheEvict.class);
if (!evicts.isEmpty()) {
ops = lazyInit(ops);
for (CacheEvict evict : evicts) {
ops.add(parseEvictAnnotation(ae, cachingConfig, evict));
}
}
Collection<CachePut> puts = AnnotatedElementUtils.getAllMergedAnnotations(ae, CachePut.class);
if (!puts.isEmpty()) {
ops = lazyInit(ops);
for (CachePut put : puts) {
ops.add(parsePutAnnotation(ae, cachingConfig, put));
}
}
Collection<Caching> cachings = AnnotatedElementUtils.getAllMergedAnnotations(ae, Caching.class);
if (!cachings.isEmpty()) {
ops = lazyInit(ops);
for (Caching caching : cachings) {
Collection<CacheOperation> cachingOps = parseCachingAnnotation(ae, cachingConfig, caching);
if (cachingOps != null) {
ops.addAll(cachingOps);
}
}
}
return ops;
}
这个方法会解析 Cacheable、CacheEvict、CachePut 和 Caching 4个注解,找到方法上的这4个注解后,会将注解中的参数解析出来,作为后续注解生效的一个依据。这里举例说一下 CacheEvict 注解。
CacheEvictOperation parseEvictAnnotation(AnnotatedElement ae, DefaultCacheConfig defaultConfig, CacheEvict cacheEvict) {
CacheEvictOperation.Builder builder = new CacheEvictOperation.Builder();
builder.setName(ae.toString());
builder.setCacheNames(cacheEvict.cacheNames());
builder.setCondition(cacheEvict.condition());
builder.setKey(cacheEvict.key());
builder.setKeyGenerator(cacheEvict.keyGenerator());
builder.setCacheManager(cacheEvict.cacheManager());
builder.setCacheResolver(cacheEvict.cacheResolver());
builder.setCacheWide(cacheEvict.allEntries());
builder.setBeforeInvocation(cacheEvict.beforeInvocation());
defaultConfig.applyDefault(builder);
CacheEvictOperation op = builder.build();
validateCacheOperation(ae, op);
return op;
}
CacheEvict 注解是用于缓存失效。这里代码会根据 CacheEvict 的配置生产一个 CacheEvictOperation 的类,注解上的 name、key、cacheManager 和 beforeInvocation 等都会传递进来。
另外需要将一下 Caching 注解,这个注解通过 parseCachingAnnotation 方法解析参数,会拆分成 Cacheable、CacheEvict、CachePut 注解,也就对应我们缓存中的增加、失效和更新操作。
Collection<CacheOperation> parseCachingAnnotation(AnnotatedElement ae, DefaultCacheConfig defaultConfig, Caching caching) {
Collection<CacheOperation> ops = null;
Cacheable[] cacheables = caching.cacheable();
if (!ObjectUtils.isEmpty(cacheables)) {
ops = lazyInit(ops);
for (Cacheable cacheable : cacheables) {
ops.add(parseCacheableAnnotation(ae, defaultConfig, cacheable));
}
}
CacheEvict[] cacheEvicts = caching.evict();
if (!ObjectUtils.isEmpty(cacheEvicts)) {
ops = lazyInit(ops);
for (CacheEvict cacheEvict : cac