springboot自定义RedisTemplate并使用jedis配置连接池
springboot自定义RedisTemplate并使用jedis配置连接池使用Jedis线程池可以不需要创建新的Jedis对象连接Redis,可以大大减少对于创建和回收Redis连接的开销@Primary: 当出现相同名字的bean是,优先使用使用了 @Primary 注解的bean下面开始使用:1、第一步我们需要导入相应的jar包<!--redis--><dependenc
springboot自定义RedisTemplate并使用jedis配置连接池
使用Jedis线程池可以不需要创建新的Jedis对象连接Redis,可以大大减少对于创建和回收Redis连接的开销
@Primary: 当出现相同名字的bean是,优先使用使用了 @Primary 注解的bean
下面开始使用:
1、第一步我们需要导入相应的jar包
<!-- redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- Redis连接Java工具 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.2.0</version>
</dependency>
2、在application.yaml里配置我们想要的配置
redis:
# 可配置参数:https://www.bbsmax.com/A/x9J2RXbMJ6/
#地址
host: 127.0.0.1
#端口号
port: 6379
database: 0
#如果有密码,请填写
password:
#连接超时时间
timeout: 3000
#最大空闲连接数
maxIdle: 200
#最大连接数(空闲+等待)
maxTotal: 500
#最大建立连接等待时间。如果超时抛出异常。设为-1表示无限制。
maxWaitMillis: 1000
#连接多久没有使用设置为闲置,检测线程直接剔除闲置
minEvictableIdleTimeMillis: 300000
#每次释放连接的最大数目,默认3
numTestsPerEvictionRun: 1024
# 后台检测线程周期 逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
timeBetweenEvictionRunsMillis: 30000
#是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
testOnBorrow: true
#后台线程对idle连接进行扫描,检测是否有效
testWhileIdle: true
3、我们需要创建一个RedisConfig配置的Java文件,读取我们配置的参数
@Configuration
public class RedisConfig {
@Value("${redis.host}")
private String host;
@Value("${redis.port}")
private Integer port;
@Value("${redis.database}")
private Integer database;
@Value("${redis.password}")
private String password;
@Value("${redis.timeout}")
private Integer timeout;
@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;
}
4、根据要求,我们需要配置一个Redis连接池,直接在 RedisConfig 里注入一个Bean
@Bean("jzRedisTemplate")
@Primary
public JedisPoolConfig jedisPoolConfig(){
//创建连接池对象
JedisPoolConfig jedisPoolConfig=new JedisPoolConfig();
//最大空闲数
jedisPoolConfig.setMaxIdle(maxIdle);
//连接池最大连接数数据库数量
jedisPoolConfig.setMaxTotal(maxTotal);
//连接最大等待时间
jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
//逐出连接最小空空闲时间
jedisPoolConfig.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
//每次逐出的最大数量
jedisPoolConfig.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
//逐出扫描时间的间隔
jedisPoolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
//是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
jedisPoolConfig.setTestOnBorrow(testOnBorrow);
//空闲时检查有效性
jedisPoolConfig.setTestWhileIdle(testWhileIdle);
return jedisPoolConfig;
}
5、配置好了连接池,同样的,我们需要在 RedisConfig 里配置一个 Redis 工厂( 有点理解难度,所以解释了很多 )
先看配置的源码,再看为什么这么配哦!
JedisConnectionFactory并没有直接设置连接池的方法,所以我们需要通过 JedisPoolingClientConfigurationBuilder 去设置连接池,并且设置一些关于连接池的属性。
**解释一:**调用 JedisClientConfiguration.builder() 生成一个 JedisClientConfigurationBuilder 对象,我们可以在源码里查看到 JedisClientConfigurationBuilder 接口可以设置连接池
/**
* Enable connection-pooling.
* <p />
* Applies only to single node Redis. Sentinel and Cluster modes use always connection-pooling regardless of the
* pooling setting.
*
* @return {@link JedisPoolingClientConfigurationBuilder}.
*/
JedisPoolingClientConfigurationBuilder usePooling();
/**
* @param poolConfig must not be {@literal null}.
* @return {@literal this} builder.
* @throws IllegalArgumentException if poolConfig is {@literal null}.
*/
JedisPoolingClientConfigurationBuilder poolConfig(GenericObjectPoolConfig poolConfig);
配置好以后,我们还需要 创建工厂对象
//工厂对象
JedisConnectionFactory factory=new JedisConnectionFactory(redisStandaloneConfiguration,jedisClientConfiguration.build());
查看 JedisConnectionFactory 的构造方法,我们需要的是一个 JedisClientConfiguration 对象,而不是 JedisClientConfigurationBuilder对象,所以我们需要调用 JedisClientConfigurationBuilder 类提供的 build() 方法创造一个 JedisClientConfiguration 对象。
/**
* Constructs a new {@link JedisConnectionFactory} instance using the given {@link RedisStandaloneConfiguration} and
* {@link JedisClientConfiguration}.
*
* @param standaloneConfig must not be {@literal null}.
* @param clientConfig must not be {@literal null}.
* @since 2.0
*/
public JedisConnectionFactory(RedisStandaloneConfiguration standaloneConfig, JedisClientConfiguration clientConfig) {
this(clientConfig);
Assert.notNull(standaloneConfig, "RedisStandaloneConfiguration must not be null!");
this.standaloneConfig = standaloneConfig;
}
/**
* Build the {@link JedisClientConfiguration} with the configuration applied from this builder.
*
* @return a new {@link JedisClientConfiguration} object.
*/
JedisClientConfiguration build();
配置工厂类
@Bean("jedisConnectionFactory")
@Primary
public JedisConnectionFactory jedisConnectionFactory(@Qualifier("jedisPoolConfig") JedisPoolConfig jedisPoolConfig){
//redis连接配置
RedisStandaloneConfiguration redisStandaloneConfiguration=new RedisStandaloneConfiguration();
//设置连接的ip
redisStandaloneConfiguration.setHostName(host);
//设置密码
redisStandaloneConfiguration.setPassword(RedisPassword.of(password));
//端口号
redisStandaloneConfiguration.setPort(port);
//连接的数据库
redisStandaloneConfiguration.setDatabase(database);
//JedisConnectionFactory配置jedisPoolConfig
JedisClientConfiguration.JedisClientConfigurationBuilder jedisClientConfiguration = JedisClientConfiguration.builder();
//客户端超时时间单位是毫秒
jedisClientConfiguration.connectTimeout(Duration.ofMillis(timeout));
//连接池
jedisClientConfiguration.usePooling().poolConfig(jedisPoolConfig);
//工厂对象
JedisConnectionFactory factory=new JedisConnectionFactory(redisStandaloneConfiguration,jedisClientConfiguration.build());
return factory;
}
6、配置好了 Redis 工厂和连接池后,我们只需要配置自定义的 RedisTemplate 了
@Bean("RedisTemplateTest")
public RedisTemplate<String,Object> RedisTemplate(@Qualifier("jedisConnectionFactory") RedisConnectionFactory redisConnectionFactory){
RedisTemplate<String,Object> redisTemplate=new RedisTemplate<>();
initRedisTemplate(redisTemplate,redisConnectionFactory);
return redisTemplate;
}
/**
* @deprecated : 初始化RedisTemplate的配置,配置序列化and工厂
* @param redisTemplate
* @return
*/
public void initRedisTemplate(RedisTemplate<String,Object> redisTemplate, RedisConnectionFactory factory){
// json 序列化配置,序列化所有对象
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会抛出异常
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// string 的序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
redisTemplate.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
redisTemplate.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
//设置连接工厂
redisTemplate.setConnectionFactory(factory);
}
这样我们就已经配置好了 Redis 连接池和自定义 RedisTemplate 了,但是建议对 RedisTemplate 再进行一层封装,封装一个 RedisUtil 类
7、封装 RedisUtil 类
public class RedisUtil {
private RedisTemplate<String,Object> redisTemplate;
public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
//...一些封装的方法
}
在 RedisConfig 里配置一个 Bean,这个便是我们要使用的 RedisTemplate ,这里做的是进一步封装
@Bean("RedisUtil")
@Primary
public RedisUtil redisUtil(@Qualifier("RedisTemplateTest") RedisTemplate<String,Object> redisTemplate){
RedisUtil redisUtil=new RedisUtil();
redisUtil.setRedisTemplate(redisTemplate);
return redisUtil;
}
8、使用,在test类里自动注解,然后就可以使用了
@Autowired
private RedisUtil redisUtil;
@Test
void contextLoads() {
System.out.println(redisUtil.set("name","future"));
System.out.println(redisUtil.get("name"));
}
更多推荐
所有评论(0)