Redis是一个基于内存的日志型可持久化的缓存数据库,SpringBoot框架良好的对Redis进行了整合,本章节主要讲解如何在SpringBoot中配置Redis。
一、在Maven中添加Redis依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
二、Redis的三种加载配置方式
1. AutoConfig加载,在application.properties 应用程序属性文件配置
#Redis 有16个数据库,指定第1个。在程序中也可以设置。
spring.redis.database=0
#redis服务器地址
spring.redis.host=127.0.0.1
#Redis端口
spring.redis.port=6379
# 连接超时时间 单位 ms(毫秒)
spring.redis.timeout=3000
# 连接池中的最大空闲连接,默认值也是8。
spring.redis.jedis.pool.max-idle=8
#连接池中的最小空闲连接,默认值也是0。
spring.redis.jedis.pool.min-idle=0
# 如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
spring.redis.jedis.pool.max-active=8
# 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException
spring.redis.jedis.pool.max-wait=-1
然后再启动 Redis 服务器,此时,我们已经完成了Redis的所有配置,可以直接来使用了,我们写一个测试用例来测试一下,注意在SpringBoot程序的入口上要添加 @EnableCaching 注解,启动缓存配置。
@Autowired
RedisTemplate<String,Object> rt;
@RequestMapping("/add/{key}/{val}")
public String add(@PathVariable String key,@PathVariable String val) {
//键值,过期时间,时间设置
rt.opsForValue().set(key, val, 120,TimeUnit.SECONDS);
return "ok";
}
访问此URL:http://localhost:8080/add/name/张明,打开Redis Desktop Manager 图形界面管理器,查看数据如下:
注意代码中操作数据的对象,RedisTemplate<String,Object> rt; 此对象前加了@Autowired注解,由Spring自动注入到程序中,此对象是在SpringBoot 程序启动时自动配置的。在package org.springframework.boot.autoconfigure.data.redis 包 RedisAutoConfiguration 类下。原代码如下:
/*
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.data.redis;
import java.net.UnknownHostException;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
/**
* {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Redis support.
*
* @author Dave Syer
* @author Andy Wilkinson
* @author Christian Dupuis
* @author Christoph Strobl
* @author Phillip Webb
* @author Eddú Meléndez
* @author Stephane Nicoll
* @author Marco Aust
* @author Mark Paluch
*/
@Configuration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(
RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean
public StringRedisTemplate stringRedisTemplate(
RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
但是,这个RedisTemplate的泛型是<Object,Object>,写代码不方便,需要写好多类型转换的代码;我们需要一个泛型为<String,Object>形式的RedisTemplate。并且,这个RedisTemplate没有设置数据存在Redis时,key及value的序列化方式。
看到这个@ConditionalOnMissingBean注解后,就知道如果Spring容器中有了RedisTemplate对象了,这个自动配置的RedisTemplate不会实例化。因此我们可以直接自己写个配置类,配置RedisTemplate。
2. 自己写代码配置 RedisTemplate
application.properties 文件不变
创建RedisConfig类来配置RedisTemplate对象
package com.icss.springbootRedis;
import org.springframework.beans.factory.annotation.Value;
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
public class RedisConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.timeout}")
private int timeout;
@Value("${spring.redis.database}")
private int database;
@Value("${spring.redis.jedis.pool.max-idle}")
private int maxIdle;
@Value("${spring.redis.jedis.pool.min-idle}")
private int minIdle;
/**
* redis模板,存储关键字是字符串,值是Jdk序列化
*
* @Description:
* @param factory
* @return
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
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;
}
}
数据操作代码不需要改变,操作结果一样。
3. 运用 xml 配置 RedisTemplate
application.properties 文件内容不变
在程序入口添加xml文件加载: @ImportResource(locations={"classpath:spring-redis.xml"}) 此文件在resources目录下
文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="minIdle" value="${spring.redis.jedis.pool.min-idle}"/>
<property name="maxIdle" value="${spring.redis.jedis.pool.max-idle}"/>
<property name="maxWaitMillis" value="10000"/>
</bean>
<bean id="jedisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="usePool" value="true"></property>
<property name="hostName" value="${spring.redis.host}"/>
<property name="port" value="${spring.redis.port}"/>
<property name="timeout" value="${spring.redis.timeout}" />
<property name="database" value="0"></property>
<constructor-arg ref="jedisPoolConfig" />
</bean>
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory" />
<property name="KeySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<property name="ValueSerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
</property>
<property name="HashKeySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<property name="HashValueSerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
</property>
</bean>
</beans>
在Pom.xml文件中添加jedis依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
数据操作代码不变,访问URL:http://localhost:8080/add/age/21 结果如下: