Spring-Boot2.x cache + redis integration

A, JSR107

Java Caching defines five core interface:

  • CachingProvider defines the creation, configuration, acquisition, management control what more CacheingManageer, an application can access multiple CachingProvider at runtime.
  • CachingManager defines the creation, configuration, acquisition, management control what more uniquely named Cache, Cache write this exists in the context CacheManager, one CacheManager only a CacheProvider owned.
  • Cache is a data structure similar to the Map and temporarily stores the value of the index key is not, a cache only have a CacheManager
  • Entry is key-value pairs stored in each of the Cache.
  • Expiry stored in each of the Cache entry has a defined period, once over this time, the state entry has not expired. Once expired, the entry ginger inaccessible, update, and delete. The cache is valid through ExpiryPolicy.

Second, the comment cache

Cache Cache interface, defined cache operation is implemented by: RedisCache, EhCacheCahe, ConcurrentMapCache
CacheManager Cache Manager, manage the cache (Cache) assemblies
@Cacheable The main methods for configuration, it is possible according to the results of its cache request parameter method
@CacheEvict Empty the cache
@CachePut Ensure the method is called, and hope results are cached
@EnableCaching Open annotation-based caching
keyGenerator When the comment cache key generation strategy
serialize Cache data value when serialization strategy

1、@Cacheable

  1. cacheNames / values : Specifies the name cache component, the method will return the results in the cache is an array, you can specify multiple cache
  2. Key : caching data used key, it can be specified, the default is to use the value of the parameter

For example: 1- methods return values ​​may be used SpEL expressions #id; parameter value id # a0 # p0 # root.args [0]

  1. keyGenerator : key generator, the key may specify their own generator component id key / keyGenerator: using a second election
  2. CacheManager / cacheResolver : Specifies the cache manager; or obtain a parser is used to specify cacheResolver
  3. for condition Condition : the case of specified qualifying only cache
  4. unless : Negative cache, unless specified when the condition is true, the return value will not be cached, the determination result can be acquired
  5. Sync : whether to use asynchronous mode

Running processes:

@Cacheable:

  1. Before running the method, go to the query Cache (cache component), acquired in accordance with the specified name cacheNames, (CacheManagerz first obtain the corresponding cache), if not first obtain the cache Cache component automatically created

  2. Find Cache to cache content, the use of a key, is the default method parameters, key is generated according to a certain strategy; default is to use keyGenerator generated,

  3. Not found in the cache is called the target method

  4. The results returned by the target method, into the cache

SpringEL expression:

first name position description Examples
methodName root object The current method is called name #root.methodName
method root object The current method is called #root.method.name
target root object The current target object has been called #root.target
targetClass root object The current target object class is called #root.targetClass
args root object Parameter list is called the current method #root.args[0]
caches root object Current methods used to invoke a cache list (e.g. @Cacheable (value = { "cache1", "cache2"})), there are two cache #root.caches[0].name
argument name evaluation context Name parameter can be directly # method parameter name, also p0 form or can use # # a0, 0 represents the index parameters; #iban, # a0, # p0
result evaluation context The return value after execution of the method (determination only after the implementation of an effective method, such as 'unless', 'cache put' expression 'cache evict' expression beforeInvocation = false) #result
@Cacheable(cacheNames = {"emp"}/*, keyGenerator = "myKeyGenerator"*/)
public Employee getEmp(Integer id){
    System.out.println("查询"+id+"号员工");
    Employee emp = employeeMapper.getEmpById(id);
    return emp;
}

2、@CachePut

Run timing:

1, the first call to the target method

2, the target method of cached results

/**
     * @Description: 既调用方法,又更新缓存
     * 先调用方法,然后将结果进行缓存
     * key = "#employee.id"
     * key = "#result.id" 返回值的id
     * 更新和查询用的key必须一致
     */
@CachePut(value = "emp",/*key = "#employee.id"*/key = "#result.id")
public Employee updateEmp(Employee employee){
    employeeMapper.updateEmp(employee);
    return employee;
}

3 @ CacheEvict

Clear the cache, you can delete the specified key

