spring-boot学习:十七、spring-boot集成redis

在springboot1.x中默认使用Jedis,而在springboot2.x中默认使用lettuce。

为什么使用lettuce替换jedis呢?

Jedis在实现上是直连的redis server,在多线程环境下是非线程安全的,这个时候只有使用连接池,为每个Jedis实例增加物理连接;

Lettuce的连接是基于Netty的,连接实例(StatefulRedisConnection)可以在多个线程间并发访问,因为StatefulRedisConnection是线程安全的,所以一个连接实例就可以满足多线程环境下的并发访问;

  • 默认使用lettuce (推荐使用)
    1)pom.xml中引入jar包
 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-pool2</artifactId>
</dependency>

2)application.properties配置redis

spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=123
spring.redis.lettuce.pool.max-active=500
spring.redis.lettuce.pool.max-idle=300
spring.redis.lettuce.pool.max-wait=1000
spring.redis.lettuce.pool.min-idle=0
spring.redis.database=8
  1. 注册redis序列化
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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 com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;

@Configuration
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisCacheConfig {

	@Bean
   public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory, RedisSerializer<Object> redisSerializer) {
       RedisTemplate<String, Object> template = new RedisTemplate<>();
       template.setConnectionFactory(redisConnectionFactory);

       //RedisTemplate对象需要指明Key序列化方式,如果声明StringRedisTemplate对象则不需要
       template.setKeySerializer(StringRedisSerializer.UTF_8);
       template.setValueSerializer(redisSerializer);

       template.setHashKeySerializer(StringRedisSerializer.UTF_8);
       template.setHashValueSerializer(redisSerializer);
       
       //template.setEnableTransactionSupport(true);//是否启用事务
       template.afterPropertiesSet();
       
       return template;
   }

   /**
    * 自定义redis序列化的机制
    *
    * @return
    */
   @Bean
   public RedisSerializer<Object> redisSerializer() {

       ObjectMapper objectMapper = new ObjectMapper();
       //反序列化时候遇到不匹配的属性并不抛出异常
       objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
       //序列化时候遇到空对象不抛出异常
       objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
       //反序列化的时候如果是无效子类型,不抛出异常
       objectMapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false);

       //指定DATE序列化格式,默认时间戳
       objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

       //不使用默认的dateTime进行序列化,
       objectMapper.configure(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS, false);
       //使用JSR310提供的序列化类,里面包含了大量的JDK8时间序列化类
       JavaTimeModule javaTimeModule = new JavaTimeModule();
       javaTimeModule.addSerializer(LocalDateTime.class,new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")));
       javaTimeModule.addDeserializer(LocalDateTime.class,new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")));
       objectMapper.registerModule(javaTimeModule);

       //指定序列化输入的类型@class  JsonTypeInfo.As.PROPERTY-表示以对象属性的形式  WRAPPER_ARRAY-表示以数组的形式
       objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
       //配置null值的序列化器
       GenericJackson2JsonRedisSerializer.registerNullValueSerializer(objectMapper, null);
       return new GenericJackson2JsonRedisSerializer(objectMapper);
   }
	
}
  1. 使用RedisTemplate
import com.kevin.core.result.ApiResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

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

/**
 * @author kevin
 * @create 2020/8/7 14:42
 */
@ApiResult
@RestController
public class TestController {
    @Autowired
    private RedisTemplate redisTemplate;

    @GetMapping(value="/test",produces= MediaType.APPLICATION_JSON_VALUE)
    public Object test(){
        Map<String, Object> user=new HashMap<>();
        user.put("id", 1);
        user.put("name","kevin");
        user.put("createTime", LocalDateTime.now());
        redisTemplate.opsForValue().set("user:"+user.get("id"), user);

        return redisTemplate.opsForValue().get("user:"+user.get("id"));
    }
}
  1. 测试
    在这里插入图片描述
    在这里插入图片描述
  • 继续使用jedis
    因为一些历史遗留问题,比如老代码中使用了jedis不想调整,想继续使用jedis,只需调整一下配置即可。
  1. pom.xml引入jar包(排除lettuce,引入jedis)
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
	<exclusions>
		<exclusion>
			<groupId>io.lettuce</groupId>
			<artifactId>lettuce-core</artifactId>
		</exclusion>
	</exclusions>
</dependency>
<dependency>
	<groupId>redis.clients</groupId>
	<artifactId>jedis</artifactId>
</dependency>
  1. application.properties配置jedis
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=123
spring.redis.jedis.pool.max-active=500
spring.redis.jedis.pool.max-idle=300
spring.redis.jedis.pool.max-wait=1000
spring.redis.jedis.pool.min-idle=0
spring.redis.database=8

猜你喜欢

转载自blog.csdn.net/guangcaiwudong/article/details/107927854