New posture of spring boot2. X operation cache

I. Introduction

spring cache is a technology introduced after spring 3, which can simplify the operation of the cache layer. spring cache is similar to spring cloud stream, which is based on the abstract layer, and can switch its implementation arbitrarily. Its core is the two interfaces of CacheManager and cache. All the caches integrated by spring must implement these two interfaces. The implementation classes of Redis are RedisCache and RedisManager.


Two, use

I. query

Dependency to import

1 <dependency>
2     <groupId>org.springframework.boot</groupId>
3     <artifactId>spring-boot-starter-cache</artifactId>
4 </dependency>
5 <dependency>
6     <groupId>org.springframework.boot</groupId>
7     <artifactId>spring-boot-starter-data-redis</artifactId>
8 </dependency>

Write configuration for cache

 1 @EnableCaching
 2 @SpringBootConfiguration
 3 public class CacheConfig {
 5     @Autowired
 6     private RedisConnectionFactory connectionFactory;
 8     @Bean // If there are more than one CacheManager You need to use@Primary Specify that directly is the default
 9     public RedisCacheManager cacheManager() {
10         RedisSerializer<String> redisSerializer = new StringRedisSerializer();
11         Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
13         ObjectMapper om = new ObjectMapper();
14         // Prevent loss of object properties during serialization
15         om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
16         // Open entity classes and json Type conversion of
17         om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
18         jackson2JsonRedisSerializer.setObjectMapper(om);
20         // Configure serialization (to solve the problem of garbled code)
21         RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()   .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))             .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
22                 // Do not cache null values
23                 .disableCachingNullValues()
24                 // 1 Minutes expired
25                 .entryTtl(Duration.ofMinutes(1))
26                 ;
27         RedisCacheManager cacheManager = RedisCacheManager.builder(connectionFactory)
28                 .cacheDefaults(config)
29                 .build();
30         return cacheManager;
31     }
32 }

After the above configuration, you can use springboot cache. There is also a key generation policy configuration (optional)

 1 @Bean
 2 public KeyGenerator keyGenerator() {
 3     return (target, method, params) -> {
 4         StringBuffer key = new StringBuffer();
 5         key.append(target.getClass().getSimpleName() + "#" + method.getName() + "(");
 6         for (Object args : params) {
 7             key.append(args + ",");
 8         }
 9         key.deleteCharAt(key.length() - 1);
10         key.append(")");
11         return key.toString();
12     };
13 }

Note: if the KeyGenerator is configured, if the key is not specified during caching, the generated key will be cached finally. If the KeyGenerator and key are configured at the same time, the key will be used first.

Add @ CacheConfig to the controller or service class. See the following table for details of the parameters in the annotation:

Parameter name Parameter value Effect
cacheNames It can be filled in at will, generally a module or a very important function name It has no specific function. It is only used to distinguish cache and facilitate management
keyGenerator Is the name of the KeyGenerator you configured The global key will be generated by his strategy
cacheManager Self configured CacheManager For operating Cache objects, many Cache configurations are also managed by him

Write a method to query a single object in the class marked with @ CacheConfig and add @ Cacheable annotation

1 @Cacheable(key = "#id", unless = "#result == null") 
2 @PatchMapping("/course/{id}")
3 public Course courseInfo(@PathVariable Integer id) {
4"Come in. .. ");
5     return courseService.getCourseInfo(id);
6 }

After executing this method, the execution result will be cached to Redis:


The parameters in the @ Cacheable annotation are detailed in the following table:

Parameter name Effect
cacheNames Namespace when cached
key The priority of the key here is the highest. It can override the key configured globally. If it is not configured, the global key is used
keyGenerator The generator of the specified cached key, which is not available by default
cacheManager Specifies which cache manager to use. The default is the underlying auto configuration manager
condition What conditions are met will be cached, in which simple expressions can be written for logical judgment
unless What conditions are met without caching? Simple expressions can be written in it for logical judgment
sync Is the operation added to the cache synchronous

II. Modification

Write a modified method to transfer parameters to the object and change the return value to this object

1 @PutMapping("/course")
2 public Course modifyCoruse(@RequestBody Course course) {
3     courseService.updateCourse(course);
4     return course;
5 }

Add @ cacheput (key = "ා course. ID") annotation on the method. This annotation means to update the return value of the method to the cache. The parameters in the annotation are the same as those in @ Cacheable, which is skipped here.

III. deletion

Write a delete method and add @ CacheEvict annotation on the method

1 @CacheEvict(key = "#id")
2 @DeleteMapping("/course/{id}")
3 public void removeCourse(@PathVariable Integer id) {
4     courseService.remove(id);
5 }

The parameter information of @ CacheEvict is shown in the following table:

Parameter name describe
allEntries Whether to delete all caches under the namespace? The default is false
beforeInvocation Clear the cache before deleting the method. The default value is false. If the deleting method reports an error, the annotation will not be executed


3, Use of code based Cache

Because we have a configured cache manager, we can manually operate the cache by using the RedisCacheManager object. First, inject the CacheManager into the cache:

 1 @Resource 
 2 private CacheManager cacheManager;
 4 @PatchMapping("/course2/{id}")
 5 public Course course2(@PathVariable Integer id) {
 6     // Gets the cache
 7     Cache cache = cacheManager.getCache("course");
 8     // adopt key Get the corresponding value
 9     Cache.ValueWrapper wrapper = cache.get(2);
10     if (wrapper == null) {
11         // query data base
12         Course course = courseService.getCourseInfo(id);
13         // Add cache
14         cache.put(course.getId(), course);
15         return course;
16     } else {
17         // Return cached results
18         // Because of the configuration enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
19         // So there is no error in the forced rotation
20         return (Course) wrapper.get(); 
21     }
22 }

If you still don't understand, please go to code cloud to get the source code


What kind of person do you want to be!

Tags: Java Spring Redis JSON SpringBoot

Posted on Thu, 20 Feb 2020 02:45:03 -0500 by hasanpor