//allEntries:默认为false,为true时,指定清楚这个缓存中所有的数据
//beforeInvocation:缓存的清除是否在方法之前执行

/**
* @Description:@CacheEvict清除缓存
*/
@CacheEvict(value = "emp",key = "#id")
public void deleteEmp(Integer id){
employeeMapper.deleteEmpById(id);
}

4.@Caching

包含上面三个注解,适合复杂规则使用
public @interface Caching {
    Cacheable[] cacheable() default {};

    CachePut[] put() default {};

    CacheEvict[] evict() default {};
} 

例如:
    //复杂规则使用
    @Caching(
            cacheable = {
                    @Cacheable(value = "emp",key = "#lastName")
            },
            put = {
                    @CachePut(value = "emp",key = "#result.id"),
                    @CachePut(value = "emp",key = "#result.email")
            }
    )
    public Employee getEmpByLastName(String lastName){
        return employeeMapper.getEmpByLastName(lastName);
    }

5 @ CacheConfig

指定公共属性
@CacheConfig(cacheNames = "emp")
@Service
 public class EmployeeService {

The specified key Component Builder:

@Bean("myKeyGenerator")
    public KeyGenerator keyGenerator(){
        return new KeyGenerator(){
            @Override
            public Object generate(Object o, Method method, Object... objects) {
                return method.getName()+"["+ Arrays.asList(objects).toString()+"]";
            }
        };
    }s

Third, as a buffer integrated redis

pom.xml file to add:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <version>2.1.5.RELEASE</version>
</dependency>
  1. Redis introduction of starter, the storage container is RedisCacheManager
  2. RedisCacheManager as a buffer components to create RedisCache
  3. Kv is the default save data object, use serialization to save
@SpringBootTest
class Springboot01CacheApplicationTests {

    @Autowired
    EmployeeMapper employeeMapper;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    RedisTemplate<Object,Employee> employeeRedisTemplate;

    /*
     *Redis常见五种数据类型: String、List、Set、Hash(散列)、ZSet(有序集合)
     *stringRedisTemplate.opsForValue()操作String;
     *stringRedisTemplate.opsForList()操作List;
     * stringRedisTemplate.opsForSet()操作Set;
     * stringRedisTemplate.opsForHash()操作Hash;
     * stringRedisTemplate.opsForZSet()操作Zset;
     */
    @Test
    public void test01(){
//        stringRedisTemplate.opsForValue().append("msg","hello");
        stringRedisTemplate.opsForList().leftPush("myList","1");
        stringRedisTemplate.opsForList().leftPush("myList","2");
        String msg = stringRedisTemplate.opsForValue().get("msg");
        System.out.println("msg = " + msg);
//        stringRedisTemplate.opsForList();
//        stringRedisTemplate.opsForSet();
//        stringRedisTemplate.opsForHash();
//        stringRedisTemplate.opsForZSet();
//        System.out.println("=========");
    }

    @Test
    public void test02(){
        Employee emp = employeeMapper.getEmpById(1);
        employeeRedisTemplate.opsForValue().set("emp-01",emp);
    }

    @Test
    void contextLoads() {
        Employee emp = employeeMapper.getEmpById(1);
    }
}

Custom cachemanager serialized to json

@Bean
public CacheManager cacheManager(RedisConnectionFactory factory){
    RedisSerializer<String> redisSerializer = new StringRedisSerializer();
    Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

    //解决查询缓存转换异常的问题
    ObjectMapper om = new ObjectMapper();
    om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
    om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    jackson2JsonRedisSerializer.setObjectMapper(om);

    RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig()
        .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));
    RedisCacheManager build = RedisCacheManager.builder(factory).cacheDefaults(configuration).build();
    return build;
}

Gets the cache and add cache

@Autowired
CacheManager cacheManager;

@Cacheable(cacheNames = "dept")
public Department getDeptById(Integer id){
    System.out.println("查询部门" + id);
    Department dept = departmentMapper.getDeptByid(id);
    Cache dept1 = cacheManager.getCache("dept");
    dept1.put("dept1",dept);
    return dept;
}
Published 26 original articles · won praise 27 · views 6859

Guess you like

Origin blog.csdn.net/qq_40705355/article/details/103632772