💡前言
Spring Boot提供了与Redis的集成框架,可以使用Lettuce作为Redis客户端来进行整合。
💡版本依赖
jdk 17
SpringBoot 3.1.0
💡环境准备
🌵依赖
<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>
🌵配置
server:
port: 8080 # 设置访问端口
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
💡实例
🌵LettuceClientConfig
//Redis服务器地址
@Value("${spring.redis.host}")
private String host;
//Redis服务端口
@Value("${spring.redis.port}")
private Integer port;
//Redis密码
@Value("${spring.redis.password}")
private String password;
//是否需要SSL
@Value("${spring.redis.ssl}")
private Boolean ssl;
//Redis默认库,一共0~15
@Value("${spring.redis.database}")
private Integer database;
//Lettuce连接配置(Redis单机版实例)
@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;
//设置可分配的最大Redis实例数量
@Value("${spring.redis.pool.maxTotal}")
private Integer maxTotal;
//设置最多空闲的Redis实例数量
@Value("${spring.redis.pool.maxIdle}")
private Integer maxIdle;
//归还Redis实例时,检查有消息,如果失败,则销毁实例
@Value("${spring.redis.pool.testOnReturn}")
private Boolean testOnReturn;
//当Redis实例处于空闲壮体啊时检查有效性,默认flase
@Value("${spring.redis.pool.testWhileIdle}")
private Boolean testWhileIdle;
//Apache-Common-Pool是一个对象池,用于缓存Redis连接,
//因为Letture本身基于Netty的异步驱动,但基于Servlet模型的同步访问时,连接池是必要的
//连接池可以很好的复用连接,减少重复的IO消耗与RedisURI创建实例的性能消耗
@Getter
GenericObjectPool<StatefulRedisConnection<String, String>> redisConnectionPool;
//Servlet初始化时先初始化Lettuce连接池
@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);
}
//Servlet销毁时先销毁Lettuce连接池
@PreDestroy
private void destroy() {
redisConnectionPool.close();
redisClient.shutdown();
}
🌵LettuceUtil
@Autowired
LettucePoolConfig lettucePoolConfig;
//编写executeSync方法,在方法中,获取Redis连接,利用Callback操作Redis,最后释放连接,并返回结果
//这里使用的同步的方式执行cmd指令
public <T> T executeSync(SyncCommandCallback<T> callback) {
//这里利用try的语法糖,执行完,自动给释放连接
try (StatefulRedisConnection<String, String> connection = lettucePoolConfig.getRedisConnectionPool().borrowObject()) {
//开启自动提交,如果false,命令会被缓冲,调用flushCommand()方法发出
connection.setAutoFlushCommands(true);
//设置为同步模式
RedisCommands<String, String> commands = connection.sync();
//执行传入的实现类
return callback.doInConnection(commands);
} catch (Exception e) {
log.error(e.getMessage());
throw new RuntimeException(e);
}
}
//分装一个set方法
public String set(final String key, final String val) {
return executeSync(commands -> commands.set(key, val));
}
//分装一个get方法
public String get(final String key) {
return executeSync(commands -> commands.get(key));
}
🌵SyncCommandCallback
//抽象方法,为了简化代码,便于传入回调函数
T doInConnection(RedisCommands<String, String> commands);
🌵LettuceController
@Autowired
LettuceUtil lettuceUtil;
/**
* 使用Lettuce工具类,调用Redis的Set指令
* http://127.0.0.1:8080/lettuce/set?key=name&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);
}
/**
* 使用Lettuce工具类,调用Redis的Get指令
* 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);
}