Redis+lettuce
一、新建一个项目
使用Intellij IDEA新建一个SpringBoot项目
修改新项目的信息
勾选组件,
启动windows环境下的Redis服务端,默认端口为6379。
客户端不需要启动的,本机的地址为127.0.0.1
修改项目的配置文件
spring:
redis:
port: 6379
host: 127.0.0.1
到测试类中简单做个测试
package com.redisbase;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
@SpringBootTest
class RedisBaseApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads() {
redisTemplate.opsForValue().set("ii","44");
System.out.println(redisTemplate.opsForValue().get("ii"));
}
}
可以看到控制台中打印出了结果
但是,如果到Redis客户端中查看的话,会显示乱码,这是因为写入内存的时候序列化方式使用的默认的JDK序列化,要解决这个问题就要自定义序列化的方式。
新建一个config包,再建一个名为RedisConfig的配置类。
package com.redisbase.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
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;
/**
* @author gaolingfeng
*/
@Configuration
public class RedisConfig {
@Bean
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
//为了开发方便,一般直接使用<String,Object>
RedisTemplate<String, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
//Json序列化配置
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance ,
ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
//string 的序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
//key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
//hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
//value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
//hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
再启动以下测试类。查看Redis中的数据如下。如果存入的是POJO对象,只需要将对象实现序列化就好了。
测试下往Redis存入一个实现序列化的对象
import java.io.Serializable;
/**
* @author gaolingfeng
*/
public class User implements Serializable {
private String name;
private Integer age;
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
public Integer getAge(){
return this.age;
}
public void setAge(Integer age){
this.age = age;
}
@Override
public String toString(){
return "name:"+name+",age:"+age;
}
}
往测试类中加入下面代码,点击运行。
@Test
void testPojo() {
User user = new User();
user.setName("王");
user.setAge(23);
redisTemplate.opsForValue().set("user",user);
System.out.println(redisTemplate.opsForValue().get("user")。toString());
}
查看Redis客户端中的内容(控制台的原因,value中的中文还是转意的字符)。
依赖下载完成后,进入POM文件中,找到Redis的依赖
SpringBoot2.x之后,原来使用的jedis被替换为了lettuce
- jedis:采用的直连,多个线程操作的话是不安全的,如果想要避免不安全,使用jedis pool连接池!更像BIO模式
- lettuce:采用netty,实例可以在多个线程中进行共享,不存在线程不安全的情况!可以减少线程数据了,更像NIO模式
Redis依赖包源码,可以看到如果自己配置了Redis,自带的配置就不生效(@ConditionalOnMissingBean)
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnClass({RedisOperations.class})
@EnableConfigurationProperties({RedisProperties.class})
@Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
public class RedisAutoConfiguration {
public RedisAutoConfiguration() {
}
@Bean
@ConditionalOnMissingBean(
name = {"redisTemplate"}
)
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
//默认的RedisTemplate,没有过多的设置
RedisTemplate<Object, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
//由于String类型太常用,所以单独定义了了个方法
@Bean
@ConditionalOnMissingBean
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}