Spring Boot Redis 集成配置详解

作者:catoop 时间:2022-12-05 20:57:59 

spring Boot 熟悉后,集成一个外部扩展是一件很容易的事,集成Redis也很简单,看下面步骤配置:

一、添加pom依赖


   <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-redis</artifactId>
   </dependency>

二、创建 RedisClient.java

注意该类存放的package


package org.springframework.data.redis.connection.jedis;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.UnsupportedEncodingException;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Protocol;
import redis.clients.jedis.exceptions.JedisException;

/**
* 工具类 RedisClient
* 因为本类中获取JedisPool调用的是JedisConnectionFactory中protected修饰的方法fetchJedisConnector()
* 所以该类需要与JedisConnectionFactory在同一个package中
*
* @author 单红宇(CSDN CATOOP)
* @create 2017年4月9日
*/
public class RedisClient {

private static Logger logger = LoggerFactory.getLogger(RedisClient.class);

private JedisConnectionFactory factory;

public RedisClient(JedisConnectionFactory factory) {
   super();
   this.factory = factory;
 }

/**
  * put操作(存储序列化对象)+ 生效时间
  *
  * @param key
  * @param value
  * @return
  */
 public void putObject(final String key, final Object value, final int cacheSeconds) {
   if (StringUtils.isNotBlank(key)) {
     redisTemplete(key, new RedisExecute<Object>() {
       @Override
       public Object doInvoker(Jedis jedis) {
         try {
           jedis.setex(key.getBytes(Protocol.CHARSET), cacheSeconds, serialize(value));
         } catch (UnsupportedEncodingException e) {
         }

return null;
       }
     });
   }
 }

/**
  * get操作(获取序列化对象)
  *
  * @param key
  * @return
  */
 public Object getObject(final String key) {
   return redisTemplete(key, new RedisExecute<Object>() {
     @Override
     public Object doInvoker(Jedis jedis) {
       try {
         byte[] byteKey = key.getBytes(Protocol.CHARSET);
         byte[] byteValue = jedis.get(byteKey);
         if (byteValue != null) {
           return deserialize(byteValue);
         }
       } catch (UnsupportedEncodingException e) {
         return null;
       }
       return null;
     }
   });
 }

/**
  * setex操作
  *
  * @param key
  *      键
  * @param value
  *      值
  * @param cacheSeconds
  *      超时时间,0为不超时
  * @return
  */
 public String set(final String key, final String value, final int cacheSeconds) {
   return redisTemplete(key, new RedisExecute<String>() {
     @Override
     public String doInvoker(Jedis jedis) {
       if (cacheSeconds == 0) {
         return jedis.set(key, value);
       }
       return jedis.setex(key, cacheSeconds, value);
     }
   });
 }

/**
  * get操作
  *
  * @param key
  *      键
  * @return 值
  */
 public String get(final String key) {
   return redisTemplete(key, new RedisExecute<String>() {
     @Override
     public String doInvoker(Jedis jedis) {
       String value = jedis.get(key);
       return StringUtils.isNotBlank(value) && !"nil".equalsIgnoreCase(value) ? value : null;
     }
   });
 }

/**
  * del操作
  *
  * @param key
  *      键
  * @return
  */
 public long del(final String key) {
   return redisTemplete(key, new RedisExecute<Long>() {
     @Override
     public Long doInvoker(Jedis jedis) {
       return jedis.del(key);
     }
   });
 }

/**
  * 获取资源
  *
  * @return
  * @throws JedisException
  */
 public Jedis getResource() throws JedisException {
   Jedis jedis = null;
   try {
     jedis = factory.fetchJedisConnector();
   } catch (JedisException e) {
     logger.error("getResource.", e);
     returnBrokenResource(jedis);
     throw e;
   }
   return jedis;
 }

/**
  * 获取资源
  *
  * @return
  * @throws JedisException
  */
 public Jedis getJedis() throws JedisException {
   return getResource();
 }

/**
  * 归还资源
  *
  * @param jedis
  * @param isBroken
  */
 public void returnBrokenResource(Jedis jedis) {
   if (jedis != null) {
     jedis.close();
   }
 }

/**
  * 释放资源
  *
  * @param jedis
  * @param isBroken
  */
 public void returnResource(Jedis jedis) {
   if (jedis != null) {
     jedis.close();
   }
 }

/**
  * 操作jedis客户端模板
  *
  * @param key
  * @param execute
  * @return
  */
 public <R> R redisTemplete(String key, RedisExecute<R> execute) {
   Jedis jedis = null;
   try {
     jedis = getResource();
     if (jedis == null) {
       return null;
     }

return execute.doInvoker(jedis);
   } catch (Exception e) {
     logger.error("operator redis api fail,{}", key, e);
   } finally {
     returnResource(jedis);
   }
   return null;
 }

/**
  * 功能简述: 对实体Bean进行序列化操作.
  *
  * @param source
  *      待转换的实体
  * @return 转换之后的字节数组
  * @throws Exception
  */
 public static byte[] serialize(Object source) {
   ByteArrayOutputStream byteOut = null;
   ObjectOutputStream ObjOut = null;
   try {
     byteOut = new ByteArrayOutputStream();
     ObjOut = new ObjectOutputStream(byteOut);
     ObjOut.writeObject(source);
     ObjOut.flush();
   } catch (IOException e) {
     e.printStackTrace();
   } finally {
     try {
       if (null != ObjOut) {
         ObjOut.close();
       }
     } catch (IOException e) {
       ObjOut = null;
     }
   }
   return byteOut.toByteArray();
 }

/**
  * 功能简述: 将字节数组反序列化为实体Bean.
  *
  * @param source
  *      需要进行反序列化的字节数组
  * @return 反序列化后的实体Bean
  * @throws Exception
  */
 public static Object deserialize(byte[] source) {
   ObjectInputStream ObjIn = null;
   Object retVal = null;
   try {
     ByteArrayInputStream byteIn = new ByteArrayInputStream(source);
     ObjIn = new ObjectInputStream(byteIn);
     retVal = ObjIn.readObject();
   } catch (Exception e) {
     e.printStackTrace();
   } finally {
     try {
       if (null != ObjIn) {
         ObjIn.close();
       }
     } catch (IOException e) {
       ObjIn = null;
     }
   }
   return retVal;
 }

interface RedisExecute<T> {
   T doInvoker(Jedis jedis);
 }
}

