Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Integrate Redis into a Spring Project

DZone's Guide to

Integrate Redis into a Spring Project

Learn how to integrate the Redis cache into your Spring project using the annotation configuration and the jedis driver.

Free Resource

Learn how to create flexible schemas in a relational database using SQL for JSON.

This article shows how to integrate Redis cache to your spring project through annotation configuration.

We will begin with our Gradle configuration. We will use the jedis driver.


group 'com.gkatzioura.spring'
version '1.0-SNAPSHOT'

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.5.RELEASE")
    }
}

jar {
    baseName = 'gs-serving-web-content'
    version =  '0.1.0'
}

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    compile "org.springframework.boot:spring-boot-starter-thymeleaf"
    compile 'org.slf4j:slf4j-api:1.6.6'
    compile 'ch.qos.logback:logback-classic:1.0.13'
    compile 'redis.clients:jedis:2.7.0'
    compile 'org.springframework.data:spring-data-redis:1.5.0.RELEASE'
    testCompile group: 'junit', name: 'junit', version: '4.11'
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.3'
}

Will proceed with the Redis configuration using spring annotations.


package com.gkatzioura.spring.config;

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {

    @Bean
    public JedisConnectionFactory redisConnectionFactory() {

        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
        jedisConnectionFactory.setUsePool(true);
        return jedisConnectionFactory;
    }

    @Bean
    public RedisSerializer redisStringSerializer() {
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        return stringRedisSerializer;
    }

    @Bean(name="redisTemplate")
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory cf,RedisSerializer redisSerializer) {
        RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>();
        redisTemplate.setConnectionFactory(cf);
        redisTemplate.setDefaultSerializer(redisSerializer);
        return redisTemplate;
    }

    @Bean
    public CacheManager cacheManager() {
        return new RedisCacheManager(redisTemplate(redisConnectionFactory(),redisStringSerializer()));
    }

}

Next step is to create our caching interface


package com.gkatzioura.spring.cache;

import java.util.Date;
import java.util.List;

public interface CacheService {

    public void addMessage(String user,String message);

    public List<String> listMessages(String user);

}

A user will add messages and he will be able to retrieve them .
However on our implementation, user related messages will have a time to live of one minute.

Our implementation CacheService using Redis follows.


package com.gkatzioura.spring.cache.impl;

import com.gkatzioura.spring.cache.CacheService;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.List;

@Service("cacheService")
public class RedisService implements CacheService {

    @Resource(name = "redisTemplate")
    private ListOperations<String, String> messageList;

    @Resource(name = "redisTemplate")
    private RedisOperations<String,String> latestMessageExpiration;

    @Override
    public void addMessage(String user,String message) {

        messageList.leftPush(user,message);

        ZonedDateTime zonedDateTime = ZonedDateTime.now();
        Date date = Date.from(zonedDateTime.plus(1, ChronoUnit.MINUTES).toInstant());
        latestMessageExpiration.expireAt(user,date);
    }

    @Override
    public List<String> listMessages(String user) {
        return messageList.range(user,0,-1);
    }

}

Our cache mechanism will retain a list of messages sent by each user. To achieve so we will employee the ListOperations interface using the user as a key.
The RedisOperations interface gives us the ability to specify a time to live for a key. In our case it is used for the user key.

Next we create a controller with the cache service injected.


package com.gkatzioura.spring.controller;

import com.gkatzioura.spring.cache.CacheService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
public class MessageController {


    @Autowired
    private CacheService cacheService;

    @RequestMapping(value = "/message",method = RequestMethod.GET)
    @ResponseBody
    public List<String> greeting(String user) {

        List<String> messages = cacheService.listMessages(user);

        return messages;
    }

    @RequestMapping(value = "/message",method = RequestMethod.POST)
    @ResponseBody
    public String saveGreeting(String user,String message) {

        cacheService.addMessage(user,message);

        return "OK";

    }

}

Last but not least our Application class


package com.gkatzioura.spring;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

In order to run just issue

Create flexible schemas using dynamic columns for semi-structured data. Learn how.

Topics:
database ,key value store ,nosql ,redis

Published at DZone with permission of Emmanouil Gkatziouras, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}