当前位置:   article > 正文

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

springboot自动回收redis

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

第二步、定义配置

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实例自动回收时间
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

配置类

/**
 * 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;
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113

第三步、模板实例管理服务创建

/**
 * 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;
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154

第四步、模板操作模板实现

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();
        }
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130

我把所有模板设计成单例,同时将内置的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");
	}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

上述过程不完善的请参考的我github
BlogRedis
在这里插入图片描述
后续还会持续更新

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/159995
推荐阅读
相关标签
  

闽ICP备14008679号