[BAEL-4868] Use Redis as cache store

This commit is contained in:
Haroon Khan 2021-05-04 17:10:01 +01:00
parent 442e5c1a7f
commit 4a1f6b132f
13 changed files with 283 additions and 0 deletions

View File

@ -623,6 +623,7 @@
<module>spring-boot-rest-2</module>
<module>spring-caching</module>
<module>spring-caching-2</module>
<module>spring-cloud</module>
<module>spring-cloud-bus</module>
@ -1079,6 +1080,7 @@
<module>spring-boot-rest-2</module>
<module>spring-caching</module>
<module>spring-caching-2</module>
<module>spring-cloud</module>
<module>spring-cloud-bus</module>

View File

@ -0,0 +1 @@
### Relevant articles:

66
spring-caching-2/pom.xml Normal file
View File

@ -0,0 +1,66 @@
<?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>
<artifactId>spring-caching-2</artifactId>
<version>0.1-SNAPSHOT</version>
<name>spring-caching-2</name>
<packaging>war</packaging>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-boot-2</relativePath>
</parent>
<properties>
<embedded.redis.version>0.7.3</embedded.redis.version>
</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-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>it.ozimov</groupId>
<artifactId>embedded-redis</artifactId>
<version>${embedded.redis.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</exclusion>
</exclusions>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,33 @@
package com.baeldung.caching.redis;
import org.springframework.boot.autoconfigure.cache.RedisCacheManagerBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import java.time.Duration;
import static org.springframework.data.redis.serializer.RedisSerializationContext.SerializationPair;
@Configuration
public class CacheConfig {
@Bean
public RedisCacheManagerBuilderCustomizer redisCacheManagerBuilderCustomizer() {
return (builder) -> builder
.withCacheConfiguration("itemCache",
RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(10)))
.withCacheConfiguration("customerCache",
RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(5)));
}
@Bean
public RedisCacheConfiguration cacheConfiguration() {
return RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(60))
.disableCachingNullValues()
.serializeValuesWith(SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.caching.redis;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.Id;
import java.io.Serializable;
@Data
@Entity
@AllArgsConstructor
@NoArgsConstructor
public class Item implements Serializable {
@Id
String id;
String description;
}

View File

@ -0,0 +1,19 @@
package com.baeldung.caching.redis;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
@AllArgsConstructor
public class ItemController {
private final ItemService itemService;
@GetMapping("/item/{id}")
public Item getItemById(@PathVariable String id) {
return itemService.getItemForId(id);
}
}

View File

@ -0,0 +1,6 @@
package com.baeldung.caching.redis;
import org.springframework.data.repository.CrudRepository;
public interface ItemRepository extends CrudRepository<Item, String> {
}

View File

@ -0,0 +1,19 @@
package com.baeldung.caching.redis;
import lombok.AllArgsConstructor;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
@AllArgsConstructor
public class ItemService {
private final ItemRepository itemRepository;
@Cacheable(value = "itemCache")
public Item getItemForId(String id) {
return itemRepository.findById(id)
.orElseThrow(RuntimeException::new);
}
}

View File

@ -0,0 +1,14 @@
package com.baeldung.caching.redis;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching
public class RedisCacheApplication {
public static void main(String[] args) {
SpringApplication.run(RedisCacheApplication.class, args);
}
}

View File

@ -0,0 +1,12 @@
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
# Enabling H2 Console
spring.h2.console.enabled=true
spring.h2.console.path=/h2
# Connection details
#spring.redis.host=localhost
#spring.redis.port=6379

View File

@ -0,0 +1 @@
INSERT INTO ITEM VALUES('abc','ITEM1');

View File

@ -0,0 +1,84 @@
package com.baeldung.caching.redis;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import redis.embedded.RedisServer;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@Import({ CacheConfig.class, ItemService.class })
@ExtendWith(SpringExtension.class)
@ImportAutoConfiguration(classes = { CacheAutoConfiguration.class, RedisAutoConfiguration.class })
@EnableCaching
class ItemServiceCachingIntegrationTest {
private static final String AN_ID = "id-1";
private static final String A_DESCRIPTION = "an item";
@MockBean
private ItemRepository mockItemRepository;
@Autowired
private ItemService itemService;
@Autowired
private CacheManager cacheManager;
@Test
void givenRedisCaching_whenFindItemById_thenItemReturnedFromCache() {
Item anItem = new Item(AN_ID, A_DESCRIPTION);
given(mockItemRepository.findById(AN_ID))
.willReturn(Optional.of(anItem));
Item itemCacheMiss = itemService.getItemForId(AN_ID);
Item itemCacheHit = itemService.getItemForId(AN_ID);
assertThat(itemCacheMiss).isEqualTo(anItem);
assertThat(itemCacheHit).isEqualTo(anItem);
verify(mockItemRepository, times(1)).findById(AN_ID);
assertThat(itemFromCache()).isEqualTo(anItem);
}
private Object itemFromCache() {
return cacheManager.getCache("itemCache").get(AN_ID).get();
}
@TestConfiguration
static class EmbeddedRedisConfiguration {
private final RedisServer redisServer;
public EmbeddedRedisConfiguration() {
this.redisServer = new RedisServer();
}
@PostConstruct
public void startRedis() {
redisServer.start();
}
@PreDestroy
public void stopRedis() {
this.redisServer.stop();
}
}
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
<logger name="org.springframework" level="OFF"/>
</configuration>