Springboot+@Cacheable注解实现缓存

248 阅读2分钟

Cacheable注解实现缓存

依赖准备

springboot的项目只需要引入spring-boot-starter-data-redis的依赖

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

Cacheable常用的属性

cacheNames/value :用来指定缓存组件的名字 cacheNames用来指定缓存组件的名字,将方法的返回结果放在哪个缓存中,可以是数组的方式,支持指定多个缓存

value只能指定一个缓存

**key **:缓存数据时使用的 key,可以用它来指定。默认是使用方法参数的值。(这个 key 你可以使用 spEL 表达式来编写)

**keyGenerator **:key 的生成器。 key 和 keyGenerator 二选一使用

cacheManager :可以用来指定缓存管理器。从哪个缓存管理器里面获取缓存。

condition :可以用来指定符合条件的情况下才缓存

**unless **:否定缓存。当 unless 指定的条件为 true ,方法的返回值就不会被缓存。当然你也可以获取到结果进行判断。(通过 #result 获取方法结果)

**sync **:是否使用异步模式。

代码实现

1.启用缓存

启动类上加注解 @EnableCaching

@SpringBootApplication
@EnableCaching
public class RedisCacheApplication {
	public static void main(String[] args) {
		SpringApplication.run(RedisCacheApplication.class, args);
	}

}

2.配置RedisCacheManager

package com.majinwen.redis.cache.conf;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;

import java.time.Duration;

/**
 * @Description:
 * @Author: 爱吃橙子的
 * @Date: 2024/3/7
 **/
@Component
public class RedisConfiguration {

    @Autowired
    private RedisProperties properties;

    /**
     * @return org.springframework.data.redis.core.RedisTemplate<java.lang.String, java.lang.Object>
     * @description 自定义redisTemplate注入到容器中
     * @author majw
     * @date 2024/03/14 14:22
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory(properties));
        // 设置key的序列化策略
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        // 设置hashkey的序列化策略
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        // 设置value的序列化策略
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        // 设置hashvalue的序列化策略
        redisTemplate.setHashValueSerializer(new StringRedisSerializer());
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    /**
     * @param properties
     * @return org.springframework.data.redis.connection.RedisConnectionFactory
     * @description RedisConnectionFactory 使用  LettuceConnectionFactory
     * @author majw
     * @date 2024/03/14 14:24
     */
    public RedisConnectionFactory redisConnectionFactory(RedisProperties properties) {
        RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration();
        redisConfig.setHostName(properties.getHost());
        redisConfig.setPort(properties.getPort());
        redisConfig.setPassword(properties.getPassword());
        redisConfig.setDatabase(properties.getDatabase());
        final LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(redisConfig);
        lettuceConnectionFactory.afterPropertiesSet();
        return lettuceConnectionFactory;
    }

    /**
     * @return org.springframework.data.redis.cache.RedisCacheManager
     * @description  配置RedisCacheManager
     * @author majw
     * @date 2024/03/14 14:24
     */
    @Bean("redisCacheManager")
    public RedisCacheManager redisCacheManager() {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                //设置缓存过期时间
                .entryTtl(Duration.ofDays(1))
                // 设置Cacheable注解 cacheNames或者value  与key的拼接符  默认是::  我这里改成:
                .computePrefixWith(name -> name + ":")
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));   //设置序列化器
        RedisCacheManager build = RedisCacheManager.builder(redisConnectionFactory(properties)).cacheDefaults(config).build();
        return build;
    }
}



3.具体的缓存案例

 @Override
    @Cacheable(cacheNames = "cache:str", key = "'p_'+#key", condition = "#value!=0")
    public String cacheString(String key, Integer value) {
        return "hello world";
    }

    @Override
    @Cacheable(cacheNames = "cache:map", key = "'p_'+#key", condition = "#value==0")
    public Map<String, Object> cacheMap(String key, Integer value) {
        final Map<String, Object> hashMap = new HashMap<>();
        hashMap.put("key1", "value1");
        hashMap.put("key2", "value2");
        return hashMap;
    }

    @Override
    @Cacheable(cacheNames = "cache:user", key = "'p_'+#key", condition = "#value==1")
    public User cacheUser(String key, Integer value) {
        final User user = new User("112", "张三先生", "123456");
        return user;
    }

4.redis中存储的效果

image.png