springboot缓存 集成Redis缓存

依赖

缓存依赖

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

配置类

package chang.redis.config;

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.cache.interceptor.SimpleKeyGenerator;
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.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

/**
 * @author chang
 */
@EnableCaching
@Configuration
public class RedisCachingConfig {

    /**
     * @param redisConnectionFactory
     * @功能描述 redis作为缓存时配置缓存管理器CacheManager,主要配置序列化方式、自定义
     *
     * 注意:配置缓存管理器CacheManager有两种方式:
     * 方式1:通过RedisCacheConfiguration.defaultCacheConfig()获取到默认的RedisCacheConfiguration对象,修改RedisCacheConfiguration对象的序列化方式等参数【这里就采用的这种方式】
     * 方式2:通过继承CachingConfigurerSupport类自定义缓存管理器,覆写各方法,参考:
     *
     * 切记:在缓存配置类中配置以后,yaml配置文件中关于缓存的redis配置就不会生效,如果需要相关配置需要通过@value去读取
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
        redisCacheConfiguration = redisCacheConfiguration
                // 设置key采用String的序列化方式
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(StringRedisSerializer.UTF_8))
                //设置value序列化方式采用jackson方式序列化
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer()))
                //当value为null时不进行缓存
                .disableCachingNullValues()
                // 配置缓存空间名称的前缀
                .prefixCacheNameWith("demo:")
                //全局配置缓存过期时间【可以不配置】
                .entryTtl(Duration.ofMinutes(30L));
        //专门指定某些缓存空间的配置,如果过期时间【主要这里的key为缓存空间名称】
        Map<String, RedisCacheConfiguration> map = new HashMap<>();

//        Set<Map.Entry<String, Long>> entries = ttlParams.entrySet();
//        for (Map.Entry<String, Long> entry : entries) {
//            //指定特定缓存空间对应的过期时间
//            map.put("user", redisCacheConfiguration.entryTtl(Duration.ofSeconds(40)));
//            map.put(entry.getKey(), redisCacheConfiguration.entryTtl(Duration.ofSeconds(entry.getValue())));
//        }

        return RedisCacheManager
                .builder(redisConnectionFactory)
                // 默认配置
                .cacheDefaults(redisCacheConfiguration)
                // 某些缓存空间的特定配置
                .withInitialCacheConfigurations(map)
                .build();
    }


    /**
     * 自定义缓存的redis的KeyGenerator【key生成策略】
     * 注意: 该方法只是声明了key的生成策略,需在@Cacheable注解中通过keyGenerator属性指定具体的key生成策略
     * 可以根据业务情况,配置多个生成策略
     * 如: @Cacheable(value = "key", keyGenerator = "cacheKeyGenerator")
     */
    @Bean
    public KeyGenerator keyGenerator() {
        /**
         * target: 类
         * method: 方法
         * params: 方法参数
         */
        return (target, method, params) -> {
            //获取代理对象的最终目标对象
            StringBuilder sb = new StringBuilder();
            sb.append(target.getClass().getSimpleName()).append(":");
            sb.append(method.getName()).append(":");
            //调用SimpleKey的key生成器
            Object key = SimpleKeyGenerator.generateKey(params);
            return sb.append(key);
        };
    }


    /**
     * 此方法不能用@Ben注解,避免替换Spring容器中的同类型对象
     */
    public GenericJackson2JsonRedisSerializer serializer() {
        return new GenericJackson2JsonRedisSerializer();
    }

}

使用

具体怎么使用可以自行百度
例如:

package chang.web.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author chang
 * @Date 2022/5/29 22:22
 */
@RestController
@RequestMapping("/cache")
public class CacheRedisController {

    private static final Logger logger= LoggerFactory.getLogger(CacheRedisController.class);

    @GetMapping("/t1")
    public String t1(){
        logger.info("执行Controller。");
        return cacheTest("a");
    }

    @Cacheable(cacheNames = "hello")
    public String cacheTest(String user_id){
        logger.info("缓存执行了。");
        return "缓存执行了。";
    }

}

注意,坑

其实上面的代码缓存是没有生效的,原理和事务失效一样,没有被AOP代理,事务是无法生效的

正确演示

package chang.web.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.AopContext;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author chang
 * @Date 2022/5/29 22:22
 */
@RestController
@RequestMapping("/cache")
public class CacheRedisController {

    private static final Logger logger= LoggerFactory.getLogger(CacheRedisController.class);

    @GetMapping("/t1")
    public String t1(){
        logger.info("执行Controller。");

        // AOP 代理
        CacheRedisController cacheRedisController = (CacheRedisController)AopContext.currentProxy();

        return cacheRedisController.cacheTest("a");
    }

    @Cacheable(cacheNames = "hello")
    public String cacheTest(String user_id){
        logger.info("缓存执行了。");
        return "缓存执行了。";
    }

}

不过这么写的话,需要引入AOP依赖,在启动类上加注解

或者你可以直接使用自动注入去使用方法就行了

// 注解
@SpringBootApplication
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
public class SpringbootReadApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootReadApplication.class, args);
    }
}

 <!--  使用 AopContext -->
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-aop</artifactId>
 </dependency>

Redis 存储效果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值