Directory
- Objective
- Realize
- Summarize
Objective
As we all know, Encache is now the most popular Java open source cache framework, simple configuration, clear structure, powerful. Annotations @Cacheable
allow you to quickly add method results to the cache. @CacheEvict
you can quickly clear out the specified cache.
However, because @CacheEvict
annotations use Key-value and do not support fuzzy deletion, you will encounter problems. When I @Cacheable
add multiple caches of the same method with the spring El expression, such as:
@GetMapping("/listOfTask/{page}/")@Cacheable(value = "BusinessCache", key = "‘listOfTask_‘+ #page")public ResponseMessage<PageTaskVO> getTaskList(@PathVariable("page") String page) { do something...}
The above code is a paging fetch task information. Use the EL expression to get the page in the parameter and as the cached key, using @Cacheable
the cache added to the Ehcache. At this point, it will appear in the cache, listOfTask_1
listOfTask_2
listOfTask_3
This type of key.
When you add or delete a task, the list changes. At this point, you need to listOfTask_*
remove all the relevant caches. At this point, I do not know exactly how much cache and listOfTask_*
related content, it is not possible to call to @CacheEvict
Delete.
Since Ehcache cannot support itself, it can only be done by ourselves.
Realize
Taking into account the added cache of annotations used, the removal of the cache also uses annotation processing, which preserves development consistency. Annotations are also very friendly to developers. Then we'll consider using custom annotations to blur the bulk of the cache removal.
First, define the annotations CacheRemove
:
@Target({ java.lang.annotation.ElementType.METHOD })@Retention(RetentionPolicy.RUNTIME)public @interface CacheRemove { String value(); String[] key();}
Where value is the same as Ehcache for defining the cache name to operate on. Key is an array that holds regular expressions for multiple cache keys. The name is CacheRemove
clearly understandable and does not conflict with the annotations of Ehcache itself. The definition of the annotation ends here. Next, we need to deal with annotations, because the use of the spring framework, it is natural to think of AOP to do the specific implementation of annotations.
The purpose of the annotations is to bulk blur the cache removal. The following two questions need to be considered:
- How to use fuzzy matching
- How to delete key in bulk
The way I deal with it, and I think the simplest way to handle it is:
- In what way fuzzy matching--
CacheRemove
the key in the regular, you can pass multiple, using regular matching
- How to bulk delete key--loop all key, find match regular to delete
First define the class name CacheRemoveAspect
:
@Aspect@Componentpublic class CacheRemoveAspect { @Pointcut(value = "(execution(* *.*(..)) && @annotation(com.example.CacheRemove))") private void pointcut() {} do something...}
Defining a tangent point in a slice, using execution(* *.*(..) && @annotation(com.example.CacheRemove))
the means that all annotated classes CacheRemove
are executed, @annotation
is the fully qualified name of the annotation.
The pointcut definition is complete, and the following plays are the concrete implementations of the facets. Generally, the cache will not be removed until the method of adding and removing changes is executed. So use @AfterReturning()
to implement. Here are a few things to do in a specific implementation:
- Annotations on interception methods
- Judging the annotation is not
CacheRemove
- Since the note passed in the key is a number of groups, the loop processes each key
- Compile each key in the loop as pattern, and loop through all the caches to remove the matching cache
The specific implementation is as follows:
@AfterReturning(value = "pointcut()")private void process(JoinPoint joinPoint){ MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); CacheRemove cacheRemove = method.getAnnotation(CacheRemove.class); if (cacheRemove != null){ String value = cacheRemove.value(); String[] keys = cacheRemove.key(); //需要移除的正则key List cacheKeys = CacheUtils.cacheKeys(value); for (String key : keys){ Pattern pattern = Pattern.compile(key); for (Object cacheKey: cacheKeys) { String cacheKeyStr = String.valueOf(cacheKey); if (pattern.matcher(cacheKeyStr).find()){ CacheUtils.remove(value, cacheKeyStr); } } } }}
Above, the specific implementation of Ehcache fuzzy batch removal cache. Where Businesscacheutils is the Ehcache tool class for its own encapsulation. The main implementation is to get the cache pool, get the cache, remove the cache, add the cache, and view all the normal functions such as caching. The code is as follows:
public class Cacheutils {private static CacheManager CacheManager = Springcontextholder.getbean ("Ehcachemanagerfactory "); public static Object Get (string cachename, string key) {element element = GetCache (cachename). get (key); return element = = null? Null:element.getObjectValue (); } public static void put (string cachename, String key, Object value) {element element = new Element (key, value) ; GetCache (CacheName). put (element); } public static void Remove (string cachename, String key) {GetCache (cachename). Remove (key); public static List Cachekeys (String cachename) {return GetCache (cachename). Getkeys (); }/** * Get a cache, no then create one. * @param cachename * @return */private static cache GetCache (String cachename) {Cache cache = Cacheman Ager.getcache (CacheName); if (cache = = null) {Cachemanager.addcache (cachename); Cache = Cachemanager.getcache (cachename); Cache.getcacheconfiguration (). Seteternal (True); } return cache; } public static CacheManager Getcachemanager () {return cachemanager; }}
At this point, the entire Ehcache fuzzy batch removal cache function is implemented.
Summarize
The whole process of thinking simple, with some knowledge of AOP to complete the required functions. However, the specific removal of some of the code can be considered for optimization. With all the loops of a single cache, remove the cache that needs to be removed, instead of having a few keys to do this now, and go through the cache a few times. The specific implementation is left to the reader to complete. I hope to be of some help to you.
Ehcache Fuzzy Batch removal cache