经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring Boot » 查看文章
Spring Boot整合Redis
来源:cnblogs  作者:yliu.best  时间:2019/1/9 9:51:01  对本文有异议

Spring Boot整合Redis

spring boot提供了spring-data-redis库来整合 Redis的操作,并通过简单的配置信息实现与Redis的整合。

PS:个人还是习惯于使用 Jedis 面向 Java 客户端操作 Redis

废话不多说,上代码。 :-)

  • Maven 依赖

  1. <dependency>
  2.     <groupId>org.springframework.boot</groupId>
  3.     <artifactId>spring-boot-starter-data-redis</artifactId>
  4. </dependency>
  5. <!-- Spring Boot项目里不用加版本号,加入 spring-boot-starter-data-redis 即可 -->
  6. <!-- 非Spring Boot项目下,可在 maven repository 中选合适的版本号 -->
  7. <!-- 面向java客户端Redis操作 -->
  8. <dependency>
  9.     <groupId>redis.clients</groupId>
  10.     <artifactId>jedis</artifactId>
  11. </dependency>
  • Jedis配置

  1. ########################## redis ###################################
  2. # Redis服务器地址
  3. spring.redis.host=127.0.0.1
  4. # Redis服务器连接密码(默认为空)
  5. spring.redis.password=123456
  6. # Redis服务器连接端口
  7. spring.redis.port=6379
  8. # 连接超时时间(毫秒)
  9. spring.redis.timeout=3000
  10. # redis 连接池配置
  11. # 池中最大链接数
  12. spring.redis.pool-config.max-total=256
  13. # 连接池中的最大空闲连接
  14. spring.redis.pool-config.max-idle=3000
  15. # 连接池中的最小空闲连接
  16. spring.redis.pool-config.min-idle=8
  17. # 连接池最大阻塞等待时间(使用负值表示没有限制)
  18. spring.redis.pool-config.max-wait-millis=1000
  19. # 调用者获取链接时,是否检测当前链接有效性
  20. spring.redis.pool-config.test-on-borrow=false
  21. # 向链接池中归还链接时,是否检测链接有效性
  22. spring.redis.pool-config.test-on-return=false
  23. # 调用者获取链接时,是否检测空闲超时, 如果超时,则会被移除
  24. spring.redis.pool-config.test-while-idle=true
  25. # 空闲链接检测线程一次运行检测多少条链接
  26. spring.redis.pool-config.num-tests-per-eviction-run=8
  27. # 空闲链接检测线程检测周期。如果为负值,表示不运行检测线程。(单位:毫秒,默认为-layer)
  28. spring.redis.pool-config.time-between-eviction-runs-millis=60000
  29. # 配置一个连接在池中最小生存的时间,单位是毫秒
  30. spring.redis.pool-config.min-evictable-idle-time-millis=300000

