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日 */@Configurationpublic 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) * @myblog http://blog.csdn.net/catoop/ * @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 了。