Spring-Boot快速集成Jedis(封装多种模板)
Jedis是Redis官方推荐的Java连接开发工具,提供redis最低层的指令,提供池化操作,执行效率高
虽然spring-boot的就提供redis操作的组件,因为高度封装的原因,RedisTemplate效率比不上jedis的效率。
第一步、引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 引入Jredis-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.5.2</version>
</dependency>
第二步、定义配置
yml配置文件
#BlogRedis配置
club.dlblog.jedis:
host: 127.0.0.1 #IP地址
port: 6379 #端口
auth: #认证密码
maxActive: 1024 #最带连接数
maxIdle: 200 #最大闲置数
maxWait: 10000 #最大等待时间
timeOut: 10000 #连接超时时间
testOnBorrow: true #连接完是否测试连接
defaultDataBase: 0 #默认数据库
clientName: dlblog-jedis-client #连接客户端名
auto.destory.ms: 10000 #jedis实例自动回收时间
配置类
/**
* Jedis配置类
* @author machenike
*/
@Configuration
public class JedisConfig {
/**
* 服务器IP地址
*/
@Value("${club.dlblog.jedis.host}")
private String host;
/**
* 端口
*/
@Value("${club.dlblog.jedis.port}")
private Integer port;
/**
* 密码
*/
@Value("${club.dlblog.jedis.auth}")
private String auth;
/**
* 连接实例的最大连接数
*/
@Value("${club.dlblog.jedis.maxActive}")
private Integer maxActive;
/**
* 控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。
*/
@Value("${club.dlblog.jedis.maxIdle}")
private Integer maxIdle;
/**
* 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间
*/
@Value("${club.dlblog.jedis.maxWait}")
private Integer maxWait;
/**
* 连接超时的时间
*/
@Value("${club.dlblog.jedis.timeOut}")
private Integer timeOut;
/**
* 在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;
*/
@Value("${club.dlblog.jedis.testOnBorrow}")
private boolean testOnBorrow;
/**
* 数据库模式是16个数据库 0~15
*/
@Value("${club.dlblog.jedis.defaultDataBase}")
private Integer defaultDataBase;
/**
* redis连接客户端名称
*/
@Value("${club.dlblog.jedis.clientName}")
private String clientName;
/**
* 初始jedisPool配置
* @return
*/
@Bean
public JedisPoolConfig jedisPoolConfig(){
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
if(maxActive!=null) {
jedisPoolConfig.setMaxTotal(maxActive);
} else {
jedisPoolConfig.setMaxTotal(1024);
}
if(maxIdle!=null){
jedisPoolConfig.setMaxIdle(maxIdle);
} else {
jedisPoolConfig.setMaxIdle(200);
}
if(maxWait!=null){
jedisPoolConfig.setMaxWaitMillis(maxWait);
}else {
jedisPoolConfig.setMaxWaitMillis(10000);
}
if(maxWait!=null) {
jedisPoolConfig.setTestOnBorrow(testOnBorrow);
} else {
jedisPoolConfig.setTestOnBorrow(true);
}
return jedisPoolConfig;
}
/**
* 初始化jedisPool
* @param jedisPoolConfig
* @return
*/
@Bean
public JedisPool jedisPool(@Qualifier("jedisPoolConfig")JedisPoolConfig jedisPoolConfig){
if(StringUtils.isEmpty(auth)){
auth = null;
}
JedisPool jedisPool = new JedisPool(jedisPoolConfig, host,port,timeOut,auth,defaultDataBase,clientName);
return jedisPool;
}
}
第三步、模板实例管理服务创建
/**
* jedis服务
* @author machenike
*/
@EnableScheduling
@Service
public class JedisServiceImpl implements JedisService {
/**
* jedis连接池
*/
@Autowired
private volatile JedisPool jedisPool;
/**
* 字符串jedis模板
*/
private StringJedis stringJedis;
/**
* listjedis模板
*/
private ListJedis listJedis;
/**
* Mapjedis模板
*/
private MapJedis mapJedis;
/**
* set模板
*/
private SetJedis setJedis;
/**
* zset模板
*/
private ZSetJedis zSetJedis;
/**
* 自动回收时间差
*/
@Value("${club.dlblog.jedis.auto.destory.ms}")
private Long autoDestoryMs;
/**
* 使用字符串模板
* @return
*/
@Override
public StringJedis asString() {
stringJedis = StringJedisImpl.getInstance(getJedis());
return stringJedis;
}
/**
* 使用list模板
* @return
*/
@Override
public ListJedis asList() {
listJedis = ListJedisImpl.getInstance(getJedis());
return listJedis;
}
/**
* 使用map模板
* @return
*/
@Override
public MapJedis asMap() {
mapJedis = MapJedisImpl.getInstance(getJedis());
return mapJedis;
}
/**
* 使用set模板
* @return
*/
@Override
public SetJedis asSet() {
setJedis = SetJedisImppl.getInstance(getJedis());
return setJedis;
}
/**
* 使用zset模板
* @return
*/
@Override
public ZSetJedis asZSet() {
zSetJedis = ZSetJedisImpl.getInstance(getJedis());
return zSetJedis;
}
/**
* jedis实例取得
* @return
*/
@Override
public synchronized Jedis getJedis() {
Jedis jedis =null;
if(jedisPool!=null){
jedis = jedisPool.getResource();
}
return jedis;
}
/**
* 自动回收jedis实例
*/
@Scheduled(cron = "*/5 * * * * ?")
public void autoReturnSource(){
if(stringJedis instanceof StringJedisImpl){
StringJedisImpl jedisImpl = (StringJedisImpl)stringJedis;
if(isNeedDestory(jedisImpl.getLastUseTime())) {
jedisImpl.returnSource();
}
}
if(listJedis instanceof ListJedisImpl){
ListJedisImpl jedisImpl = (ListJedisImpl)stringJedis;
if(isNeedDestory(jedisImpl.getLastUseTime())) {
jedisImpl.returnSource();
}
}
if(mapJedis instanceof MapJedisImpl){
MapJedisImpl jedisImpl = (MapJedisImpl)mapJedis;
if(isNeedDestory(jedisImpl.getLastUseTime())) {
jedisImpl.returnSource();
}
}
if(zSetJedis instanceof ZSetJedisImpl){
ZSetJedisImpl jedisImpl = (ZSetJedisImpl)zSetJedis;
if(isNeedDestory(jedisImpl.getLastUseTime())) {
jedisImpl.returnSource();
}
}
}
private boolean isNeedDestory(LocalDateTime time){
LocalDateTime now = LocalDateTime.now();
Long nowMs = now.toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
Long oldMs = time.toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
Long realTime = nowMs-oldMs;
if(realTime>autoDestoryMs){
return true;
}
return false;
}
}
第四步、模板操作模板实现
redis中数据结构包含以下五种
支持以下数据类型
数据类型 | 使用方式 | |
---|---|---|
1 | String | jedisService.asString().set(…) |
2 | List | jedisService.asList().lpush(…) |
3 | Map | jedisService.asMap().set(…) |
4 | Set | jedisService.asSet().set(…) |
5 | Zet | jedisService.asZSet().set(…) |
以下以List结构的实现为例
/**
* @author machenike
*/
public class ListJedisImpl extends JedisReturnSource implements ListJedis {
private volatile Jedis jedis;
private static ListJedisImpl listJedisImpl;
public static synchronized ListJedisImpl getInstance(Jedis jedis){
if(listJedisImpl==null) {
listJedisImpl = new ListJedisImpl(jedis);
} else {
listJedisImpl.jedis = jedis;
listJedisImpl.lastUseTime = LocalDateTime.now();
}
return listJedisImpl;
}
private ListJedisImpl(Jedis jedis){
super();
this.jedis = jedis;
this.lastUseTime = LocalDateTime.now();
}
@Override
public void lpush(String key, List<String> list) {
if(jedis!=null){
jedis.lpush(key, StringArrayUtil.toArray(list));
this.lastUseTime = LocalDateTime.now();
}
}
@Override
public void lpush(String key, String item) {
if(jedis!=null){
jedis.lpush(key, item);
this.lastUseTime = LocalDateTime.now();
}
}
@Override
public void rpush(String key, List<String> list) {
if(jedis!=null){
jedis.rpush(key, StringArrayUtil.toArray(list));
this.lastUseTime = LocalDateTime.now();
}
}
@Override
public void rpush(String key, String item) {
if(jedis!=null){
jedis.rpush(key, item);
this.lastUseTime = LocalDateTime.now();
}
}
@Override
public void lrem(String key, String value) {
if(jedis!=null){
jedis.lrem(key, 0L,value);
this.lastUseTime = LocalDateTime.now();
}
}
@Override
public String lpop(String key) {
String item = null;
if(jedis!=null){
item = jedis.lpop(key);
this.lastUseTime = LocalDateTime.now();
}
return item;
}
@Override
public String rpop(String key) {
String item = null;
if(jedis!=null){
item = jedis.rpop(key);
this.lastUseTime = LocalDateTime.now();
}
return item;
}
@Override
public List<String> get(String key) {
List<String> list = new ArrayList<>();
if(jedis!=null) {
list = jedis.lrange(key, 0, -1);
this.lastUseTime = LocalDateTime.now();
}
return list;
}
@Override
public List<String> get(String key, Long endRange) {
List<String> list = new ArrayList<>();
if(jedis!=null) {
list = jedis.lrange(key, 0, endRange);
this.lastUseTime = LocalDateTime.now();
}
return list;
}
@Override
public List<String> get(String key, Long startRange, Long endRange) {
List<String> list = new ArrayList<>();
if(jedis!=null) {
list = jedis.lrange(key, startRange, endRange);
this.lastUseTime = LocalDateTime.now();
}
return list;
}
@Override
public void returnSource() {
returnSource(jedis);
}
@Override
public void del( String key) {
if(jedis!=null) {
jedis.del(key);
this.lastUseTime = LocalDateTime.now();
}
}
}
我把所有模板设计成单例,同时将内置的jedis实例设计成线程安全的,同时每次操作都会重置实例的最后使用时间,后续会根据这个时间来回收对象。
第五步、测试代码
@SpringBootTest
class BlogRedisApplicationTests {
@Autowired
JedisService jedisService;
@Test
void testRedis() {
jedisService.asString().set("test01", "test01String");
jedisService.asString().get("test01");
jedisService.asList().lpush("test02", "testList01");
jedisService.asList().get("test02");
}
}
上述过程不完善的请参考的我github
BlogRedis
后续还会持续更新