注:properties中的配置可根据项目实际情况自己调整,我不敢保证以上配置所有项目都适用

  • 封装Properties Redis配置

  1. @Configuration
  2. @ConfigurationProperties(prefix = "spring.redis")
  3. public class RedisProperties {
  4.  
  5.     private String host;
  6.  
  7.     private String password;
  8.  
  9.     private int port;
  10.  
  11.     private int timeout;
  12.     
  13.     // 此对象的句柄命名要和 Properties 中一一对应
  14.     // Properties 中为 “pool-config” 那么这里应为 “poolConfig”
  15.     private RedisPoolConfigProperties poolConfig = new RedisPoolConfigProperties();
  16.  
  17.     public String getHost() {
  18.         return host;
  19.     }
  20.  
  21.     public void setHost(String host) {
  22.         this.host = host;
  23.     }
  24.  
  25.     public String getPassword() {
  26.         return password;
  27.     }
  28.  
  29.     public void setPassword(String password) {
  30.         this.password = password;
  31.     }
  32.  
  33.     public int getPort() {
  34.         return port;
  35.     }
  36.  
  37.     public void setPort(int port) {
  38.         this.port = port;
  39.     }
  40.  
  41.     public int getTimeout() {
  42.         return timeout;
  43.     }
  44.  
  45.     public void setTimeout(int timeout) {
  46.         this.timeout = timeout;
  47.     }
  48.  
  49.     public RedisPoolConfigProperties getPoolConfig() {
  50.         return poolConfig;
  51.     }
  52.  
  53.     public void setPoolConfig(RedisPoolConfigProperties poolConfig) {
  54.         this.poolConfig = poolConfig;
  55.     }
  56.  
  57.     @Override
  58.     public String toString() {
  59.         return "RedisProperties{" +
  60.                 "host='" + host + '\'' +
  61.                 ", password='" + password + '\'' +
  62.                 ", port=" + port +
  63.                 ", timeout=" + timeout +
  64.                 ", poolConfig=" + poolConfig +
  65.                 '}';
  66.     }
  67. }
  1. // 该对象为 上面 RedisProperties 中的一个属性
  2. public class RedisPoolConfigProperties {
  3.  
  4.     private int maxTotal;
  5.  
  6.     private int maxIdle;
  7.  
  8.     private int minIdle;
  9.  
  10.     private int maxWaitMillis;
  11.  
  12.     private Boolean testOnBorrow;
  13.  
  14.     private Boolean testOnReturn;
  15.  
  16.     private Boolean testWhileIdle;
  17.  
  18.     private int numTestsPerEvictionRun;
  19.  
  20.     private int timeBetweenEvictionRunsMillis;
  21.  
  22.     private int minEvictableIdleTimeMillis;
  23.  
  24.     public int getMaxTotal() {
  25.         return maxTotal;
  26.     }
  27.  
  28.     public void setMaxTotal(int maxTotal) {
  29.         this.maxTotal = maxTotal;
  30.     }
  31.  
  32.     public int getMaxIdle() {
  33.         return maxIdle;
  34.     }
  35.  
  36.     public void setMaxIdle(int maxIdle) {
  37.         this.maxIdle = maxIdle;
  38.     }
  39.  
  40.     public int getMinIdle() {
  41.         return minIdle;
  42.     }
  43.  
  44.     public void setMinIdle(int minIdle) {
  45.         this.minIdle = minIdle;
  46.     }
  47.  
  48.     public int getMaxWaitMillis() {
  49.         return maxWaitMillis;
  50.     }
  51.  
  52.     public void setMaxWaitMillis(int maxWaitMillis) {
  53.         this.maxWaitMillis = maxWaitMillis;
  54.     }
  55.  
  56.     public Boolean getTestOnBorrow() {
  57.         return testOnBorrow;
  58.     }
  59.  
  60.     public void setTestOnBorrow(Boolean testOnBorrow) {
  61.         this.testOnBorrow = testOnBorrow;
  62.     }
  63.  
  64.     public Boolean getTestOnReturn() {
  65.         return testOnReturn;
  66.     }
  67.  
  68.     public void setTestOnReturn(Boolean testOnReturn) {
  69.         this.testOnReturn = testOnReturn;
  70.     }
  71.  
  72.     public Boolean getTestWhileIdle() {
  73.         return testWhileIdle;
  74.     }
  75.  
  76.     public void setTestWhileIdle(Boolean testWhileIdle) {
  77.         this.testWhileIdle = testWhileIdle;
  78.     }
  79.  
  80.     public int getNumTestsPerEvictionRun() {
  81.         return numTestsPerEvictionRun;
  82.     }
  83.  
  84.     public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
  85.         this.numTestsPerEvictionRun = numTestsPerEvictionRun;
  86.     }
  87.  
  88.     public int getTimeBetweenEvictionRunsMillis() {
  89.         return timeBetweenEvictionRunsMillis;
  90.     }
  91.  
  92.     public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) {
  93.         this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
  94.     }
  95.  
  96.     public int getMinEvictableIdleTimeMillis() {
  97.         return minEvictableIdleTimeMillis;
  98.     }
  99.  
  100.     public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
  101.         this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
  102.     }
  103.  
  104.     @Override
  105.     public String toString() {
  106.         return "RedisPoolConfigProperties{" +
  107.                 "maxTotal=" + maxTotal +
  108.                 ", maxIdle=" + maxIdle +
  109.                 ", minIdle=" + minIdle +
  110.                 ", maxWaitMillis=" + maxWaitMillis +
  111.                 ", testOnBorrow=" + testOnBorrow +
  112.                 ", testOnReturn=" + testOnReturn +
  113.                 ", testWhileIdle=" + testWhileIdle +
  114.                 ", numTestsPerEvictionRun=" + numTestsPerEvictionRun +
  115.                 ", timeBetweenEvictionRunsMillis=" + timeBetweenEvictionRunsMillis +
  116.                 ", minEvictableIdleTimeMillis=" + minEvictableIdleTimeMillis +
  117.                 '}';
  118.     }
  119. }

注:封装对象时一定要注意,在Properties中的每个属性对应在JavaBean中要一一对应,并使用驼峰是命名。

max-total 对应 Java Bean 属性为 maxTotal;password 对应 Java Bean 属性为 password

  • Redis配置纳入JedsiPool(Jedis连接池)中,并把JedsiPool交由Spring管理

  1. @Configuration
  2. public class RedisConfig {
  3.  
  4.     private static final Logger log = LoggerFactory.getLogger(RedisConfig.class);
  5.  
  6.     // 此处通过构造方法注入了 RedisProperties 
  7.     // 也可改成:
  8.     // @Autowired 
  9.     // private RedisProperties redis;
  10.     private final RedisProperties redis;
  11.     public RedisConfig(RedisProperties redis) {
  12.         this.redis = redis;
  13.     }
  14.  
  15.     @Bean
  16.     public JedisPool jedisPool() {
  17.         RedisPoolConfigProperties poolConfig = redis.getPoolConfig();
  18.         final JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
  19.         jedisPoolConfig.setMaxTotal(poolConfig.getMaxTotal());
  20.         jedisPoolConfig.setMaxIdle(poolConfig.getMaxIdle());
  21.         jedisPoolConfig.setMaxWaitMillis(poolConfig.getMaxWaitMillis());
  22.         jedisPoolConfig.setMinIdle(poolConfig.getMinIdle());
  23.         jedisPoolConfig.setMinEvictableIdleTimeMillis(poolConfig.getMinEvictableIdleTimeMillis());
  24.         jedisPoolConfig.setNumTestsPerEvictionRun(poolConfig.getNumTestsPerEvictionRun());
  25.         jedisPoolConfig.setTestOnBorrow(poolConfig.getTestOnBorrow());
  26.         jedisPoolConfig.setTestOnReturn(poolConfig.getTestOnReturn());
  27.         jedisPoolConfig.setTestWhileIdle(poolConfig.getTestWhileIdle());
  28.         jedisPoolConfig.setTimeBetweenEvictionRunsMillis(poolConfig.getTimeBetweenEvictionRunsMillis());
  29.         log.info("JedisPoolConfig Initialize ........");
  30.         log.info("JedisPoolConfig Info ........ {}", poolConfig);
  31.         String host = redis.getHost();
  32.         String password = redis.getPassword();
  33.         int port = redis.getPort();
  34.         int timeout = redis.getTimeout();
  35.         final JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, password);
  36.         log.info("JedisPool Initialize ........");
  37.         log.info("redis address---> {}:{}", host, port);
  38.         return jedisPool;
  39.     }
  40. }

至此,JedisPool已经纳入了Spring中,如果中间有错误,细心检查一下。 :-)

  • 封装操作 Jedis 接口

  1. public interface JedisClient {
  2.  
  3.     /**
  4.      * 将字符串值 value 关联到 key
  5.      */
  6.     void set(String key, String value);
  7.  
  8.     /**
  9.      * 返回 key 所关联的字符串值。
  10.      * 如果 key 不存在那么返回特殊值 nil 。
  11.      * 假如 key 储存的值不是字符串类型,返回一个错误,因为 GET 只能用于处理字符串值。
  12.      */
  13.     String get(String key);
  14.  
  15.     /**
  16.      * 检查给定 key 是否存在。
  17.      */
  18.     Boolean exists(String key);
  19.  
  20.     /**
  21.      * 为给定 key 设置生存时间,当 key 过期时(生存时间为 0 ),它会被自动删除。
  22.      * 单位:秒
  23.      */
  24.     void expire(String key, int seconds);
  25.  
  26.     /**
  27.      * 以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live)。
  28.      */
  29.     Long ttl(String key);
  30.  
  31.     /**
  32.      * 将 key 中储存的数字值增一。
  33.      * 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。
  34.      */
  35.     Long incr(String key);
  36.  
  37.     /**
  38.      * 将 key 中储存的数字值减一。
  39.      * 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 DECR 操作。
  40.      * 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
  41.      */
  42.     Long decr(String key);
  43.  
  44.     /**
  45.      * 将哈希表 key 中的域 field 的值设为 value 。
  46.      * 如果 key 不存在,一个新的哈希表被创建并进行 HSET 操作。
  47.      * 如果域 field 已经存在于哈希表中,旧值将被覆盖。
  48.      */
  49.     Long hset(String key, String field, String value);
  50.  
  51.     /**
  52.      * 返回哈希表 key 中给定域 field 的值。
  53.      */
  54.     String hget(String key, String field);
  55.  
  56.     /**
  57.      * 删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略。
  58.      */
  59.     Long hdel(String key, String... field);
  60.  
  61.     /**
  62.      * 查看哈希表 key 中,给定域 field 是否存在。
  63.      */
  64.     Boolean hexists(String key, String field);
  65.  
  66.     /**
  67.      * 返回哈希表 key 中所有域的值。
  68.      */
  69.     List<String> hvals(String key);
  70.  
  71.     /**
  72.      * 删除给定的一个 key 。
  73.      */
  74.     Long del(String key);
  75.  
  76.     /**
  77.      * 存储数据到缓存中,并制定过期时间和当Key存在时是否覆盖。
  78.      * @param nxxx 值只能取NX或者XX,如果取NX,则只有当key不存在是才进行set,如果取XX,则只有当key已经存在时才进行set
  79.      * @param expx expx的值只能取EX或者PX,代表数据过期时间的单位,EX代表秒,PX代表毫秒。
  80.      * @param time 过期时间,单位是expx所代表的单位。
  81.      */
  82.     String set(String key, String value, String nxxx, String expx, long time);
  83.  
  84.     /**
  85.      * redis 脚本扩展器
  86.      */
  87.     Object eval(String script, List<String> keys, List<String> args);
  88.  
  89.     /**
  90.      * 将值 value 关联到 key ,并将 key 的生存时间设为 seconds (以秒为单位)。
  91.      * 如果 key 已经存在, SETEX 命令将覆写旧值。
  92.      * 原子性(atomic)操作,关联值和设置生存时间两个动作会在同一时间内完成
  93.      * @param seconds 以秒为单位
  94.      */
  95.     boolean setex(String key, String value, int seconds);
  96.  
  97.     /**
  98.      * 订阅一个或多个符合给定模式的频道。
  99.      * 每个模式以 * 作为匹配符,比如 it* 匹配所有以 it 开头的频道( it.news 、 it.blog 、 it.tweets 等等),
  100.      * news.* 匹配所有以 news. 开头的频道( news.it 、 news.global.today 等等),诸如此类。
  101.      */
  102.     <extends JedisPubSub> void psubscribe(T jedisPubSub, String... patterns);
  103. }
  • 对应实现

  1. /**
  2.  * Redis实现
  3.  */
  4. @Configuration
  5. public class JedisClientPool implements JedisClient {
  6.  
  7.     private final JedisPool jedisPool;
  8.  
  9.     private static final Logger logger = LoggerFactory.getLogger(JedisClientPool.class);
  10.  
  11.     @Autowired
  12.     public JedisClientPool(JedisPool jedisPool) {
  13.         this.jedisPool = jedisPool;
  14.     }
  15.  
  16.     @Override
  17.     public void set(String key, String value) {
  18.         Jedis jedis = jedisPool.getResource();
  19.         jedis.set(key, value);
  20.         jedis.close();
  21.     }
  22.  
  23.     @Override
  24.     public String get(String key) {
  25.         Jedis jedis = jedisPool.getResource();
  26.         String result = jedis.get(key);
  27.         jedis.close();
  28.         return result;
  29.     }
  30.  
  31.     @Override
  32.     public Boolean exists(String key) {
  33.         Jedis jedis = jedisPool.getResource();
  34.         Boolean result = jedis.exists(key);
  35.         jedis.close();
  36.         return result;
  37.     }
  38.  
  39.     @Override
  40.     public void expire(String key, int seconds) {
  41.         Jedis jedis = jedisPool.getResource();
  42.         jedis.expire(key, seconds);
  43.         jedis.close();
  44.     }
  45.  
  46.     @Override
  47.     public Long ttl(String key) {
  48.         Jedis jedis = jedisPool.getResource();
  49.         Long result = jedis.ttl(key);
  50.         jedis.close();
  51.         return result;
  52.     }
  53.  
  54.     @Override
  55.     public Long incr(String key) {
  56.         Jedis jedis = jedisPool.getResource();
  57.         Long result = jedis.incr(key);
  58.         jedis.close();
  59.         return result;
  60.     }
  61.  
  62.     @Override
  63.     public Long decr(String key) {
  64.         Jedis jedis = jedisPool.getResource();
  65.         Long result = jedis.decr(key);
  66.         jedis.close();
  67.         return result;
  68.     }
  69.  
  70.     @Override
  71.     public Long hset(String key, String field, String value) {
  72.         Jedis jedis = jedisPool.getResource();
  73.         Long result = jedis.hset(key, field, value);
  74.         jedis.close();
  75.         return result;
  76.     }
  77.  
  78.     @Override
  79.     public String hget(String key, String field) {
  80.         Jedis jedis = jedisPool.getResource();
  81.         String result = jedis.hget(key, field);
  82.         jedis.close();
  83.         return result;
  84.     }
  85.  
  86.     @Override
  87.     public Long hdel(String key, String... field) {
  88.         Jedis jedis = jedisPool.getResource();
  89.         Long result = jedis.hdel(key, field);
  90.         jedis.close();
  91.         return result;
  92.     }
  93.  
  94.     @Override
  95.     public Boolean hexists(String key, String field) {
  96.         Jedis jedis = jedisPool.getResource();
  97.         Boolean result = jedis.hexists(key, field);
  98.         jedis.close();
  99.         return result;
  100.     }
  101.  
  102.     @Override
  103.     public List<String> hvals(String key) {
  104.         Jedis jedis = jedisPool.getResource();
  105.         List<String> result = jedis.hvals(key);
  106.         jedis.close();
  107.         return result;
  108.     }
  109.  
  110.     @Override
  111.     public Long del(String key) {
  112.         Jedis jedis = jedisPool.getResource();
  113.         Long result = jedis.del(key);
  114.         jedis.close();
  115.         return result;
  116.     }
  117.  
  118.     @Override
  119.     public String set(String key, String value, String nxxx, String expx, long time) {
  120.         Jedis jedis = jedisPool.getResource();
  121.         String result = jedis.set(key, value, nxxx, expx, time);
  122.         jedis.close();
  123.         return result;
  124.     }
  125.  
  126.     @Override
  127.     public Object eval(String script, List<String> keys, List<String> args) {
  128.         Jedis jedis = jedisPool.getResource();
  129.         Object result = jedis.eval(script, keys, args);
  130.         jedis.close();
  131.         return result;
  132.     }
  133.  
  134.     @Override
  135.     public boolean setex(String key, String value, int seconds) {
  136.         Jedis jedis = jedisPool.getResource();
  137.         String result = jedis.setex(key, seconds, value);
  138.         jedis.close();
  139.         return "ok".equalsIgnoreCase(result);
  140.     }
  141.  
  142.     @Override
  143.     public <extends JedisPubSub> void psubscribe(T jedisPubSub, String... patterns) {
  144.         Jedis jedis = jedisPool.getResource();
  145.         String parameter = "notify-keyspace-events";
  146.         List<String> notify = jedis.configGet(parameter);
  147.         if(StringUtils.isBlank(notify.get(1))) {
  148.             logger.info("重新设置过期事件 -->"+parameter);
  149.             // 过期事件
  150.             jedis.configSet(parameter, "Ex"); 
  151.         }
  152.         jedis.psubscribe(jedisPubSub, patterns);
  153.         jedis.close();
  154.     }
  155. }

至此,所有流程OK,测试一下~

  • 单元测试

  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest
  3. public class ZjH5ApplicationTests {
  4.     
  5.     @Autowired
  6.     private JedisClient jedis;
  7.     
  8.     @Test
  9.     public void contextLoads() {
  10.         jedis.set("test..........", String.valueOf(System.currentTimeMillis()));
  11.     }
  12.  
  13. }

在这里插入图片描述

测试OK,可以开心的撸代码啦~~~

注:如果流程中出现什么问题记得耐心的查看日志。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号