当前位置: 首页 > article >正文

Spring Cache使用教程

使用步骤:

1.导入相关依赖(redis、Springcache)

    <!-- Spring Boot Starter Cache -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>

    <!-- Redis 缓存实现 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>

2.配置缓存信息(application.yml)

spring:
  # redis配置
  redis:
    # redis服务器地址
    host: ${sky.redis.host}
    # redis服务器端口
    port: ${sky.redis.port}
    # redis密码,没有可不写
    password: ${sky.redis.password}
    # redis数据库索引(默认为0、默认库有0-15)
    database: ${sky.redis.database}
    # 缓存配置
  cache:
    # 缓存类型
    type: redis

3.添加Redis配置类(RedisConfig.java、这里是因为使用的redsis,所以配置合在一起了)

package com.sky.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.CacheManager;
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.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.lang.reflect.Method;
import java.time.Duration;
import java.util.Random;


/**
 * Redis配置类,用于配置RedisTemplate以支持自定义的序列化和反序列化。
 * 通过自定义序列化器,可以将复杂的Java对象序列化为JSON格式存储到Redis中,并在读取时反序列化为Java对象。
 */
@Configuration
@EnableCaching
@Slf4j
public class RedisConfig {
    /**
     * 配置RedisTemplate以使用自定义序列化器。
     *
     * @param redisConnectionFactory Redis连接工厂,用于创建Redis连接
     * @return 配置好的RedisTemplate实例
     */
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        log.info("开始创建RedisTemplate实例...");
        // 创建RedisTemplate实例
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();

        // 设置Redis连接工厂
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        // 使用Jackson2JsonRedisSerializer替换默认的序列化方式,以便将对象序列化为JSON格式存储在Redis中
        Jackson2JsonRedisSerializer jsonRedisSerializer =
                new Jackson2JsonRedisSerializer(Object.class);
        // 配置ObjectMapper以解决查询缓存转换异常
        ObjectMapper om = new ObjectMapper();
        // 支持Java8的时间类型
        om.registerModule(new JavaTimeModule());
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jsonRedisSerializer.setObjectMapper(om);

        // 设置RedisTemplate的value序列化器为自定义的JSON序列化器
        // 这样可以将复杂的Java对象序列化为JSON格式存储到Redis中
        redisTemplate.setValueSerializer(jsonRedisSerializer);

        // 设置RedisTemplate的key序列化器为StringRedisSerializer
        // 这样可以将字符串类型的键存储到Redis中
        redisTemplate.setKeySerializer(new StringRedisSerializer());

        // 初始化RedisTemplate,确保所有属性设置正确
        redisTemplate.afterPropertiesSet();

