Spring Boot 1.5.x 整合Redis

Published on with 0 views and 0 comments

  1. 添加依赖

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

    该依赖里默认包含了spring-data-redis和Jedis依赖,见这里

  2. 添加配置文件

    	# REDIS (RedisProperties)
    	# Redis数据库索引(默认为0)
    	spring.redis.database=0
    	# Redis服务器地址
    	spring.redis.host=192.168.0.58
    	# Redis服务器连接端口
    	spring.redis.port=6379
    	# Redis服务器连接密码(默认为空)
    	spring.redis.password=
    	# 连接池最大连接数(使用负值表示没有限制)
    	spring.redis.pool.max-active=8
    	# 连接池最大阻塞等待时间(使用负值表示没有限制)
    	spring.redis.pool.max-wait=-1
    	# 连接池中的最大空闲连接
    	spring.redis.pool.max-idle=8
    	# 连接池中的最小空闲连接
    	spring.redis.pool.min-idle=0
    	# 连接超时时间(毫秒)
    	spring.redis.timeout=0
    
  3. 添加cache的配置类

    spring boot在Spring Data Redis提供了两个模板:

    • RedisTemplate

    • StringRedisTemplate

    RedisTemplate会使用JdkSerializationRedisSerializer处理数据,这意味着key和value都会通过Java进行序列化。

    StringRedisTemplate默认会使用StringRedisSerializer处理数据。

    要是操作字符串的话,用StringRedisTemplate就可以满足。但要是想要存储一个对象Object,我们就需要使用RedisTemplate,并对key采用String序列化方式,对value采用json序列化方式,这时候就需要对redisTemplate自定义配置

    	/**
    	 * @author liyf
    	 * Created in 2018\11\8
    	**/
    	@Configuration
    	@EnableCaching//启用缓存,这个注解很重要;
    	public class RedisCacheConfig {
    
    	 /**
    	  * 功能描述: 缓存管理器
    	  *
    	  * @param [redisTemplate]
    	  * @return org.springframework.cache.CacheManager
    	  * @author liyf
    	 **/
    	@Bean
    	public CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate) {
    	RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
    	// 设置缓存过期时间(单位:秒)
    	rcm.setDefaultExpiration(60 * 24);
    	return rcm;
    	 }
    
    	  @Bean
    	  public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
    
    	  RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
    
    	  redisTemplate.setConnectionFactory(factory);
    	  //key序列化方式;(不然会出现乱码;),但是如果方法上有Long等非String类型的话,会报类型转换错误;
    	  //所以在没有自己定义key生成策略的时候,以下这个代码建议不要这么写,可以不配置或者自己实现ObjectRedisSerializer
    	  //或者JdkSerializationRedisSerializer序列化方式;
    	  RedisSerializer<String> redisSerializer = new StringRedisSerializer();//Long类型不可以会出现异常信息;
    	  redisTemplate.setKeySerializer(redisSerializer);
    	  redisTemplate.setHashKeySerializer(redisSerializer);
    	  return redisTemplate;
    	   }
    
    	/**
    	 * 功能描述: 自定义key.
    	 *
    	 * @param []
    	 * @return org.springframework.cache.interceptor.KeyGenerator
    	 * @author liyf
    	**/
    	@Override
    	public KeyGenerator keyGenerator() {
    
    	System.out.println("RedisCacheConfig.keyGenerator()");
    	return (o, method, objects) -> {
    
    	// This will generate a unique key of the class name, the method name
    	//and all method parameters appended.
    	StringBuilder sb = new StringBuilder();
    	String[] value = new String[1];
    	// sb.append(target.getClass().getName());
    // sb.append(":" + method.getName());
    	Cacheable cacheable = method.getAnnotation(Cacheable.class);
    	if (cacheable != null) {
    	  value = cacheable.value();
    	}
    
    	  CachePut cachePut = method.getAnnotation(CachePut.class);
    
    	  if (cachePut != null) {
    
    	  value = cachePut.value();
    
    	  }
    
    		  CacheEvict cacheEvict = method.getAnnotation(CacheEvict.class);
    
    		  if (cacheEvict != null) {
    
    		  value = cacheEvict.value();
    
    		  }
    
    		  sb.append(value[0]);
    
    		  for (Object obj : objects) {
    
    		  sb.append(obj.toString());
    
    		  }
    
    		  return sb.toString();
    
    		  };
    
    	}
    
    	}
    
    
    • 注意:

    要缓存的 Java 对象必须实现 Serializable 接口,因为 Spring 会将对象先序列化再存入 Redis,如果不实现 Serializable 的话将会遇到类似这种错误:nested exception is java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type xxx

  4. 通过注解对数据进行缓存处理

    
    	@Service
    
    	public class UserServiceImpl implements UserService {
    
    	  private final UserRepository userRepository;
    
    	  @Autowired
    	  public UserServiceImpl(UserRepository userRepository) {
    		this.userRepository = userRepository;
    	  }
    
    	  @CachePut(value = "userInfo", key = "#root.caches[0].name + #user.uid")
    	  @Override
    	  public User saveUser(User user) {
    
    		return userRepository.save(user);
    
    	  }
    
    	  @Override
    	  @Cacheable(value = "userInfo")
    	  public User getUser(Long uid) {
    
    		System.out.println("从数据库中进行获取的....uid=" + uid);
    
    		return userRepository.findOne(uid);
    
    	  }
    
    	}
    
    
  5. 测试