Java整合SpringCache简化缓存开发

本文介绍了如何使用SpringCache与Redis整合实现缓存功能。通过添加依赖、配置Redis为缓存管理器,利用注解@Cacheable、@CacheEvict、@CachePut等进行缓存操作。在启动类上启用缓存,并通过SpEL定制缓存key和存活时间,以优化数据的读写和一致性。对于需要强一致性的场景,可以设置sync参数以添加本地锁。

官方文档

https://docs.spring.io/spring-framework/docs/5.3.25/reference/html/integration.html#cache

一个应用里要使用缓存,一般要配置一个或几个CacheManager

一、引入依赖

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

二、配置文件配置使用redis作为缓存

spring.cache.type: redis
#还可以设置过期时间,单位毫秒
spring.cache.redis.time-to-live: 360000

三、测试使用缓存

根据官方文档,使用如下5个注释

For caching declaration, Spring’s caching abstraction provides a set of Java annotations:

  • @Cacheable: Triggers cache population.

(触发将数据保存到缓存的操作)

  • @CacheEvict: Triggers cache eviction.

(触发将数据从缓存删除的操作,支持失效模式)

如下举例,在更新分类的方法上加上该注释,参数为写入缓存时的value与key值,要与其一样。

当更新数据库时,就会删除该缓存。

@CacheEvict(value = "category",key = "'getLevel1Categorys'")

//若想清楚这一个区(value)的缓存的话,就可按如下下
@CacheEvict(value = "category",allEntries = true)
  • @CachePut: Updates the cache without interfering with the method execution.

(不影响方法执行更新缓存,支持双写模式)

  • @Caching: Regroups multiple cache operations to be applied on a method.

(组合以上多个操作)

    @Caching(evict = {
            @CacheEvict(value = "category",key = "'getLevel1Categorys'"),
            @CacheEvict(value = "category",key = "'getCatalogJson'")
    })
  • @CacheConfig: Shares some common cache-related settings at class-level.

(在类级别共享缓存的相同配置)

1、开启缓存功能

在启动类上加上@EnableCaching注释

2、只需要使用注解就能完成缓存操作

如下举例

//查询所有1级分类
//每一个需要缓存的数据我们都来指定要放到那个名字的缓存。【也就是缓存的分区(可按业务类型分)】
//代表当前方法的返回需要缓存,如果缓存中有,方法不用调用。如没有,则调用方法,最后将结果放入缓存
    @Cacheable({"category"}) 
    @Override
    public List<CategoryEntity> getLevel1Categorys() {
        System.out.println("调用了方法....");
        long l = System.currentTimeMillis();
        QueryWrapper<CategoryEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_cid", 0);
        List<CategoryEntity> categoryEntities = baseMapper.selectList(queryWrapper);
        System.out.println("消耗时间:" + (System.currentTimeMillis() - l));
        return categoryEntities;
    }

结果运行来两次后,当第一次访问时,会调用方法。第二次访问时,则不会。

其中它会有如下默认行为:

a)、在redis中会自动生成key,其组成为:缓存的名字::自主生成的key(category::SimpleKey[])

b)、value的值,默认使用jdk序列化机制,将序列化后的数据存到redis

我们可以自定义一些操作:

a)、指定生成的缓存使用的key

使用key属性指定,接受一个SpEL格式语句,若有直接写String格式,则在“”里面加‘’。

@Cacheable(value = {"category"},key = "'level1Categorys'")

结果如下:category::level1Categorys

若想使用方法名作为key,则可更改成如下

@Cacheable(value = {"category"},key = "#root.method.name")

结果如下:category::getLevel1Categorys

由于SprinCache默认是没有加锁的,所以按如下加上sync=true,即可加上本地锁,但只有读模式有,写模式没有

@Cacheable(value = {"category"},key = "#root.method.name",sync = true)

更多SpEL表达式参考官方文档:

https://docs.spring.io/spring-framework/docs/5.3.25/reference/html/integration.html#cache-spel-context

b)、指定缓存的数据的存活时间

在配置文件中修改

#设置存活时间,单位毫秒
spring.cache.redis.time-to-live=3600000

c)、将数据保存为json格式

写一个配置类

@Configuration
@EnableCaching
public class MyCacheConfig {
        @Bean
        RedisCacheConfiguration redisCacheConfiguration(){
            RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
            //设置key的格式为String
            config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
            //设置value的格式为json
            config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
            return config;
    }
}

但只这样配置,会导致在redis中的过期时间变成恒定的-1,没有读取到配置文件中的360000毫秒,所以需要再加上如下配置,即可读取到配置文件中的参数了:

@EnableConfigurationProperties(CacheProperties.class)
@Configuration
@EnableCaching
public class MyCacheConfig {
    /*
    * 配置文件中的东西没用上
    * 1、原来和配置文件绑定的配置类是这样的
    * @ConfigurationProperties(prefix="spring.cache")
    * public class CacheProperties
    *
    * 2、要让他生效
    *    @EnableConfigurationProperties(CacheProperties.class)
     */
        @Bean
        RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties){
            RedisCacheConfiguration config = RedisCacheConfiguration
                                                .defaultCacheConfig();
            //设置key的格式为String
            config = config.serializeKeysWith(RedisSerializationContext
                    .SerializationPair
                    .fromSerializer(new StringRedisSerializer()));
            //设置value的格式为json
            config = config.serializeValuesWith(RedisSerializationContext
                    .SerializationPair
                    .fromSerializer(new GenericJackson2JsonRedisSerializer()));

            CacheProperties.Redis redisProperties = cacheProperties.getRedis();
            //将配置文件中的配置生效
            if (redisProperties.getTimeToLive() != null) {
                config = config.entryTtl(redisProperties.getTimeToLive());
            }

            if (redisProperties.getKeyPrefix() != null) {
                config = config.prefixCacheNameWith(redisProperties.getKeyPrefix());
            }

            if (!redisProperties.isCacheNullValues()) {
                config = config.disableCachingNullValues();
            }

            if (!redisProperties.isUseKeyPrefix()) {
                config = config.disableKeyPrefix();
            }        
            return config;
    }
}

总结

常规数据(读多写少,即时性,一致性要求不高的数据),完全可以使用spring-cache(只要缓存的数据有过期时间就足够了)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值