Spring-Boot快速集成Jedis(封装多种模板,自动回收实例,线程安全)

3 篇文章 0 订阅
2 篇文章 0 订阅

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中数据结构包含以下五种

支持以下数据类型

数据类型使用方式
1StringjedisService.asString().set(…)
2ListjedisService.asList().lpush(…)
3MapjedisService.asMap().set(…)
4SetjedisService.asSet().set(…)
5ZetjedisService.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
在这里插入图片描述
后续还会持续更新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值