前言
在本篇文章中将SpringBoot整合Redis,使用的是RedisTemplate,分别实现了SpringBoot与redis的单机版的整合。
Maven依赖
org.springframework.boot
spring-boot-starter-data-redis
项目下载及目录结构
修改配置文件
创建一个redis.properties配置文件。
#ip地址
redis.hostName=192.168.177.128
#端口号
redis.port=6382
#如果有密码
redis.password=
#客户端超时时间单位是毫秒 默认是2000
redis.timeout=10000
#最大空闲数
redis.maxIdle=300
#连接池的最大数据库连接数。设为0表示无限制,如果是jedis 2.4以后用redis.maxTotal
#redis.maxActive=600
#控制一个pool可分配多少个jedis实例,用来替换上面的redis.maxActive,如果是jedis 2.4以后用该属性
redis.maxTotal=1000
#最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
redis.maxWaitMillis=1000
#连接的最小空闲时间 默认1800000毫秒(30分钟)
redis.minEvictableIdleTimeMillis=300000
#每次释放连接的最大数目,默认3
redis.numTestsPerEvictionRun=1024
#逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
redis.timeBetweenEvictionRunsMillis=30000
#是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
redis.testOnBorrow=true
#在空闲时检查有效性, 默认false
redis.testWhileIdle=true
SpringBoot整合单机版redis
package cn.temptation.config;
import java.time.Duration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;
@Configuration
@PropertySource("classpath:config/redis.properties")
public class RedisConfig {
@Value("${redis.maxIdle}")
private Integer maxIdle;
@Value("${redis.maxTotal}")
private Integer maxTotal;
@Value("${redis.maxWaitMillis}")
private Integer maxWaitMillis;
@Value("${redis.minEvictableIdleTimeMillis}")
private Integer minEvictableIdleTimeMillis;
@Value("${redis.numTestsPerEvictionRun}")
private Integer numTestsPerEvictionRun;
@Value("${redis.timeBetweenEvictionRunsMillis}")
private long timeBetweenEvictionRunsMillis;
@Value("${redis.testOnBorrow}")
private boolean testOnBorrow;
@Value("${redis.testWhileIdle}")
private boolean testWhileIdle;
/*@Value("${spring.redis.cluster.nodes}")
private String clusterNodes;
@Value("${spring.redis.cluster.max-redirects}")
private Integer mmaxRedirectsac;*/
/**
* JedisPoolConfig 连接池
* @return
*/
@Bean
public JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
// 最大空闲数
jedisPoolConfig.setMaxIdle(maxIdle);
// 连接池的最大数据库连接数
jedisPoolConfig.setMaxTotal(maxTotal);
// 最大建立连接等待时间
jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
// 逐出连接的最小空闲时间 默认1800000毫秒(30分钟)
jedisPoolConfig.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
// 每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3
jedisPoolConfig.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
// 逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
jedisPoolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
// 是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
jedisPoolConfig.setTestOnBorrow(testOnBorrow);
// 在空闲时检查有效性, 默认false
jedisPoolConfig.setTestWhileIdle(testWhileIdle);
return jedisPoolConfig;
}
/**
* 单机版配置
* @Title: JedisConnectionFactory
* @param @param jedisPoolConfig
* @param @return
* @return JedisConnectionFactory
* @autor lpl
* @date 2018年2月24日
* @throws
*/
@Bean
public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig jedisPoolConfig){
JedisConnectionFactory JedisConnectionFactory = new JedisConnectionFactory(jedisPoolConfig);
/*
//连接池
JedisConnectionFactory.setPoolConfig(jedisPoolConfig);
//IP地址
JedisConnectionFactory.setHostName("127.0.0.1");
//端口号
JedisConnectionFactory.setPort(6379);
//如果Redis设置有密码
//JedisConnectionFactory.setPassword(password);
//客户端超时时间单位是毫秒
JedisConnectionFactory.setTimeout(5000);
*/
//pringboot 2.x版本 JedisConnectionFactory 设置连接已过时
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration ();
redisStandaloneConfiguration.setHostName("127.0.0.1");
redisStandaloneConfiguration.setPort(6379);
redisStandaloneConfiguration.setDatabase(1);
//redisStandaloneConfiguration.setPassword(RedisPassword.of(password));
JedisClientConfiguration.JedisClientConfigurationBuilder jedisClientConfiguration = JedisClientConfiguration.builder();
jedisClientConfiguration.connectTimeout(Duration.ofMillis(1800));// connection timeout
return JedisConnectionFactory;
}
/**
* 实例化 RedisTemplate 对象
*
* @return
*/
@Bean//(name = "redisTemplate")
public RedisTemplate functionDomainRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate redisTemplate = new RedisTemplate<>();
initDomainRedisTemplate(redisTemplate, redisConnectionFactory);
return redisTemplate;
}
/**
* 设置数据存入 redis 的序列化方式,并开启事务
*
* @param redisTemplate
* @param factory
*/
private void initDomainRedisTemplate(RedisTemplate redisTemplate, RedisConnectionFactory factory) {
//如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
// 开启事务
redisTemplate.setEnableTransactionSupport(true);
redisTemplate.setConnectionFactory(factory);
}
}
测试:
package cn.temptation;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import cn.temptation.bean.User;
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
public class RedisTest {
@Autowired
private RedisTemplate redisTemplate;//需要在配置中声明@Bean(name = "redisTemplate"),不然乱码或者直接使用下面那种注入
//@Autowired
//private RedisTemplate redisTemplate;
@Test
public void testSet() {
/*User vo = new User() ;
vo.setUserid(19);
vo.setUsername("username");
//this.redisTemplate.opsForValue().set("study", vo);
System.out.println("study-set1:");
this.redisTemplate.opsForValue().set("study", vo , 1000,TimeUnit.SECONDS);
System.out.println("study-set1:");*/
}
@Test
public void testGet() {
User vo = new User() ;
vo.setUserid(19);
vo.setUsername("username");
//this.redisTemplate.opsForValue().set("study", vo);
System.out.println("study-set1:");
this.redisTemplate.opsForValue().set("study", vo , 1000,TimeUnit.SECONDS);
System.out.println("study-set1:");
System.out.println("study-get:"+this.redisTemplate.opsForValue().get("study"));
}
}
在这里可以看到redis序列化有乱码,也就是我们的配置没有生效,所以我们需要重新修改配置文件,
Debug调试可以看到set的时候使用的是JdkSerializationRedisSerializer而不是我们配置的StringRedisSerializer
在实例化bean的时候加上(name = “redisTemplate”)
/**
* 实例化 RedisTemplate 对象
*
* @return
*/
@Bean(name = “redisTemplate”)
public RedisTemplate
RedisTemplate
initDomainRedisTemplate(redisTemplate, redisConnectionFactory);
return redisTemplate;
}
再次测试可以看到序列化时使用的是我们配置的类型
问题应该出现在注入bean的时候redisTemplate不是唯一的,所以我们需要在配置的时候指定name = “redisTemplate”