Redis| integrateion to Spring

Introduction

In this file, I want to record the steps to integrate Redis to Spring including the installation of Redis, setup of Redis configure file and visiting redis using Jedis.

Installation

  1. Redis is written using C so we can go to its official website and download the source code.
  2. Then we just need to compile the source code.
  3. Normally, we want user with authentification to visit redis, so we need to go redis.conf file and uncomment the line “requirepass” and setup personal password.
  4. After installation, we need to start the redeis-server so it will run in RAM and works as nosql.
  5. In order to visit the database, we just need to run redis-cli and use command line.
  6. Redis is always running as a back-end service so we want to run this service using ./utils/install_server.sh
    • Select a port for redis, default 6379
    • Select the configuration file for redis serivce.
    • Select the log file for redis service.
    • Select the data directory for redis service.
    • Select the redis executatble file path. Currently, when linus is startup, it will follow the init.d and run a bash script to start redis, redis will be started during bootstrap and run as a daemon service.

Integration with SpringBoot

  1. Add dependency of Jedis
     <!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
     <dependency>
         <groupId>redis.clients</groupId>
         <artifactId>jedis</artifactId>
         <version>3.0.1</version>
     </dependency>
    
  2. Add dependency of FastJson, we also can use protobuf but after serialization, pritobuf is not readable while FastJson can be read in Json format.
     <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
     <dependency>
         <groupId>com.alibaba</groupId>
         <artifactId>fastjson</artifactId>
         <version>1.2.54</version>
     </dependency>
    
  3. Configuration in SpringBoot:
    • Setup some parameters for initializing JedisPool in Application.properties.
       redis.host=${spring.redis.host}
       redis.port=${spring.redis.port}
       redis.timeout=3
       redis.password=${spring.redis.password}
       redis.maxActive=${spring.redis.jedis.pool.max-active}
       redis.maxIdle=${spring.redis.jedis.pool.min-idle}
       redis.maxWait=3
      
    • Create a Configuration Bean instance for loading all parameters.
       @Component
       @ConfigurationProperties(prefix = "redis")
       @Slf4j
       public class RedisConfig {
        @Getter@Setter
        private String host;
        @Getter@Setter
        private int port;
        @Getter@Setter
        private int timeout;
        @Getter@Setter
        private String password;
        @Getter@Setter
        private int maxActive;
        @Getter@Setter
        private int maxIdle;
        @Getter@Setter
        private int maxWait;
       }
      
    • Create a JedisPoolFactory method for getting jedisPool instance.
       @Bean
       public JedisPool jedisPoolFactory(){
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxIdle(redisConfig.getMaxIdle());
        poolConfig.setMaxTotal(redisConfig.getMaxActive());
        poolConfig.setMaxWaitMillis(redisConfig.getMaxWait() * 1000);
        JedisPool pool = new JedisPool(poolConfig, redisConfig.getHost(), redisConfig.getPort(), redisConfig.getTimeout() * 1000, redisConfig.getPassword());
        return pool;
       }
      

Usage

  1. Every time we want to have a connection with Redis, we need to retrieve a connection from redisPool and close the connection after finish our transaction.
    public <T> T get(String key, Class<T> clazz){
     Jedis jedis = null;
     try {
         jedis = this.jedisPool.getResource();   // Get connection from redis pool.
         String string  =jedis.get(key);
         return stringToBean(string, clazz);
     }finally {
         returnToPool(jedis);    // close the connect if it exists.
     }
    }
    
  2. As mentioned before, we want to use FastJson and Jedis together, which means if we want to save an object, we need to change it to json format and load a object, we first get a string and then decode it to a object, I can use the following two methods:
    private <T> String beanToString(T value, Class<T> clazz){
     if(value == null || clazz != value.getClass()){
         return null;
     }else if(clazz == int.class || clazz == Integer.class){
         return "" + value;
     }else if(clazz == String.class){
         return (String) value;
     }else if(clazz == long.class || clazz == Long.class){
         return "" + value;
     }else{
         return JSON.toJSONString(value);
     }
    }
    private <T> T stringToBean(String string, Class<T> clazz) {
     if(string == null || string.length() <= 0 || clazz == null){
         return null;
     }else if(clazz == int.class || clazz == Integer.class){
         return (T)Integer.valueOf(string);
     }else if(clazz == String.class){
         return (T)string;
     }else if(clazz == long.class || clazz == Long.class){
         return (T)Long.valueOf(string);
     }else{
         return JSON.toJavaObject(JSON.parseObject(string), clazz);
     }
    }
    
  3. Remember to use prefix for saving. Since redundant saving use same key will override the value saved in current key, so it will be a good habit to have a prefix for every key value. The best way of doing this is to use Classname:(save index) as the key, which can guarantee the unique of key value. ```Java

```

Reference

  1. ApplicationContext.xml