[SpringCache] Detailed explanation of SpringCache and its use, Redis control expiration time

1. Use

In Spring, using caching typically involves the following steps:

1. Add cache dependencies : Make sure cache-related dependencies are added to the project. If you use Maven, you can add the Spring Cache dependency in the project's pom.xml file.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

2. Configure the cache : Perform basic configuration of the cache in the Spring configuration file. If you are using Spring Boot, there is usually no need for additional configuration because Spring Boot provides default cache configuration.

Step 1: Add annotation @EnableCaching to the startup class
Step 2: Add annotations [@CachePut, @CacheEvict, @Caching] to specific methods or add @Cacheable annotations to methods: Use @Cacheable on methods that require caching Annotation, specify cache name, key and other information.

3. Trigger cache : When calling a method with @Cacheable annotation, Spring will check whether the corresponding result is already in the cache. If there is, the cached result is returned directly; if not, the method body is executed, the result is calculated and the result is cached.

2. Detailed explanation

1、@Cacheable

@Cacheable is an annotation in the Spring Framework that is used to declare that the results of a method should be cached so that the cached results can be returned directly in subsequent calls without the need to execute the method body again. This annotation is often used to improve the execution efficiency of methods, especially those that are computationally expensive.

Basic usage

import org.springframework.cache.annotation.Cacheable;

public class MyService {
    
    

    @Cacheable(value = "myCache", key = "#input")
    public String getResult(String input) {
    
    
        // 如果缓存中存在以input为key的结果,则直接返回缓存结果
        // 否则,执行方法体,并将结果缓存起来
        // ...
    }
}

In the above example:

The @Cacheable annotation is marked on the getResult method, indicating that the results of this method will be cached.
The value attribute specifies the name of the cache (there can be multiple caches, each with a name).
The key attribute specifies the cache key. SpEL (Spring Expression Language) expression is used here, which means that the value of the input parameter is used as the cache key. Sometimes it is written as follows:

@Cacheable(value = "myCache", key = "#p0+','+#p1")

key = "#p0+','+#p1" : Specifies the cache key, using the Spring Expression Language (SpEL) syntax. #p0 represents the first parameter of the method, #p1 represents the second parameter of the method. In this example, the key is formed by comma concatenating the first parameter and the second parameter. This means that if the two parameters have the same value when the method is called twice, they will share the same cached result. If you want to modify the cache value every time you call a method, you can use other splicing characters, such as dashes, spaces, colons, or use the method name as part of the key value.

key = "#p0 + '_' + #p1"  // 使用下划线

key = "#p0 + ',' + #p1 + ',' + #p2"  // 添加额外的参数或常量

key = "methodName + ',' + #p0 + ',' + #p1"  //使用方法名作为一部分

Precautions:

The @Cacheable annotation needs to take effect in the Spring environment, so the cache function usually needs to be enabled in the Spring configuration file.
The return value type of the method should be serializable so that it can be stored in the cache.
The cache key is generated based on the key attribute, so ensure that it uniquely identifies the method's input parameters.
@Cacheable is part of the Spring Cache abstraction, and the specific cache implementation can be based on different backends, such as memory-based, Redis, Ehcache, etc.
We often use it together with the @SqlQuery annotation. If a method uses both the @Cacheable annotation and the @SqlQuery annotation, the execution process is usually as follows:

  • First call: When the method is called for the first time, Spring will first check the cache (
    managed by the @Cacheable annotation). If the corresponding result exists in the cache, it is retrieved directly from the cache and returned without executing the actual SQL query.

  • Cache miss: If the corresponding result does not exist in the cache, the method body will be executed. In the method body, a SQL query (
    managed by the @SqlQuery annotation) may be executed and the query results mapped to the method's return type.

  • Result caching: If the @Cacheable annotation is enabled
    , after the method is executed, the calculated results will be cached so that the next time the same method is called, it can be obtained directly from the cache.

Therefore, the actual SQL query may not be executed if the corresponding result is already in the cache. This can effectively reduce the pressure on database access and improve the execution efficiency of the method. When using these two annotations, ensure that cache keys and SQL query parameters do not cause confusion so that the cache can be correctly identified and managed.

2、@CacheEvict

@CacheEvict is an annotation in the Spring framework used to clear cache. It is used to mark a method that will clear the data in the specified cache when the method is executed. The following are the main properties and usage of the @CacheEvict annotation:

Main attributes:
value (or cacheNames) : Specifies the names of caches to clear, which can be an array of strings. For example: @CacheEvict(value = “myCache”) or @CacheEvict(cacheNames = {“cache1”, “cache2”}).

key : Specifies the SpEL expression used to generate the cache key. For example:@CacheEvict(value = "myCache", key = "#userI

condition : Specifies the condition for clearing the cache, which is a SpEL expression. If the value of the expression is false, the cache will not be cleared. For example:@CacheEvict(value = "myCache", condition = "#userId > 0")。

allEntries : If set to true, all entries in the specified cache will be cleared. For example: @CacheEvict(value = "myCache", allEntries = true).

beforeInvocation : If set to true, the cache is cleared before the method is called; if set to false (default), the cache is cleared after the method is called. For example: @CacheEvict(value = "myCache", beforeInvocation = true).

Example usage:

@Service
public class MyService {
    
    

    @CacheEvict(value = "myCache", key = "#userId")
    public void clearCacheByUserId(long userId) {
    
    
        // 此方法执行时,会清除名为 "myCache" 中 key 为 userId 的缓存条目
    }

    @CacheEvict(value = "myCache", allEntries = true)
    public void clearEntireCache() {
    
    
        // 此方法执行时,会清除名为 "myCache" 中的所有缓存条目
    }
}

In the above example, the clearCacheByUserId method is used to clear the cache entry named "myCache" with key userId, while the clearEntireCache method is used to clear all cache entries in "myCache".

Note that the @CacheEvict annotation is typically used to clear the cache when a method is executed. If method execution throws an exception, cache clearing may not occur unless beforeInvocation = true is set. Therefore, it is necessary to ensure that the cache clearing operation is safe and does not cause cache clearing failure due to exceptions.

3、@CachePut

@CachePut is an annotation in the Spring framework used to update the cache. It is used to mark a method, and when the method is executed, the results will be placed in the cache. Unlike @Cacheable, @CachePut does not first check whether the result is already in the cache, but directly puts the return value of the method into the cache .

The following are the main properties and usage of the @CachePut annotation:

Main attributes:
value (or cacheNames) : Specifies the name of the cache to be updated, which can be an array of strings. For example: @CachePut(value = "myCache") 或 @CachePut(cacheNames = {"cache1", "cache2"}).

key : Specifies the SpEL expression used to generate the cache key. For example: @CachePut(value = "myCache", key = "#userId").

condition : Specifies the condition for placing in the cache, which is a SpEL expression. If the value of the expression is false, it will not be placed in the cache. For example: @CachePut(value = "myCache", condition = "#userId > 0").

unless : Contrary to condition, if the value of the expression is true, it will not be placed in the cache. For example: @CachePut(value = "myCache", unless = "#result == null").

Example usage:

@Service
public class MyService {
    
    

    @CachePut(value = "myCache", key = "#userId")
    public String updateCacheByUserId(long userId) {
    
    
        // 此方法执行时,会将返回值放入名为 "myCache" 中 key 为 userId 的缓存条目
        // 注意:不会先检查缓存中是否已有结果,直接将方法的返回值放入缓存中
        // ...
        return "Updated Value";
    }
}

In the above example, the updateCacheByUserId method is used to place the return value into the cache entry named "myCache" with the key userId. When this method is executed, it will not first check whether there is a result in the cache, but directly put the return value of the method into the cache.

@CachePut is usually used to put the latest results into the cache after an update operation to maintain cache consistency. It should be noted that unlike @Cacheable, @CachePut will not prevent the execution of the method, and even if the cache operation fails, it will not affect the normal execution of the method.

4. @Caching
@Caching is an annotation in the Spring framework used to combine multiple cache annotations. It allows multiple cache-related annotations to be used on a method at the same time, including @Cacheable, @CachePut, @CacheEvict, etc., thereby providing more flexible cache configuration.

Example usage:

@Service
public class MyService {
    
    

    @Caching(
        cacheable = {
    
    @Cacheable(value = "cache1", key = "#userId")},
        put = {
    
    @CachePut(value = "cache2", key = "#result.id")}
    )
    public User getUserById(long userId) {
    
    
        // 先尝试从 "cache1" 缓存中获取结果
        // 如果获取成功,则返回结果,不执行方法体
        // 如果获取失败,则执行方法体,并将结果放入 "cache1" 和 "cache2" 缓存中
        // ...
        return new User(userId, "John Doe");
    }
}

In the above example, the @Caching annotation is used with both @Cacheable and @CachePut annotations. Specifically:

The @Cacheable annotation is used to try to obtain the result from the cache named "cache1". If the acquisition is successful, the result will be returned directly without executing the method body.
The @CachePut annotation is used to put the return value of the method into the cache named "cache2", regardless of whether the same key is already in the cache.
Through the @Caching annotation, multiple caching annotations can be combined more flexibly to meet complex caching requirements.

3. Cache expiration time configuration

1. Setting in the annotation attribute
When using the @Cacheable annotation, you can configure the cache expiration time by setting the expire or expireAfterWrite attribute. This depends on the cache manager used, as different cache managers may support different configurations.

For example, if you are using Spring Boot and the underlying cache manager is based on Caffeine, you can use the expireAfterWrite property to set the expiration time. Here is an example:

@Cacheable(value = "myCache", key = "#input", expireAfterWrite = 5, timeUnit = TimeUnit.MINUTES)
public String getResult(String input) {
    
    
    // 如果缓存中存在以 input 为 key 的结果,则直接返回缓存结果
    // 否则,执行方法体,并将结果缓存起来,缓存时间为 5 分钟
    // ...
}

In the above example:

expireAfterWrite = 5 means that the cache item expires 5 minutes after being written.
timeUnit = TimeUnit.MINUTES indicates that the time unit is minutes.
The exact configuration depends on the cache manager used. If you are using other cache managers, such as EhCache, Redis, etc., the specific configuration methods may be different. Check the relevant properties in the configuration file or annotations to ensure that the cache expiration time is set correctly.

2. Redis manager settings
When using Redis as the cache manager, the expiration time of the Redis cache can be set through the Spring Boot configuration file or Java configuration . Here is an example:

  • Set the Redis cache expiration time in the Spring Boot configuration file:
    Add the following configuration in the application.properties or application.yml file:

    # Redis 服务器地址 spring.redis.host=localhost
    # Redis 服务器端口 spring.redis.port=6379
    # 缓存的默认失效时间,单位秒 spring.cache.redis.time-to-live=600
    
  • spring.cache.redis.time-to-live in the above configuration
    indicates that the default cache expiration time is 600 seconds (10 minutes). This value will be applied to all caches configured through @Cacheable and @CachePut annotations.


    Set the Redis cache expiration time in Java configuration: If you use the Java configuration class, you can set the cache expiration time through RedisCacheConfiguration in the configuration class . Here is an example:

     java @Configuration @EnableCaching public class CacheConfig
       extends CachingConfigurerSupport {
          
          
       
           @Bean
           public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
          
          
               RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                       .entryTtl(Duration.ofSeconds(600)); // 设置缓存失效时间为600秒(10分钟)
       
               return RedisCacheManager.builder(connectionFactory)
                       .cacheDefaults(config)
                       .build();
           } } 
    

    In the above configuration, entryTtl(Duration.ofSeconds(600))it means setting the cache expiration time to 600 seconds. This value will also apply to all caches configured through @Cacheable and @CachePut annotations.

Depending on your specific needs, you can configure different expiration times based on cache specificity. The above example is only for demonstration. In actual applications, the appropriate cache expiration time can be set according to business needs.

Guess you like

Origin blog.csdn.net/weixin_45188218/article/details/135131996