Lettuce 能够⽀持 Reactive ⽅式
Spring Data Redis 中主要的⽀持
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.zhz</groupId>
<artifactId>reactive-spring-boot-reactive-redis-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>reactive-spring-boot-reactive-redis-demo</name>
<description>Spring Boot中的reactive集成redis</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
spring:
datasource:
url: jdbc:mysql://119.29.36.141:3306/spring-test?serverTimezone=GMT%2B8
username: root
password: root
hikari:
connection-test-query: SELECT 1
connection-timeout: 60000
idle-timeout: 500000
max-lifetime: 540000
maximum-pool-size: 12
minimum-idle: 10
pool-name: GuliHikariPool
output:
ansi:
enabled: always
redis:
host: localhost
port: 6379
password: 123456
management:
endpoints:
web:
exposure:
include: '*'
mybatis:
type-handlers-package: com.zhz.springbootmybatisdemo.handler
configuration:
map-underscore-to-camel-case: true
package com.zhz.reactive;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Coffee {
private Long id;
private String name;
private Long price;
}
5、测试类
package com.zhz.reactive;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory;
import org.springframework.data.redis.core.ReactiveHashOperations;
import org.springframework.data.redis.core.ReactiveRedisTemplate;
import org.springframework.data.redis.core.ReactiveStringRedisTemplate;
import org.springframework.jdbc.core.JdbcTemplate;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import java.time.Duration;
import java.util.List;
import java.util.concurrent.CountDownLatch;
@Slf4j
@SpringBootApplication
public class ReactiveSpringBootReactiveRedisDemoApplication implements ApplicationRunner {
private static final String KEY = "COFFEE_MENU";
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private ReactiveStringRedisTemplate reactiveStringRedisTemplate;
public static void main(String[] args) {
SpringApplication.run(ReactiveSpringBootReactiveRedisDemoApplication.class, args);
}
@Bean
public ReactiveStringRedisTemplate reactiveRedisTemplate(ReactiveRedisConnectionFactory reactiveRedisConnectionFactory) {
return new ReactiveStringRedisTemplate(reactiveRedisConnectionFactory);
}
@Override
public void run(ApplicationArguments args) throws Exception {
ReactiveHashOperations<String, String, String> hashOperations = reactiveStringRedisTemplate.opsForHash();
CountDownLatch countDownLatch = new CountDownLatch(1);
List<Coffee> coffees = jdbcTemplate.query("select * from t_coffee", (rs, i) ->
Coffee.builder()
.id(rs.getLong("id"))
.name(rs.getString("name"))
.price(rs.getLong("price"))
.build()
);
Flux.fromIterable(coffees)
.publishOn(Schedulers.single())
.doOnComplete(() -> log.info("查询完毕"))
.flatMap(c -> {
log.info("try to put {},{}", c.getName(), c.getPrice());
return hashOperations.put(KEY, c.getName(), c.getPrice().toString());
})
.concatWith(reactiveStringRedisTemplate.expire(KEY, Duration.ofMinutes(1)))//1分钟
.doOnComplete(() -> log.info("expire ok"))
.onErrorResume(e -> {
log.error("exception {}", e.getMessage());
return Mono.just(false);
})
.subscribe(b -> log.info("Boolean: {}", b),
e -> log.error("Exception {}", e.getMessage()),
() -> countDownLatch.countDown());
log.info("Waiting");
countDownLatch.await();
;
}
}