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