SpringBoot2整合Redis缓存

在学习springboot集成redis的时候遇到这样一个奇怪的问题:我从数据库中取得的对象已经放入了redis中,而且从redis的客服端也可以查看到对应的key,开始的时候还是正常的,能正常的从缓存中取得并返回我需要的类;但是过一段时间第二次访问这个方法时(这时应该是到redis里面取)抛出了java.lang.ClassCastException异常,说你的com.test.PerSon类(假设你存入缓存的是com.test.PerSon类),不能转为com.test.PerSon类。

这个就比较奇怪了,最后在不知道怎么回事的情况下把

org.springframework.boot

spring-boot-devtools

true

模块去掉了就正常了。这个也......;


1、pom文件加入


			org.springframework.boot
			spring-boot-starter-data-redis
			2.0.3.RELEASE
		
		
		
		
			org.apache.commons
			commons-pool2
			2.5.0
		


2、application.properties 加入redis相关配置

spring.redis.host=192.168.19.173
spring.redis.port=6379
spring.redis.timeout=60s
# 数据库连接超时时间,2.0 中该参数的类型为Duration,这里在配置的时候需要指明单位
spring.redis.timeout=60s
# 连接池配置,2.0中直接使用jedis或者lettuce配置连接池
# 最大活跃连接数,负数为不限制
spring.redis.lettuce.pool.max-active=500
# 等待可用连接的最大时间,负数为不限制
spring.redis.lettuce.pool.max-wait=-1ms
# 最大空闲连接数
spring.redis.lettuce.pool.max-idle=100
# 最小空闲连接数
spring.redis.lettuce.pool.min-idle=20



3、启动类加注解 

@EnableCaching

4、缓存配置类

package com.ps.uzkefu.common;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cache.CacheManager;
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.StringRedisSerializer;

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

/**
 * Author:ZhuShangJin
 * Date:2018/6/25
 */
@Configuration
public class CacheConfig {
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);

        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
        Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);

        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);

        template.setValueSerializer(serializer);
        //使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }
    //    redis缓存和EhCache缓存不能同时存在
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
//        RedisCacheManager cacheManager = RedisCacheManager.create(redisConnectionFactory);

// 生成一个默认配置,通过config对象即可对缓存进行自定义配置
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        config = config.entryTtl(Duration.ofMinutes(1))     // 设置缓存的默认过期时间,也是使用Duration设置
                .disableCachingNullValues();     // 不缓存空值

        // 设置一个初始化的缓存空间set集合
        Set cacheNames =  new HashSet<>();
        cacheNames.add("timeGroup");
        cacheNames.add("user");

        // 对每个缓存空间应用不同的配置
        Map configMap = new HashMap<>();
        configMap.put("timeGroup", config);
        configMap.put("user", config.entryTtl(Duration.ofSeconds(120)));

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


5、

Service层应用缓存(注解方式)


@Service
public class PersonService {

    @Autowired
    private PersonRepo personRepo;

   /**
     * @Cacheable 应用到读取数据的方法上,先从缓存中读取,如果没有再从DB获取数据,然后把数据添加到缓存中
    * unless 表示条件表达式成立的话不放入缓存
     * @param username
     * @return
     */
    @Cacheable(value = "user", key = "#root.targetClass + #username", unless = "#result eq null")
    public Person getPersonByName(String username) {
        Person person = personRepo.getPersonByName(username);
        return person;
    }

   /**
    * @CachePut 应用到写数据的方法上,如新增/修改方法,调用方法时会自动把相应的数据放入缓存
     * @param person
     * @return
     */
    @CachePut(value = "user", key = "#root.targetClass + #result.username", unless = "#person eq null")
    public Person savePerson(Person person) {
        return personRepo.savePerson(person);
    }

   /**
    * @CacheEvict 应用到删除数据的方法上,调用方法时会从缓存中删除对应key的数据
     * @param username
     * @return
     */
    @CacheEvict(value = "user", key = "#root.targetClass + #username", condition = "#result eq true")
    public boolean removePersonByName(String username) {
        return personRepo.removePersonByName(username) > 0;
    }

    public boolean isExistPersonName(Person person) {
        return personRepo.existPersonName(person) > 0;
    }
}

 
 

你可能感兴趣的:(Java和Jvm)