SpringBoot integrates redis+lettuce

Foreword

Spring Boot provides an integration framework with Redis, which can be integrated using Lettuce as a Redis client.

Version dependency

jdk 17

SpringBoot 3.1.0

Environment preparation

Dependencies

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.0</version>
    </parent>
    <groupId>com.example</groupId>
    <artifactId>RedisLettuceDemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>RedisLettuceDemo</name>
    <description>RedisLettuceDemo</description>
    <properties>
        <java.version>17</java.version>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.32</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
    </dependencies>

Configuration

server:
  port: 8080 #Set access port

spring:
  redis:
    host: localhost
    port: 6379
    password: 123456
    database: 0
    ssl: false
    pool:
      maxIdle: 100
      minIdle: 0
      maxTotal: 100
      maxWaitMillis: 500
      testOnBorrow: false
      testOnReturn: true
      testWhileIdle: true

Example

LettuceClientConfig

//Redis server address
    @Value("${spring.redis.host}")
    private String host;

    //Redis service port
    @Value("${spring.redis.port}")
    private Integer port;

    //Redis password
    @Value("${spring.redis.password}")
    private String password;

    // Whether to require SSL
    @Value("${spring.redis.ssl}")
    private Boolean ssl;

    //Redis default library, total 0~15
    @Value("${spring.redis.database}")
    private Integer database;


    //Lettuce connection configuration (Redis stand-alone version instance)
    @Bean(name = "redisClient")
    public RedisClient redisClient() {
        RedisURI uri = RedisURI.Builder.redis(this.host, this.port)
                .withDatabase(this.database)
                .build();
        return RedisClient.create(uri);
    }

LettucePoolConfig

@Resource
    RedisClient redisClient;

    //Set the maximum number of Redis instances that can be allocated
    @Value("${spring.redis.pool.maxTotal}")
    private Integer maxTotal;

    //Set the maximum number of idle Redis instances
    @Value("${spring.redis.pool.maxIdle}")
    private Integer maxIdle;

    //When returning the Redis instance, check for a message, and if it fails, destroy the instance
    @Value("${spring.redis.pool.testOnReturn}")
    private Boolean testOnReturn;

    //Check the validity when the Redis instance is idle, the default is flase
    @Value("${spring.redis.pool.testWhileIdle}")
    private Boolean testWhileIdle;

    //Apache-Common-Pool is an object pool for caching Redis connections,
    //Because Letture itself is based on Netty's asynchronous driver, but the connection pool is necessary for synchronous access based on the Servlet model
    //The connection pool can reuse connections very well, reducing repeated IO consumption and performance consumption of RedisURI instance creation
    @Getter
    GenericObjectPool<StatefulRedisConnection<String, String>> redisConnectionPool;

    //When Servlet is initialized, first initialize the Lettuce connection pool
    @PostConstruct
    private void init() {
        GenericObjectPoolConfig<StatefulRedisConnection<String, String>> redisPoolConfig
                = new GenericObjectPoolConfig<>();
        redisPoolConfig.setMaxIdle(this.maxIdle);
        redisPoolConfig.setMinIdle(0);
        redisPoolConfig.setMaxTotal(this.maxTotal);
        redisPoolConfig.setTestOnReturn(this.testOnReturn);
        redisPoolConfig.setTestWhileIdle(this.testWhileIdle);
        redisPoolConfig.setMaxWaitMillis(1000);
        this.redisConnectionPool =
                ConnectionPoolSupport.createGenericObjectPool(() -> redisClient.connect(), redisPoolConfig);
    }

    //Destroy the Lettuce connection pool first when Servlet is destroyed
    @PreDestroy
    private void destroy() {
        redisConnectionPool.close();
        redisClient.shutdown();
    }

LettuceUtil

@Autowired
    LettucePoolConfig lettucePoolConfig;

    //Write the executeSync method, in the method, obtain the Redis connection, use the Callback to operate Redis, finally release the connection, and return the result
    //The synchronous method used here executes the cmd command
    public <T> T executeSync(SyncCommandCallback<T> callback) {
        //Here, use the syntactic sugar of try to automatically release the connection after execution
        try (StatefulRedisConnection<String, String> connection = lettucePoolConfig.getRedisConnectionPool().borrowObject()) {
            //Enable automatic submission, if false, the command will be buffered, call the flushCommand() method to issue
            connection.setAutoFlushCommands(true);
            //Set to synchronous mode
            RedisCommands<String, String> commands = connection.sync();
            //Execute the passed implementation class
            return callback.doInConnection(commands);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new RuntimeException(e);
        }
    }

    //Deploy a set method
    public String set(final String key, final String val) {
        return executeSync(commands -> commands.set(key, val));
    }

    //Deploy a get method
    public String get(final String key) {
        return executeSync(commands -> commands.get(key));
    }

SyncCommandCallback

 //Abstract method, in order to simplify the code and facilitate the incoming callback function
    T doInConnection(RedisCommands<String, String> commands);

LettuceController

@Autowired
    LettuceUtil lettuceUtil;

    /**
     * Use the Lettuce tool class to call the Set instruction of Redis
     * http://127.0.0.1:8080/lettuce/set?key=name & amp;val=ipipman
     *
     * @param key
     * @param val
     * @return
     */
    @GetMapping("/set")
    public Object setItem(@RequestParam(name = "key", required = true) String key,
                          @RequestParam(name = "val", required = true) String val) {
        return lettuceUtil.set(key, val);
    }

    /**
     * Use the Lettuce tool class to call the Get command of Redis
     * http://127.0.0.1:8080/lettuce/get?key=name
     *
     * @param key
     * @return
     */
    @GetMapping("/get")
    public Object getItem(@RequestParam(name = "key", required = true) String key) {
        return lettuceUtil.get(key);
    }

If you need the complete source code, please follow the public account “Architecture Hall” and reply “SpringBoot + redis + lettuce” to get it

Write it at the end

If you are interested in related articles, you can follow the public account “Architecture Palace”, which will continue to update AIGC, Java basic interview questions, netty, spring boot, spring cloud and other series of articles, and a series of useful information will be delivered at any time!