        // 返回配置好的RedisTemplate实例
        return redisTemplate;
    }


    /**
     * 创建自定义的KeyGenerator,用于生成缓存的键。
     *
     * @return 自定义的KeyGenerator实例
     */
    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                // 格式化缓存key字符串
                StringBuilder sb = new StringBuilder();
                // 追加类名
                sb.append(target.getClass().getName());
                // 追加方法名
                sb.append(method.getName());
                // 遍历参数并追加
                for (Object obj : params) {
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }

    /**
     * 配置CacheManager以使用自定义的序列化和反序列化。
     *
     * @param factory Redis连接工厂,用于创建Redis连接
     * @return 配置好的CacheManager实例
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        // 创建Redis序列化对象
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        // 创建Jackson的序列化对象
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer =
                new Jackson2JsonRedisSerializer(Object.class);
        // 解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        // 支持Java8的时间类型
        om.registerModule(new JavaTimeModule());
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // 配置序列化(解决乱码的问题)
        RedisCacheConfiguration configuration =
                RedisCacheConfiguration.defaultCacheConfig()
                        // 设置缓存过期时间
                        .entryTtl(Duration.ofSeconds(new Random().nextInt(+0*60*60*24+new Random().nextInt(+60*60*24))))
                        .serializeKeysWith(RedisSerializationContext.SerializationPair.
                                fromSerializer(redisSerializer))
                        .serializeValuesWith(RedisSerializationContext.SerializationPair.
                                fromSerializer(jackson2JsonRedisSerializer))
                        .disableCachingNullValues();
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(configuration).build();
        return cacheManager;
    }
}

4.开启Redis缓存支持、启动类添加注解(@EnableCaching)

//在启动类添加注解,开启缓存支持
@EnableCaching

常用注解:

@Cacheable

作用

将方法的结果存储在缓存中,下次调用相同参数的方法时直接从缓存中获取结果,而不是重新执行方法。

常用属性

valuecacheNames:指定缓存的名称。

key:指定缓存的键,可以使用 SpEL 表达式。

unless:指定条件,如果条件为真,则不缓存结果。

condition:指定条件,如果条件为真,则缓存结果。

示例:        

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Cacheable(value = "users", key = "#id")
    public User getUserById(String id) {
        // 模拟从数据库中查询用户
        return userRepository.findById(id);
    }
}


@CachePut

作用

更新缓存中的值,每次方法调用后都会将结果存入缓存。

常用属性

value cacheNames:指定缓存的名称。

key:指定缓存的键,可以使用 SpEL 表达式。

unless:指定条件,如果条件为真,则不缓存结果。

condition:指定条件,如果条件为真,则缓存结果。

示例

import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @CachePut(value = "users", key = "#user.id")
    public User updateUser(User user) {
        // 更新用户信息并返回
        return userRepository.save(user);
    }
}

@CacheEvict

作用

从缓存中删除指定的条目。

常用属性

valuecacheNames:指定缓存的名称。

key:指定缓存的键,可以使用 SpEL 表达式。

allEntries:如果为 true,则清除所有缓存条目。

beforeInvocation:如果为 true,则在方法调用前清除缓存;默认为 false,即在方法调用

清除缓存。

示例

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @CacheEvict(value = "users", key = "#id")
    public void deleteUser(String id) {
        // 删除用户
        userRepository.deleteById(id);
    }

    @CacheEvict(value = "users", allEntries = true)
    public void clearAllUsersCache() {
        // 清除所有用户的缓存
    }
}

@Caching

作用

组合多个缓存操作,适用于复杂场景。

常用属性

cacheable:包含 @Cacheable 注解的数组。

put:包含 @CachePut 注解的数组。

evict:包含 @CacheEvict 注解的数组。

示例

import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Caching(
        cacheable = { @Cacheable(value = "users", key = "#id") },
        put = { @CachePut(value = "users", key = "#user.id") },
        evict = { @CacheEvict(value = "users", key = "#oldId") }
    )
    public User updateUser(String oldId, User user) {
        // 更新用户信息并返回
        user.setId(oldId);
        return userRepository.save(user);
    }
}

@CacheConfig

作用

在类级别定义缓存配置,避免在每个方法上重复相同的缓存配置。

常用属性

value 或 cacheNames:指定缓存的名称。

keyGenerator:指定自定义的键生成器。

cacheManager:指定自定义的缓存管理器。

cacheResolver:指定自定义的缓存解析器。

示例:        

import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
@CacheConfig(cacheNames = "users")
public class UserService {

    @Cacheable(key = "#id")
    public User getUserById(String id) {
        // 模拟从数据库中查询用户
        return userRepository.findById(id);
    }

    @CachePut(key = "#user.id")
    public User updateUser(User user) {
        // 更新用户信息并返回
        return userRepository.save(user);
    }

    @CacheEvict(key = "#id")
    public void deleteUser(String id) {
        // 删除用户
        userRepository.deleteById(id);
    }
}


 


http://www.kler.cn/a/401075.html

相关文章:

  • 【ArcGISPro】使用AI模型提取要素-提取车辆(目标识别)
  • 【python】机器学习调参与自动化:使用Hyperopt优化你的模型
  • HTTP 1.0、HTTP 1.1 和 HTTP 2.0 区别
  • 【FAQ】HarmonyOS SDK 闭源开放能力 —Share Kit
  • C/C++中使用MYSQL
  • 【linux】如何扩展磁盘容量(VMware虚拟机)-转载
  • NVMe非易失性存储器访问和传输协议;以及PICE总线简单理解
  • 2024年11月14日Github流行趋势
  • 称重传感器指示器行业全面且深入的分析
  • fastadmin操作数据库字段为json、查询遍历each、多级下拉、union、php密码设置、common常用函数的使用小技巧
  • 【原创】java+ssm+mysql成绩统计分析管理系统设计与实现
  • 神经网络与Transformer详解
  • VueDPlayer视频插件的使用
  • thinkphp6安装php-mqtt/client,并实现实时消息收发写入日志
  • web——upload-labs——第十一关——黑名单验证,双写绕过
  • 【WSL+Kali】进行系统升级时在 Setting up libc6:amd64 (2.37-15) ... 卡住不动
  • CSS 样式覆盖规则?
  • Java-03 深入浅出 MyBatis - 快速入门(无 Spring) 增删改查 核心配置讲解 XML 与 注解映射
  • 联想 ThinkPad的高级键盘功能
  • php消息路由
  • React Native 全栈开发实战班 - 性能与调试之打包与发布
  • 什么是‌‌‌‌‌‌SQL,有什么特点
  • 数据库的性能优化 -- SQL性能优化
  • 【DBA攻坚指南:左右Oracle,右手MySQL-学习总结】
  • 面向对象几个自测题
  • 新能源汽车领域的磁集成解决方案及挑战