Spring Data Redis is JPA based framework to use the Redis cache as temporary data store. Using this framework you can use redis cache as any other database with spring data. Using JPA interfaces you can just perform CRUD operations and write custom queries.
Configuration can be done using properties or @Configuration. In this example, I used H2 DB for the datastore and redis cache for the cache data store. It means there are two repositories.
In this post, I will focus on the redis part only.
Gradle dependencies for Spring Data Redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'redis.clients:jedis'
Configuration for Redis DataSource
spring.datasource.url=jdbc:h2:mem:user_info
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.defer-datasource-initialization=true
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.h2.console.settings.trace=true
spring.h2.console.settings.web-allow-others=false
spring.cache.type=redis
spring.redis.host = 192.168.1.59
spring.redis.port = 6379
Cache Configuration
Use @EnableRedisRepositories
annotation to assign redis Datasource on DTO and Repository object with basePacjages/baseClasses
attributes and @EnableJpaRepositories to another data source.
@SpringBootApplication
@EnableCaching
@EnableRedisRepositories(enableKeyspaceEvents = RedisKeyValueAdapter.EnableKeyspaceEvents.ON_STARTUP,
basePackages = {"com.c4c.authn.core.repository.redis"})
@EnableJpaRepositories(basePackages = {"com.c4c.authn.core.repository.db"})
public class AuthApplication {
public static void main(String[] args) {
SpringApplication.run(AuthApplication.class, args);
}
}
Define redis Entity
Use @RedisHash
with a key otherwise, it will generate on its own.
RedisHash
marks Objects as aggregate roots to be stored in a Redis hash.
As default TTL we define in application property to 10 minutes, this can be set to each cache entry by putting @TimeToLive annotation to a member or method whose value is numeric. The default unit for @TimeToLive is seconds but you can define it.
TimeToLive
marks a single numeric property on aggregate root to be used for setting expirations in Redis. The annotated property supersedes any other timeout configuration.
RedisHash(value = "cache_item", timeToLive = 600000 )
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CacheItem {
@TimeToLive(unit = TimeUnit.SECONDS )
private Long ttl;
@NotNull
@Id
private String id;
}
Define Repository
@Repository
public interface CacheItemRepository extends JpaRepository<CacheItem, String> {
}
Define Service
public interface CacheService {
void add(CacheItem response);
boolean exists(String id);
}
@Service
public class RedisCacheServiceImpl implements CacheService {
@Autowired
private CacheItemRepository brandRepository;
@Override
public void add(CacheItem response){
this.brandRepository.save(response);
}
@Override
public boolean exists(String id){
return !this.brandRepository.findById(id).isEmpty();
}
}
Test with Junit 5
public class RedisCacheServiceImplTest extends BaseServiceTest {
@Autowired
private CacheService cacheService;
@Test
public void test_add_ok() throws InterruptedException {
this.cacheService.add(new CacheItem(5l, "ID1"));
assertTrue(this.cacheService.exists("ID1"));
Thread.sleep(6000);
assertFalse(this.cacheService.exists("ID1"));
}
}
Checkout complete working source at https://github.com/sheelprabhakar/spring-boot-authn-authr-ms.git