spring boot 2.x整合redis作为缓存

先安装rediswindows下安装redis

添加依赖

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

配置redis数据库

配置文件application.properties

在1.x中,时间相关的配置参数类型为int,默认单位为毫秒,配置中只需指定具体的数字即可,而在2.x中,时间相关的配置的参数类型都改为了jdk1.8的Duration,因此在配置文件中配置redis的连接超时时间timeout时,需要加入时间单位,如60s;还有,在2.0中配置redis的连接池信息时,不再使用spring.redis.pool的属性,而是直接使用redis的lettuce或jedis客户端来配置:

#缓存
spring.cache.type=redis

#redis数据源配置
spring.redis.host=localhost
spring.redis.port=6379
#数据库索引默认为0
spring.redis.database=0
#密码默认为空
#spring.redis.password=
#连接池最大连接数   负数表示没有限制
spring.redis.jedis.pool.max-active=8
#springboot2.0不再使用spring.redis.pool,与时间有关的要加上时间单位
#连接池最大阻塞等待事件  负数表示没有限制
spring.redis.jedis.pool.max-wait=-1s
#连接池最大空闲连接
spring.redis.jedis.pool.max-idle=8
#连接池最小空闲连接
spring.redis.jedis.pool.min-idle=0
#连接超时事件
spring.redis.timeout=60s

使用redis做缓存的配置类

之前看过很多网上的配置都是1.x的导致配置CacheManager时一直出错,是因为在1.0中使用RedisTemplate即可实例化一个RedisCacheManager:RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);,在2.0中删除了这个构造器,同时也不可以通过之前的setDefaultExpiration方法设置默认的缓存过期时间等,在新版本中可以通过以下的两种方式构造一个RedisCacheManager:

1.静态方法create,此方法产生的CacheManager使用的是Spring提供的默认配置:

public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisCacheManager rcm = RedisCacheManager.create(factory);
        return rcm;
    }

2.构造一个自己的redis配置类,创建RedisCacheConfiguration类,添加一些配置信息,再利用RedisCacheManager中的builder.build()的方式生成cacheManager:

@Bean
    public CacheManager cacheManager(RedisConnectionFactory factory){
        //生成一个默认配置,通过config对象即可对缓存进行自定义配置
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        config = config.entryTtl(Duration.ofMinutes(1))//设置缓存默认过期时间
            .disableCachingNullValues();    //不缓存空值
                                            //每调用一次配置类的设置方法都会返回一个新的config类,可以自己点进去源码看    

        //设置一个初始化的缓存空间set集合
        Set<String> cacheNames = new HashSet<String>();
        cacheNames.add("my-redis-cache-1");
        cacheNames.add("my-redis-cache-2");

        //对每个缓存空间应用不同的配置
        Map<String,RedisCacheConfiguration> configMap = new HashMap<>();
        configMap.put("my-redis-cache-1",config);
        configMap.put("my-redis-cahce-2",config.entryTtl(Duration.ofHours(1)));

        // 使用自定义的缓存配置初始化一个cacheManager
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .initialCacheNames(cacheNames)              //此方法参数为Set 一定要先调用该方法设置初始化的缓存名,再初始化相关的配置
                .withInitialCacheConfigurations(configMap)  //此方法参数为Map
                .build();
        return cacheManager;

    }

注意:若在设置配置信息时没有接收返回的新的配置类,配置信息更改不会生效

附上整个类的代码

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
    /**自定义缓存key生成策略**/
    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getName());
                sb.append(method.getName());
                for (Object obj:params){
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }

    //@Bean
    /**通过RedisCacheManager的静态方法create:这样产生的cacheManager只是使用Spring提供的默认配置**/
    /*public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisCacheManager rcm = RedisCacheManager.create(factory);
        return rcm;
    }*/
   /**缓存管理器**/
    /**通过Spring提供的RedisCacheConfiguration类,构造一个自己的redis配置类,
     从该配置类中可以设置一些初始化的缓存命名空间、及对应的默认过期时间等属性,
     再利用RedisCacheManager中的builder.build()的方式生成cacheManager:
    **/
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory){
        //生成一个默认配置,通过config对象即可对缓存进行自定义配置
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        config = config.entryTtl(Duration.ofMinutes(1))//设置缓存默认过期时间
            .disableCachingNullValues();    //不缓存空值

        //设置一个初始化的缓存空间set集合
        Set<String> cacheNames = new HashSet<String>();
        cacheNames.add("my-redis-cache-1");
        cacheNames.add("my-redis-cache-2");

        //对每个缓存空间应用不同的配置
        Map<String,RedisCacheConfiguration> configMap = new HashMap<>();
        configMap.put("my-redis-cache-1",config);
        configMap.put("my-redis-cahce-2",config.entryTtl(Duration.ofHours(1)));

        // 使用自定义的缓存配置初始化一个cacheManager
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .initialCacheNames(cacheNames)              //此方法参数为Set 注意这两句的调用顺序,一定要先调用该方法设置初始化的缓存名,再初始化相关的配置
                .withInitialCacheConfigurations(configMap)  //此方法参数为Map
                .build();
        return cacheManager;

    }

    @Bean
    public RedisTemplate<Object,Object> redisTemplate(RedisConnectionFactory factory){
        RedisTemplate<Object,Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

        jackson2JsonRedisSerializer.setObjectMapper(om);
        //使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(factory);
        return stringRedisTemplate;
    }
}

在注解上使用Cacheable

@Service
@CacheConfig(cacheNames="my-cache-redis-1")//使用此处缓存名,若方法上注解有写,则按后者来
public class GirlService {
    @SuppressWarnings("all")
    @Autowired
    private GirlMapper girlMapper;

    public int add(String cupSize,Integer age){
        return girlMapper.add(cupSize,age);
    }

    @CachePut(key="#p0") //指定key,将更新的结果同步到redis中
    public int update(String cupSize,Integer age,Integer id){
        return girlMapper.update(cupSize,age,id);
    }

    @CacheEvict(key="p0",allEntries=true) //如果指定为 true,则方法调用后将立即清空所有缓存
    public int delete(Integer id){
        return girlMapper.delete(id);
    }

    @Cacheable(key="#p0")//将查询结果缓存到redis中,(key="#p0")指定传入的第一个参数作为redis的key
    public Girl getGirlById(Integer id){
        System.out.println("不使用缓存查找");
        return girlMapper.getGirlById(id);
    }
    @Cacheable
    public List<Girl> getGirls(){
        System.out.println("不使用缓存查找");
        return girlMapper.getGirls();
    }
}

若是@Cacheable(key="#p0")不指定key 值,则按照RedisConfig类中的keyGenereator()方法的返回值做为key值

redis中的缓存信息

有关@Cacheable,@CachePut , @CacheEvict的使用可以参考:

Spring缓存注解@Cacheable,@CachePut , @CacheEvict使用

猜你喜欢

转载自blog.csdn.net/huofuman960209/article/details/87825121
今日推荐