Spring Boot integrates user defined generation methods of redis and key

  • 2021-09-24 22:41:37
  • OfStack

1) Customize the redis key generation policy

@Configuration Indicates that the current class belongs to a configuration class, similar to an spring. cfg. xml.

@EnableCaching Indicates support for enabling caching.

Custom configuration source code:


import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCachePrefix;
import org.springframework.data.redis.core.RedisTemplate; 
import com.alibaba.fastjson.JSON;
 
/**
 * redis Configuration tool class 
 * @Configuration Indicates that the current class belongs to the configuration class 
 * @EnableCaching Indicates support for caching 
 * @author ouyangjun
 */
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
 
    /**
     * redis key Generation strategy 
     * target:  Class 
     * method:  Method 
     * params:  Parameter 
     * @return KeyGenerator
     *  Attention :  The method simply declares the key Generation strategy of , It has not been used yet , Need to be in @Cacheable Specified in the annotation keyGenerator
     *       Such as : @Cacheable(value = "key", keyGenerator = "cacheKeyGenerator")
     */
    @Bean
    public KeyGenerator cacheKeyGenerator() {
        return (target, method, params) -> {
            StringBuilder sb = new StringBuilder();
            sb.append(target.getClass().getName());
            sb.append(method.getName());
            for (Object obj : params) {
                //  Because the parameters may be different, , hashCode Definitely not 1 Sample ,  Cached key Also need not 1 Sample 
                sb.append(JSON.toJSONString(obj).hashCode());
            }
            return sb.toString();
        };
    }
 
    /**
     * redis Global default configuration 
     * @param redisTemplate
     * @return
     */
    @Bean
    public CacheManager cacheManager(RedisTemplate<String, Object> redisTemplate) {
        RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate);
        redisCacheManager.setUsePrefix(true);
        // key Cached prefix , With conf Beginning 
        RedisCachePrefix cachePrefix = new RedisPrefix("conf");
        redisCacheManager.setCachePrefix(cachePrefix);
        // key Expiration time of cache , 600 Seconds 
        redisCacheManager.setDefaultExpiration(600L);
        return redisCacheManager;
    }
}

2) SpringBoot comes with its own cache mode

Notes:

@Cacheable Meaning: When calling the method declared by the annotation, it will first look up from the cache to judge whether there is data in the same cache as key. If there is, it will directly return the data. If not, it will execute the method, and then store the returned data in the cache in the way of key value, which is convenient to return the data directly from the cache when the same parameter is requested next time.

@ Cacheable supports the following parameters:

cacheNames 1 segment name of cache location, cannot be empty, and value1 meaning.

value 1 segment name of cache location, cannot be empty, and cacheNames1 meaning.

key The cached key is empty by default, indicating that the parameter type and parameter value of the method are used as key, and SpEL is supported.

keyGenerator Specifies the build policy for key.

condition : Trigger condition. If the condition is met, it will be added to the cache. It is empty by default, indicating that all of them will be added to the cache. SpEL is supported.

@CacheEvict Meaning: When there is a cache with the same key, emptying the cache is equivalent to deleting it.

@ CacheEvict supports the following parameters:

cacheNames 1 segment name of cache location, cannot be empty, and value1 meaning.

value 1 segment name of cache location, cannot be empty, and cacheNames1 meaning.

key The cached key is empty by default, indicating that the parameter type and parameter value of the method are used as key, and SpEL is supported.

condition : Trigger condition. If the condition is met, it will be added to the cache. It is empty by default, indicating that all of them will be added to the cache. SpEL is supported.

allEntries : true means clearing all caches in value, and the default is false.

Test code:


package hk.com.cre.process.basic.service.impl; 
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable; 
public class RdisCacheTest {
 
    /**
     *  Cache test 
     *  Cache generation rules : conf:redis: Class name method name parameter hashcode
     *  Attention : @Cacheable The type generated by annotations is in the redis The default in is string
     *       At each request , It's all based on key To redis Does the query exist , Execute the code in the method if it does not exist 
	 */
    @Cacheable(cacheNames = "redis", keyGenerator = "cacheKeyGenerator")
    public String getRedisString(String param1, String param2) {
        return param1+":"+param2;
    }
	
    /**
     *  Clear the cache 
     */
    @CacheEvict(cacheNames = "redis", allEntries = true)
    public String cleanCache() {
        return "success";
    }
}

Spring Cache KeyGenerator Custom rediskey

1. Overview

In this tutorial, we demonstrate how to create a custom key generator using Spring Cache.

2. KeyGenerator

This is responsible for generating each key for each data item in the cache, which will be used to find the data item at retrieval time.

The default implementation here is SimpleKeyGenerator, which uses the provided method parameters to generate the key. This means that if we have two methods that use the same cache name and parameter type set, there is a good chance of a conflict.

It also means that cached data can be overwritten by another method.

3. Customize the key generator

The key generator only needs to implement one method:


Object generate(Object object, Method method, Object... params)

If not implemented or used correctly, it may cause cached data to be overwritten.

Let's look at implementation:


public class CustomKeyGenerator implements KeyGenerator {
    public Object generate(Object target, Method method, Object... params) {
        return target.getClass().getSimpleName() + "_"
          + method.getName() + "_"
          + StringUtils.arrayToDelimitedString(params, "_");
    }
}

After that, we have two possible ways to use it; The first is to declare a bean in the application Config.

It is important to note that classes must support or implement cache configurator extensions from cache configuration:


@EnableCaching
@Configuration
public class ApplicationConfig extends CachingConfigurerSupport {
    @Bean
    public CacheManager cacheManager() {
        SimpleCacheManager cacheManager = new SimpleCacheManager();
        Cache booksCache = new ConcurrentMapCache("books");
        cacheManager.setCaches(Arrays.asList(booksCache));
        return cacheManager;
    }
    @Bean("customKeyGenerator")
    public KeyGenerator keyGenerator() {
        return new CustomKeyGenerator();
    }
}

The second method is to use it for specific methods:


@Component
public class BookService {
    @Cacheable(value = "books", keyGenerator = "customKeyGenerator")
    public List<Book> getBooks() {
        List<Book> books = new ArrayList<>();
        books.add(new Book("The Counterfeiters", "Andr é  Gide"));
        books.add(new Book("Peer Gynt and Hedda Gabler", "Henrik Ibsen"));
        return books;
    }
}

4. Conclusion

In this paper, we discuss the method of implementing a key generator with custom spring cache.

As usual, the complete source code of the example can be found on GitHub.


Related articles: