springCache整合redis详细讲解和配置

SpringCache的简介

缓存,就是将数据从数据库等数据来源获取数据,将数据缓存在内存或其他设备如Redis中,为了二次查询能够快速高效的响应结果.

Spring Cache是3.1开始提供, 通过注解的形式,对于整合业务代码友好.

Spring Cache特点:

提供Cache通用入口 ,方便多种实现切换缓存源,如Redis,Guava Cache等
支持事务, 即事务回滚时,缓存同时自动回滚

Cache-redis环境搭建

1.依赖配置
<!-- 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>
<!-- jackson默认不支持java8的时间类型,需要添加一个时间模块 -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.13.0</version>
</dependency>
2.application配置
#redis
redis:
host: 43.139.54.197
port: 6370
password: '123456'
database: 0
lettuce:
pool:
max-active: 8
max-idle: 8
min-idle: 0
max-wait: 1000ms #连接等待时间
debug: true

Cache的注解

  1. @EnableCaching

    使用场景:在启动类注解@EnableCaching开启缓存 

    @SpringBootApplication
    @EnableCaching //开启缓存
    public class DemoApplication{
    public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
    }
    }
  2. @Cacheable

    使用场景: 查询方法接口

    该注解会把方法的返回值缓存下来, 下一次调用方法时, 先查询缓存中是否存在,存在则直接返回,不存在,则查询数据返回,并将数据缓存.

    // 先从缓存中读取,如果没有再调用方法获取数据,然后把数据添加到缓存中
    @Cacheable(value = "user", key = "#id")
    public User select(String id) {
    List<User> users = userMapper.selectAll();
    for (User user : users) {
    if (user.getId().equals(id)) {
    return user;
    }
    }
    return null;
    }

    1.注解属性:

    注解属性 作用
    cacheNames 缓存key前缀名字,设置缓存组件
    key 缓存key后缀
    condition SpringEL表达式,结果为true,缓存数据到redis。结果为false,不缓存数据到redis
    unless SpringEL表达式,结果为false,缓存数据到redis。结果为true,不缓存数据到redis

    2.SpEL上下文数据

    属性名称 描述 示例
    methodName 当前方法名 #root.methodName
    method 当前方法 #root.method.name
    target 当前被调用的对象 #root.target
    targetClass 当前被调用的对象的class #root.targetClass
    args 当前方法参数组成的数组 #root.args[0]
    caches 当前被调用的方法使用的Cache #root.caches[0].name
  3. @Cacheput

    使用场景: 新增或修改方法

    该注解会把方法的返回值Put到缓存中, 供其他查询使用,如果有同一缓存则覆盖.

    // 查询数据库,将返回结果放到缓存
    @CachePut(value = "user", key = "#user.id")
    public User save(User user) {
    userMapper.insert(user);
    return user;
    }
  4. @CacheEvict

    使用场景: 删除或修改方法

    该注解会清空指定缓存.

    // 移除对应的缓存
    @CacheEvict(value = "user", key = "#user.id")
    public User update(User user) {
    userMapper.updateByPrimaryKey(user);
    return user;
    }
  5. @Caching

    使用场景: 同时操作多个缓存

    该注解是一个组合缓存,可以同时添加几个不同的注解,供不同的应用场景使用.如一个接口,可能同时操作多个缓存,且缓存的处理状态都不一样.

    @Caching(
    cacheable = {
    @Cacheable(value = "user",keyGenerator = "xdclassKeyGenerator")
    },
    put = {
    @CachePut(value = "user",key = "#id"),
    @CachePut(value = "user",key = "'stock:'+#id")
    }
    )
  6. @CacheConfig

    该注解用于配置该类中用的一些共用的缓存配置

    @CacheConfig(cacheNames = "cache:prefix")

Redis序列化配置类和Cache缓存配置类

@Configuration
public class RedisConfig {
private static StringRedisSerializer stringRedisSerializer;
private static Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer;
static {
//定义string类型序列化对象
stringRedisSerializer = new StringRedisSerializer();
//定义Jackson类型序列化对象
jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题
ObjectMapper om = new ObjectMapper();
//LocalDateTime序列化异常
om.registerModule(new JavaTimeModule());
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL
, JsonTypeInfo.As.WRAPPER_ARRAY);
jackson2JsonRedisSerializer.setObjectMapper(om);
}
@Bean //Redis序列化配置
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
//配置连接工程
template.setConnectionFactory(factory);
//redis key序列化方式
template.setKeySerializer(stringRedisSerializer);
//redis value序列化
template.setValueSerializer(jackson2JsonRedisSerializer);
//hashmap key序列化
template.setHashKeySerializer(stringRedisSerializer);
//hashmap value序列化
template.setHashValueSerializer(jackson2JsonRedisSerializer);
return template;
}
//Cache配置
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
// 配置序列化(解决乱码的问题),过期时间600秒
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
//过期时间
.entryTtl(Duration.ofSeconds(600))
//缓存key
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(stringRedisSerializer))
//缓存组件value
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
//value不为空
.disableCachingNullValues()
.computePrefixWith(cacheName -> cacheName + ":");
RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
.cacheDefaults(config)
.build();
return cacheManager;
}
}

Cache的自定义Key策略组件配置

1.配置
@Component("selfKeyGenerate")
public class SelfKeyGenerate implements KeyGenerator {
public Object generate(Object target, Method method, Object... params) {
if (params.length == 0) {
return SimpleKey.EMPTY;
}
Object param = params[0];
// 参数为map自定义key=类名+方法名+map的key-value值
if (param instanceof Map) {
StringBuilder builder = new StringBuilder();
// 分隔符
String sp = ".";
builder.append(target.getClass().getSimpleName()).append(sp);
builder.append(method.getName()).append(sp);
Map<String, Object> map = (Map<String, Object>) param;
if (map.isEmpty()) {
return builder.toString();
}
for (String key : map.keySet()) {
builder.append(key).append("-").append(map.get(key)).append(sp);
}
// builder.append(IdUtil.randomUUID());
return builder.toString();
}
return new SimpleKey(params);
}
}
2.使用
@Cacheable(cacheNames = "perCenter",keyGenerator = "selfKeyGenerate")
public R PersonalCenter(HttpServletRequest request){
return null;
}
posted @   西东怪  阅读(946)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
返回顶端
点击右上角即可分享
微信分享提示