三、创建Redis配置类

RedisConfig.Java


package com.shanhy.example.redis;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.RedisClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
* Redis配置
*
* @author 单红宇(CSDN catoop)
* @create 2016年9月12日
*/
@Configuration
public class RedisConfig {

@Bean
 public RedisTemplate<String, Object> redisTemplate(JedisConnectionFactory factory) {
   RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
   template.setConnectionFactory(factory);
   template.setKeySerializer(new StringRedisSerializer());
   template.setValueSerializer(new RedisObjectSerializer());
   template.afterPropertiesSet();
   return template;
 }

@Bean
 public RedisClient redisClient(JedisConnectionFactory factory){
   return new RedisClient(factory);
 }
}

RedisObjectSerializer.java


package com.shanhy.example.redis;

import org.springframework.core.convert.converter.Converter;
import org.springframework.core.serializer.support.DeserializingConverter;
import org.springframework.core.serializer.support.SerializingConverter;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

/**
* 实现对象的序列化接口
* @author  单红宇(365384722)
* @create  2017年4月9日
*/
public class RedisObjectSerializer implements RedisSerializer<Object> {

private Converter<Object, byte[]> serializer = new SerializingConverter();
 private Converter<byte[], Object> deserializer = new DeserializingConverter();

static final byte[] EMPTY_ARRAY = new byte[0];

@Override
 public Object deserialize(byte[] bytes) {
   if (isEmpty(bytes)) {
     return null;
   }

try {
     return deserializer.convert(bytes);
   } catch (Exception ex) {
     throw new SerializationException("Cannot deserialize", ex);
   }
 }

@Override
 public byte[] serialize(Object object) {
   if (object == null) {
     return EMPTY_ARRAY;
   }

try {
     return serializer.convert(object);
   } catch (Exception ex) {
     return EMPTY_ARRAY;
   }
 }

private boolean isEmpty(byte[] data) {
   return (data == null || data.length == 0);
 }

}

四、创建测试方法

下面代码随便放一个Controller里


 @Autowired
 private RedisTemplate<String, Object> redisTemplate;

/**
  * 缓存测试
  *
  * @return
  * @author SHANHY
  * @create 2016年9月12日
  */
 @RequestMapping("/redisTest")
 public String redisTest() {
   try {
     redisTemplate.opsForValue().set("test-key", "redis测试内容", 2, TimeUnit.SECONDS);// 缓存有效期2秒

logger.info("从Redis中读取数据:" + redisTemplate.opsForValue().get("test-key").toString());

TimeUnit.SECONDS.sleep(3);

logger.info("等待3秒后尝试读取过期的数据:" + redisTemplate.opsForValue().get("test-key"));
   } catch (InterruptedException e) {
     e.printStackTrace();
   }

return "OK";
 }

五、配置文件配置Redis

application.yml


spring:
# Redis配置
redis:
 host: 192.168.1.101
 port: 6379
 password:
 # 连接超时时间(毫秒)
 timeout: 10000
 pool:
  max-idle: 20
  min-idle: 5
  max-active: 20
  max-wait: 2

这样就完成了Redis的配置,可以正常使用 redisTemplate 了。

来源:http://blog.csdn.net/catoop/article/details/71275331

标签:spring,boot,redis
0
投稿

猜你喜欢

  • Java中的final关键字详解及实例

    2023-05-26 11:09:46
  • Spring Boot中如何使用断路器详解

    2022-03-03 06:34:49
  • android studio生成aar包并在其他工程引用aar包的方法

    2021-07-23 21:28:30
  • Java基础题新手练习(二)

    2022-03-10 00:11:57
  • java 实现随机数组输出及求和实例详解

    2021-10-27 13:12:50
  • ViewPager判断是向左划还是右划的实例

    2023-12-10 04:53:18
  • 一步步教你如何创建第一个C#项目

    2021-08-15 04:41:56
  • C#构建树形结构数据(全部构建,查找构建)

    2022-07-22 12:22:52
  • maven手动上传jar包示例及图文步骤过程

    2023-11-13 22:10:57
  • C#访问SQLServer增删改查代码实例

    2021-10-08 14:39:03
  • 适配android7.0获取文件的Uri的方法

    2022-03-13 17:32:06
  • C#使用Socket实现服务器与多个客户端通信(简单的聊天系统)

    2022-03-08 23:48:07
  • Android Studio自动提取控件Style样式教程

    2022-01-29 14:09:55
  • 详解Android获取设备唯一ID的几种方式

    2022-07-15 12:33:41
  • Android7.0版本影响开发的改进分析

    2022-06-06 03:40:37
  • 完美解决Android App启动页有白屏闪过的问题

    2021-11-18 02:12:31
  • MyBatis框架底层的执行原理源码解析

    2023-10-28 12:19:27
  • android自动化测试知识点总结

    2022-12-28 03:51:50
  • WPF模拟实现Gitee泡泡菜单的示例代码

    2023-09-19 00:53:16
  • springboot使用mybatis开启事务回滚

    2022-09-10 05:15:55
  • asp之家 软件编程 m.aspxhome.com