Java Spring Boot jedis连接池 的应用总结

471 阅读2分钟

在 Spring Boot 项目开发中,我们一定会遇到 缓存问题,其中 jedis 应用广泛,这里熟悉下整合 jedis连接池 ,简单实现个 控制器类 和一个 service实现类+测试。

环境:

  • Spring Boot: 3.1.16
  • JDK: 17

依赖

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>5.0.2</version>
</dependency>

<!-- 配置处理 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

主配置文件

通过一个简单的 yaml 文件配置 redis 的连接池选项:

#redis
spring:
  jmx:
    enabled: false
  data:
    redis:
      host: 172.xxx.xxx.xxx
      port: 6379
      timeout: 2000 # 20s
      database: 5
      jedis:
        pool:
          max-idle: 5
          max-active: 10
          min-idle: 3

解析配置

通过配置类,自动载入配置:

package com.example.springbootjedispooldemo.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

@Configuration
@EnableAutoConfiguration(exclude = {JmxAutoConfiguration.class}) // 关闭spring boot的jmx自动配置,防止二次创建
public class JedisConfig {
    private Logger logger = LoggerFactory.getLogger(JedisConfig.class);

    @Value("${spring.data.redis.host}")
    private String host;

    @Value("${spring.data.redis.port}")
    private int port;

    @Value("${spring.data.redis.timeout}")
    private int timeout;

    @Value("${spring.data.redis.database}")
    private int database;

    @Value("${spring.data.redis.jedis.pool.max-active}")
    private int maxActive;

    @Value("${spring.data.redis.jedis.pool.max-idle}")
    private int maxIdle;

    @Value("${spring.data.redis.jedis.pool.min-idle}")
    private int minIdle;

    @Bean
    public JedisPool jedisPool() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(maxActive);
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMinIdle(minIdle);

        JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, null, database);

        logger.info("JedisPool conn success: " + host + ":" + port);

        return jedisPool;
    }
}

工具类

简单封装成工具:

package com.example.springbootjedispooldemo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

@Component
public class JedisUtil {

    @Autowired
    private JedisPool jedisPool;

    public Jedis getJedis() {
        return jedisPool.getResource();
    }

    public void close(Jedis jedis) {
        if (jedis != null) {
            jedis.close();
        }
    }
}

控制器类

直接上个控制类的接口测试:

package com.example.springbootjedispooldemo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.util.Map;

@RestController
public class RedisController {

    @Autowired
    private JedisPool jedisPool;

    @PostMapping("/redis/set")
    public Object setValue(@RequestBody Map<String, String> data) {
        String key = data.get("key");
        String value = data.get("value");
        Jedis jedis = jedisPool.getResource();
        jedis.set(key, value);
        jedis.expire(key, 60);
        System.out.println("URI: " + "/redis/set," + " run ok.");
        return "ok";
    }
}

service实现类

编写个简单的 服务实现类:

package com.example.springbootjedispooldemo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;

@Service
public class JedisServiceImpl {
    @Autowired
    private JedisUtil jedisUtil;

    public String getValue(String key) {
        Jedis jedis = jedisUtil.getJedis();
        String value = null;

        if (!jedis.exists(key)) {
            value = "default";
            System.out.println(String.format("key: %s not exists in cache, and cache tmp %s: %s", key, key, "default"));
            jedis.set(key, "default");
        } else {
            value = jedis.get(key);
            System.out.println("query value: " + value);
        }

        jedisUtil.close(jedis);
        return value;
    }
}

测试

package com.example.springbootjedispooldemo;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

@SpringBootTest
public class JedisAppTest {

    @Autowired
    private JedisPool jedisPool;

    @Test
    public void loadJedis() {
        System.out.println(jedisPool);

        // get a conn from pool
        Jedis jedis = jedisPool.getResource();
        jedis.set("cache", "redis");
        String result = jedis.get("cache");
        System.out.println("Test: result: " + result);
        jedis.close();
    }
}

运行程序,看看接口测试:

1702288854(1).png

image.png

从返回值来看是成功的,接下来看看测试:

image.png

image.png

从各种来看,首先我们的配置是成果读取并自动装配的,而且 redis 也成功连接上,最后我们也在 Spring Boot 中成功应用了 jedis。

参考: