范培忠 2018-04-18
Spring Boot2.0.
在2018年3月1日正式发布。2.0下对Redis的使用与之前略有不同。具体实现如下:
一、Maven依赖和配置
添加3个依赖:
<dependency>
<groupId></groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--spring2.0集成redis所需common-pool2-->
<dependency>
<groupId></groupId>
<artifactId>commons-pool2</artifactId>
<version>2.5.0</version>
</dependency>
<!-- 将作为Redis对象序列化器 -->
<dependency>
<groupId></groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
配置:
spring:
redis:
#数据库索引
database: 0
host: 127.0.0.1
port: 6379
password: 123
lettuce:
pool:
#最大连接数
max-active: 8
#最大阻塞等待时间(负数表示没限制)
max-wait: -1
#最大空闲
max-idle: 8
#最小空闲
min-idle: 0
#连接超时时间
timeout: 10000
配置:
本配置是为了解决在1.2.24后因修复漏洞导致的autotype is not support错误。
具体解决办法为声明文件,将需要打包的类设置白名单等,如下代码所示。
可参考官方通告:/alibaba/fastjson/wiki/enable_autotype
=.
二、自定义序列化器
若要实现对象的缓存,最好定义自己的序列化和反序列化器。使用阿里的fastjson来实现的比较多。
package .;
import ;
import ;
import ;
import ;
import ;
public class FastJsonRedisSerializer<T> implements RedisSerializer<T> {
private static final Charset DEFAULT_CHARSET = ("UTF-8");
private Class<T> clazz;
public FastJsonRedisSerializer(Class<T> clazz) {
super();
= clazz;
}
@Override
public byte[] serialize(T t) throws SerializationException {
if (null == t) {
return new byte[0];
}
return (t, ).getBytes(DEFAULT_CHARSET);
}
@Override
public T deserialize(byte[] bytes) throws SerializationException {
if (null == bytes || <= 0) {
return null;
}
String str = new String(bytes, DEFAULT_CHARSET);
return (T) (str, clazz);
}
}
三、添加RedisConfig配置
在RedisConfig类里定义RedisTemplate的bean和Redis的CacheManager。
package .;
import .;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
@EnableCaching
@Configuration
@ConditionalOnClass()
@EnableConfigurationProperties()
public class RedisConfig extends CachingConfigurerSupport {
@Bean(name = "redisTemplate")
@SuppressWarnings("unchecked")
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
//使用fastjson序列化
FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer();
// value值的序列化采用fastJsonRedisSerializer
(fastJsonRedisSerializer);
(fastJsonRedisSerializer);
// key的序列化采用StringRedisSerializer
(new StringRedisSerializer());
(new StringRedisSerializer());
(redisConnectionFactory);
return template;
}
/*@Bean
@ConditionalOnMissingBean()
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate template = new StringRedisTemplate();
(redisConnectionFactory);
return template;
}*/
//缓存管理器
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
builder = RedisCacheManager
.RedisCacheManagerBuilder
.fromConnectionFactory(redisConnectionFactory);
return ();
}
}
四、定义用于测试的User类和UserService
User类:
package .;
import ;
public class User implements Serializable {
private static final long serialVersionUID = -1L;
private String username;
private Integer age;
public User(String username, Integer age) {
= username;
= age;
}
//getter和setter省略
}
UserService:
package .;
import .;
import .;
import ;
import ;
@Service
public class UserServiceImpl implements UserService {
@Override
@Cacheable(value = "user", key = "'user_'+#username")
public User getUser(String username) {
(username + "进入实现类获取数据!");
return new User("Ttomm", 22);
}
}
五、编写测试类
package .springbootdemoredis3;
import .;
import .;
import ;
import ;
import ;
import ;
import ;
import ;
import .;
@SuppressWarnings("unchecked")
@RunWith()
@SpringBootTest
public class SpringBootDemoRedis3ApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private UserService userService;
@Test
//直接使用redisTemplate存取字符串
public void setAndGet() {
().set("test:set", "testValue1");
("testValue1", ().get("test:set"));
}
@Test
//直接使用redisTemplate存取对象
public void setAndGetAUser() {
User user = new User("Tom", 10);
().set("test:setUser", user);
((), ((User) ().get("test:setUser")).getUsername());
}
@Test
//使用Redis缓存对象,getUser只会被调用一次
public void testCache() {
User user;
user = ("Ttomm");
user = ("Ttomm");
user = ("Ttomm");
}
}
六、执行效果
testCache()的执行效果如下,可见后台日志显示方法仅被实际调用了一次,缓存成功: