SpringBoot - @Cacheable、@CacheEvict、@CachePut

Starting from 3.1, Spring introduced support for Cache. Its use method and principle are similar to Spring's support for transaction management. Spring Cache works on methods, and its core idea is this: when we call a cache method, the method parameters and the returned result are stored in the cache as a key-value pair, and the next time we use the same parameters When this method is called, the method will no longer be executed, but the result will be obtained directly from the cache and returned. Therefore, when using Spring Cache, we must ensure that our cached methods have the same return results for the same method parameters.

Using Spring Cache requires us to do two things:

  1. Declare certain methods to use cache
  2. Configure Spring's support for Cache

Like Spring's support for transaction management, Spring's support for Cache is also based on annotations and XML-based configuration. Let's first take a look at the annotation-based approach.

 

Annotation-based support

Spring provides us with several annotations to support Spring Cache. Its core is mainly @Cacheable and @CacheEvict. The methods marked with @Cacheable will cache the returned results after execution, while the methods marked with @CacheEvict will remove some elements in Spring Cache before or after the method is executed. In the following, we will introduce in detail several annotations provided by Spring based on annotations support for Cache.

 

1、@Cacheable

@Cacheable can be marked on a method or a class. When marked on a method, it means that the method supports caching. When marked on a class, it means that all methods in this class support caching. For a method that supports caching, Spring will cache the return value after it is called, to ensure that the next time you use the same parameters to execute the method, you can directly get the results from the cache without having to execute the method again. Spring caches the return value of the method with key-value pairs. The value is the return result of the method. As for the key, Spring supports two strategies, the default strategy and the custom strategy, which will be explained later. It should be noted that when a method that supports caching is called inside the object, the caching function will not be triggered. @Cacheable can specify three attributes, value, key and condition.

1.1 The value attribute specifies the Cache name

The value attribute must be specified, which indicates in which cache the return value of the current method will be cached, corresponding to the name of the cache. It can be one Cache or multiple Caches, it is an array when multiple Caches need to be specified.

@Cacheable("cache1") // Cache是发生在cache1上的
public User find(Integer id) {
  returnnull;
}

@Cacheable({"cache1", "cache2"}) // Cache是发生在cache1和cache2上的
public User find(Integer id) {
  returnnull;
}

1.2 Use the key attribute to customize the key

The key attribute is used to specify the corresponding key when the Spring cache method returns the result. This attribute supports SpringEL expressions. When we do not specify this attribute, Spring will use the default strategy to generate the key. Let's take a look at the custom strategy here, as for the default strategy will be introduced separately later.

Custom strategy means that we can specify our key through Spring's EL expression. Here EL expressions can use method parameters and their corresponding attributes. When using method parameters, we can directly use "#parameter name" or "#pparameter index". Here are a few examples of using parameters as keys.

/**
* key 是指传入时的参数
*
*/

@Cacheable(value="users", key="#id")
public User find(Integer id) {
  return null;
}

// 表示第一个参数
@Cacheable(value="users", key="#p0")
public User find(Integer id) {
  return null;
}

// 表示User中的id值
@Cacheable(value="users", key="#user.id")
public User find(User user) {
  return null;
}

// 表示第一个参数里的id属性值
@Cacheable(value="users", key="#p0.id")
public User find(User user) {
  return null;
}

In addition to using the above method parameters as keys, Spring also provides us with a root object that can be used to generate keys. Through this root object we can obtain the following information.

When we want to use the attribute of the root object as the key, we can also omit "#root", because Spring uses the attribute of the root object by default. Such as:

// key值为: user中的name属性的值
@Cacheable(value={"users", "xxx"}, key="caches[1].name")
public User find(User user) {
  return null;
}

1.3 The condition attribute specifies the condition that occurs

Sometimes we may not want to cache all the results returned by a method. This function can be achieved through the condition attribute. The condition attribute is empty by default, indicating that all invocation situations will be cached. The value is specified by the SpringEL expression. When it is true, it means that the cache processing is performed; when it is false, it means that the cache processing is not performed, that is, the method will be executed once every time the method is called. The following example indicates that the cache is only performed when the user's id is even.

// 根据条件判断是否缓存
@Cacheable(value={"users"}, key="#user.id", condition="#user.id%2==0")
public User find(User user) {
  System.out.println("find user by user " + user);
  return user;
}

 

2 @CachePut

In the environment that supports Spring Cache, for the method marked with @Cacheable, Spring will check whether there is a cache element with the same key in the Cache before each execution. If it exists, the method will not be executed and will be directly obtained from the cache. The result is returned, otherwise it will be executed and the returned result will be stored in the specified cache. @CachePut can also declare a method to support the cache function. The difference with @Cacheable is that the method marked with @CachePut will not check whether there is a previously executed result in the cache before execution, but will execute the method every time and store the execution result in the form of key-value pairs In the specified cache.

// @CachePut也可以标注在类上和方法上。使用@CachePut时我们可以指定的属性跟@Cacheable是一样的。
@CachePut("users") // 每次都会执行方法,并将结果存入指定的缓存中
public User find(Integer id) {
  return null;
}

 

3 @CacheEvict

@CacheEvict is used to mark methods or classes that need to clear cache elements. When marked on a class, it means that the execution of all methods in it will trigger the clear operation of the cache. The attributes that @CacheEvict can specify are value, key, condition, allEntries, and beforeInvocation. The semantics of value, key and condition are similar to the corresponding attributes of @Cacheable. That is, value indicates on which cache the clearing operation occurred (corresponding to the name of the cache); key indicates which key needs to be cleared, if not specified, the key generated by the default strategy will be used; condition indicates the condition where the clearing operation occurs. Let's introduce the two newly appeared attributes allEntries and beforeInvocation.

3.1 allEntries attribute

allEntries is a boolean type, indicating whether all elements in the cache need to be cleared. The default is false, which means no need. When allEntries is specified as true, Spring Cache will ignore the specified key. Sometimes we need to cache to clear all elements, which is more efficient than clearing elements one by one.

@CacheEvict(value="users", allEntries=true)
public void delete(Integer id) {
  System.out.println("delete user by id: " + id);
}

3.2 beforeInvocation attribute

By default, the clear operation is triggered after the corresponding method is successfully executed, that is, if the method fails to return because of throwing an exception, the clear operation will not be triggered. Use beforeInvocation can change the time to trigger the clear operation. When we specify the value of this attribute to be true, Spring will clear the specified element in the cache before calling this method.

@CacheEvict(value="users", beforeInvocation=true)
public void delete(Integer id) {
  System.out.println("delete user by id: " + id);
}

In fact, in addition to using @CacheEvict to clear cache elements, when we use Ehcache as an implementation, we can also configure Ehcache's own expulsion strategy, which is specified through the Ehcache configuration file. Since Ehcache is not the focus of this article, I wo n’t go into details here. For more information about Ehcache, please check my column about Ehcache.

 

4 @Caching

@Caching annotation allows us to specify multiple Spring Cache related annotations on a method or class at the same time. It has three attributes: cacheable, put, and evict, which are used to specify @Cacheable, @CachePut, and @CacheEvict, respectively.

@Caching(cacheable = @Cacheable("users"), evict = { @CacheEvict("cache2"),
@CacheEvict(value = "cache3", allEntries = true) })
public User find(Integer id) {
  return null;
}

 

5 Use custom annotations

Spring allows us to use custom annotations when configuring cacheable methods, provided that the custom annotations must be marked with corresponding annotations. For example, we have the following custom annotation marked with @Cacheable.

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Cacheable(value="users")
public @interface MyCacheable {}

Then using @MyCacheable to label the method we need to cache can also achieve the same effect.

@MyCacheable
public User findById(Integer id) {
  System.out.println("find user by id: " + id);
  User user = new User();
  user.setId(id);
  user.setName("Name" + id);
  return user;
}

Published 952 original articles · praised 1820 · 890,000 views

Guess you like

Origin blog.csdn.net/Dream_Weave/article/details/105415161