Spring Webflux and @Cacheable Annotation
This commit is contained in:
parent
3ab032d095
commit
19437f2e13
3
pom.xml
3
pom.xml
|
@ -7,6 +7,9 @@
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>parent-modules</artifactId>
|
<artifactId>parent-modules</artifactId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
<modules>
|
||||||
|
<module>spring-webflux-caching</module>
|
||||||
|
</modules>
|
||||||
<name>parent-modules</name>
|
<name>parent-modules</name>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.baeldung.spring</groupId>
|
||||||
|
<artifactId>spring-webflux-caching</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
<name>spring-webflux-caching</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<description>Spring WebFlux Caching Sample</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-boot-2</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../parent-boot-2</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.reactivex.rxjava2</groupId>
|
||||||
|
<artifactId>rxjava</artifactId>
|
||||||
|
<version>2.2.19</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.projectreactor.addons</groupId>
|
||||||
|
<artifactId>reactor-extra</artifactId>
|
||||||
|
<version>3.4.5</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.ben-manes.caffeine</groupId>
|
||||||
|
<artifactId>caffeine</artifactId>
|
||||||
|
<version>3.0.4</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.projectreactor</groupId>
|
||||||
|
<artifactId>reactor-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.testcontainers</groupId>
|
||||||
|
<artifactId>mongodb</artifactId>
|
||||||
|
<version>1.16.2</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,50 @@
|
||||||
|
package com.baeldung.caching;
|
||||||
|
|
||||||
|
import org.springframework.data.annotation.Id;
|
||||||
|
import org.springframework.data.mongodb.core.mapping.Document;
|
||||||
|
|
||||||
|
@Document
|
||||||
|
public class Item {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private String _id;
|
||||||
|
private String name;
|
||||||
|
private double price;
|
||||||
|
|
||||||
|
public Item(String name, double price) {
|
||||||
|
this.name = name;
|
||||||
|
this.price = price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public String get_id() {
|
||||||
|
return _id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getPrice() {
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrice(double price) {
|
||||||
|
this.price = price;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Item{" +
|
||||||
|
"id='" + _id + '\'' +
|
||||||
|
", name='" + name + '\'' +
|
||||||
|
", price=" + price +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.baeldung.caching;
|
||||||
|
|
||||||
|
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface ItemRepository extends ReactiveMongoRepository<Item, String> {
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.baeldung.caching;
|
||||||
|
|
||||||
|
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||||
|
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||||
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import reactor.cache.CacheMono;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ItemService {
|
||||||
|
|
||||||
|
private final ItemRepository repository;
|
||||||
|
private final LoadingCache<String, Object> cache;
|
||||||
|
|
||||||
|
public ItemService(ItemRepository repository) {
|
||||||
|
this.repository = repository;
|
||||||
|
this.cache = Caffeine.newBuilder()
|
||||||
|
.build(this::getItem_withAddons);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Cacheable("items")
|
||||||
|
public Mono<Item> getItem(String id) {
|
||||||
|
return repository.findById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mono<Item> save(Item item) {
|
||||||
|
return repository.save(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Cacheable("items")
|
||||||
|
public Mono<Item> getItem_withCache(String id) {
|
||||||
|
return repository.findById(id).cache();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Cacheable("items")
|
||||||
|
public Mono<Item> getItem_withAddons(String id) {
|
||||||
|
return CacheMono.lookup(cache.asMap(), id)
|
||||||
|
.onCacheMissResume(() -> repository.findById(id).cast(Object.class)).cast(Item.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.baeldung.caching;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.cache.annotation.EnableCaching;
|
||||||
|
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableMongoRepositories
|
||||||
|
@EnableCaching
|
||||||
|
public class SpringWebfluxCachingApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(SpringWebfluxCachingApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
logging.level.org.springframework.data.mongodb.core.ReactiveMongoTemplate=DEBUG
|
||||||
|
logging.level.org.springframework.cache=TRACE
|
|
@ -0,0 +1,95 @@
|
||||||
|
package com.baeldung.caching;
|
||||||
|
|
||||||
|
|
||||||
|
import org.assertj.core.api.Assertions;
|
||||||
|
import org.junit.ClassRule;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.DynamicPropertyRegistry;
|
||||||
|
import org.springframework.test.context.DynamicPropertySource;
|
||||||
|
import org.testcontainers.containers.MongoDBContainer;
|
||||||
|
import org.testcontainers.utility.DockerImageName;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
public class MonoFluxResultCachingLiveTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
ItemService itemService;
|
||||||
|
|
||||||
|
final static MongoDBContainer mongoDBContainer = new MongoDBContainer(DockerImageName.parse("mongo:4.0.10"));
|
||||||
|
|
||||||
|
@DynamicPropertySource
|
||||||
|
static void mongoDbProperties(DynamicPropertyRegistry registry) {
|
||||||
|
mongoDBContainer.start();
|
||||||
|
registry.add("spring.data.mongodb.uri", mongoDBContainer::getReplicaSetUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenItem_whenGetItemIsCalled_thenMonoIsCached() {
|
||||||
|
Mono<Item> glass = itemService.save(new Item("glass", 1.00));
|
||||||
|
|
||||||
|
String id = glass.block().get_id();
|
||||||
|
|
||||||
|
Mono<Item> mono = itemService.getItem(id);
|
||||||
|
Item item = mono.block();
|
||||||
|
|
||||||
|
assertThat(item).isNotNull();
|
||||||
|
assertThat(item.getName()).isEqualTo("glass");
|
||||||
|
assertThat(item.getPrice()).isEqualTo(1.00);
|
||||||
|
|
||||||
|
Mono<Item> mono2 = itemService.getItem(id);
|
||||||
|
Item item2 = mono2.block();
|
||||||
|
|
||||||
|
assertThat(item2).isNotNull();
|
||||||
|
assertThat(item2.getName()).isEqualTo("glass");
|
||||||
|
assertThat(item2.getPrice()).isEqualTo(1.00);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenItem_whenGetItemWithCacheIsCalled_thenMonoResultIsCached() {
|
||||||
|
Mono<Item> glass = itemService.save(new Item("glass", 1.00));
|
||||||
|
|
||||||
|
String id = glass.block().get_id();
|
||||||
|
|
||||||
|
Mono<Item> mono = itemService.getItem_withCache(id);
|
||||||
|
Item item = mono.block();
|
||||||
|
|
||||||
|
assertThat(item).isNotNull();
|
||||||
|
assertThat(item.getName()).isEqualTo("glass");
|
||||||
|
assertThat(item.getPrice()).isEqualTo(1.00);
|
||||||
|
|
||||||
|
Mono<Item> mono2 = itemService.getItem_withCache(id);
|
||||||
|
Item item2 = mono2.block();
|
||||||
|
|
||||||
|
assertThat(item2).isNotNull();
|
||||||
|
assertThat(item2.getName()).isEqualTo("glass");
|
||||||
|
assertThat(item2.getPrice()).isEqualTo(1.00);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenItem_whenGetItemWithAddonsIsCalled_thenMonoResultIsCached() {
|
||||||
|
Mono<Item> glass = itemService.save(new Item("glass", 1.00));
|
||||||
|
|
||||||
|
String id = glass.block().get_id();
|
||||||
|
|
||||||
|
Mono<Item> mono = itemService.getItem_withAddons(id);
|
||||||
|
Item item = mono.block();
|
||||||
|
|
||||||
|
assertThat(item).isNotNull();
|
||||||
|
assertThat(item.getName()).isEqualTo("glass");
|
||||||
|
assertThat(item.getPrice()).isEqualTo(1.00);
|
||||||
|
|
||||||
|
Mono<Item> mono2 = itemService.getItem_withAddons(id);
|
||||||
|
Item item2 = mono2.block();
|
||||||
|
|
||||||
|
assertThat(item2).isNotNull();
|
||||||
|
assertThat(item2.getName()).isEqualTo("glass");
|
||||||
|
assertThat(item2.getPrice()).isEqualTo(1.00);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue