Springboot-24 advanced feature - cache (JSR107, cache abstraction, Cacheable, redis integration)

Posted by timmytock on Sat, 26 Feb 2022 09:53:18 +0100

Purpose:

  • Read cache to reduce server pressure and improve performance;
  • Temporary data, such as validity verification code;

1,JSR107

(1) java caching defines five core interfaces

  • Cache provider: create, configure, obtain, manage and control the cache manager. An application can access multiple cache providers at runtime;
  • chchemanager: create, configure, manage, and control multiple uniquely named caches that exist in the context of the cache manager. A cache manager can only be used by one cache provider;
  • Cache: a map like data structure that temporarily stores values indexed by key s. A cache can only be owned by one cache manager;
  • entry: a key stored in the cache_ Value pair;
  • Expire: sets the cache expiration date.

(2) Relationship
An application has multiple providers, one provider has multiple managers, and one manager has multiple caches. From bottom to top, one to one, from top to bottom, one to many.

(3) Use
Import dependency

<dependency>
<grouId>javax.cache</grouId>
<artifactId>cache-api</artifactId>
</dependecy>

Use less, usually use spring cache abstraction more.

2. spring cache abstraction

spring3.1. The cache and cachemanager interfaces are defined to unify different caches, and support jcache(jsr107) annotation to simplify development;

  • The cache interface is defined by the cache component specification, including various operation sets of caching;
  • The spring interface of cache provides the implementation of various caches, such as redsicache,encache, etc;
  • Note: determine the cache strategy; Determine the cache storage data structure before reading.

Notes:

  • @Cacheable: cache;
  • @CacheEvict: clear the cache;
  • @CachePut: update cache;
  • @Enable caching: enables cache based annotation.
  • keyGenerator: key generation strategy when caching data;
  • serialize: the serialization policy of value.

use:

  • Import dependency:
    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
  • Enable annotation based caching
@SpringBootApplication
@MapperScan("com.example.sbgj.Mapper")
@EnableCaching // Enable annotation based caching
public class SbgjApplication {

    public static void main(String[] args) {
        SpringApplication.run(SbgjApplication.class, args);
    }

}
  • Annotation cache @ Cacheable
    Mark the @ Cacheable annotation on the method to cache the running results. In the future, the same data will be used and retrieved directly from the cache.

Principle:

  • simpleCache is enabled by default;

  • Configure the class to open the cache and import the cache component to the container;

  • Debug = true / / check which are effective;

@Cacheable property: add cache

Mechanism: check whether there is a key in the cache before calling the method, and then call the method

(1) cacheNames/value: the name of the cache component, in array mode. Multiple can be specified;
(2) Key: the key of the cached data, which is the value of the method parameter by default;
(3) keyGenerator: the generator of the key. It can be used with one of the two keys. It can be used by user-defined keys;
(4) cacheManager: Specifies the cache manager;
(5) cacheResolver: cache parser, choose one from the manager;
(6) Condition: condition caching. If the condition is true, it will be cached;
(7) Unless: unless the condition is true, it will not be cached;
(8) sync: whether to use asynchronous mode;

@Cacheable(cacheNames = "depart" ,key = "#id",condtion ="#id != 0",unless = "#result != null")

#id: the value of parameter id, equivalent to #a0 / #p0 / #root args[0]

@CachePut attribute: call the method to update the data and update the cache

Mechanism: call the method first, and then cache the method results

@CachePut(value= "depart" ,key = "#depart.id")

Query again after updating the information. There is no need to query the data at this time, but the information is the same as before the update???
Because the keys are inconsistent when updating and saving, it is necessary to ensure that the key policies when updating and adding are consistent.

@CacheEvict property: delete cache

Specify the data to be cleared through key
(1) allEntries: delete all caches. The default value is false. Do not delete all caches;
(2) beforeInvocation: the default is false, which means that the method is executed after execution, and true is before.

@CacheEvict(value= "depart" ,key = "#id")
@CacheEvict(value= "depart" ,allEntries= true)

@Caching property: specify complex rules

@Caching(
  cacheable ={
      @Cacheable(cacheNames = "depart" ,key = "#id")
  },
  put = {
      @CacheEvict(value= "depart" ,key = "#id")
      @CacheEvict(value= "depart" ,key = "#name")
  }
)(value= "depart" ,key = "#id")
@CacheEvict(value= "depart" ,allEntries= true)

@CacheConfig property: cache configuration

Add this annotation to a class to identify the public cache configuration class of the class

@CacheConfig(value="depart")//All cache configuration value s in this class need not be written

3,redis

Cache middleware is used in actual development, such as redis\ehcache.
(1) Build environment
Install redis using docker;

(2) Study
Official website: redis Chinese website

See more: Study notes

4. Cache principle and custom cacheManager

After introducing cache, help us create * * cache as cache component;

Custom json serialization

package com.example.sbgj.Config;

import com.example.sbgj.Entity.Depart;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

@Configuration
public class RedisConfig {
    
    //Define json serialization
    @Bean
    public RedisTemplate<Object, Depart> departRedisTemplate(RedisConnectionFactory redisConnectionFactory){
        RedisTemplate<Object,Depart> redisTemplate = new RedisTemplate<Object,Depart>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        Jackson2JsonRedisSerializer<Depart> jsonRedisSerializer= new Jackson2JsonRedisSerializer<Depart>(Depart.class );
        redisTemplate.setDefaultSerializer(jsonRedisSerializer);
        return redisTemplate;
    }
    
}

The use of serialization requires the object to implement the Serializable interface

Topics: Redis Spring Boot Cache