1. RedissionRedis客户端中比较优秀的一个。学好Redission的使用是必要的。现在的项目开发,主要使用SpringBoot框架。那么我们就介绍一下SpringBoot如何整合Redission

1.整合方式

SpringBoot整合Redission需要关注一下SpringBoot的版本信息。作者使用的是SpringBoot2.6.2版本。于是我整合Redission的方式是:

  1. <dependency>
  2. <groupId>org.redisson</groupId>
  3. <artifactId>redisson-spring-boot-starter</artifactId>
  4. <version>3.16.7</version>
  5. <exclusions>
  6. <exclusion>
  7. <groupId>org.redisson</groupId>
  8. <artifactId>redisson-spring-data-25</artifactId>
  9. </exclusion>
  10. </exclusions>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.redisson</groupId>
  14. <artifactId>redisson-spring-data-26</artifactId>
  15. <version>3.16.7</version>
  16. </dependency>

这里作者剔除**redisson-spring-data-25**呢?

image.png 如果我使用SpringBoot2.6.x的话,最后匹配redission-spring-data-26

2.配置

这里我们只需像使用spring-boot-starter-redis那样配置一下redis位置就可以了。其他一些Bean配置都不需要我们做。Redission这个整合包中的RedissonAutoConfiguration已经帮我们配置好了。

  1. @Configuration
  2. @ConditionalOnClass({Redisson.class, RedisOperations.class})
  3. @AutoConfigureBefore(RedisAutoConfiguration.class)
  4. @EnableConfigurationProperties({RedissonProperties.class, RedisProperties.class})
  5. public class RedissonAutoConfiguration {
  6. private static final String REDIS_PROTOCOL_PREFIX = "redis://";
  7. private static final String REDISS_PROTOCOL_PREFIX = "rediss://";
  8. @Autowired(required = false)
  9. private List<RedissonAutoConfigurationCustomizer> redissonAutoConfigurationCustomizers;
  10. @Autowired
  11. private RedissonProperties redissonProperties;
  12. @Autowired
  13. private RedisProperties redisProperties;
  14. @Autowired
  15. private ApplicationContext ctx;
  16. /** redisTemplate注入就用*/
  17. @Bean
  18. @ConditionalOnMissingBean(name = "redisTemplate")
  19. public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
  20. RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
  21. template.setConnectionFactory(redisConnectionFactory);
  22. return template;
  23. }
  24. /** stringRedisTemplate注入就用*/
  25. @Bean
  26. @ConditionalOnMissingBean(StringRedisTemplate.class)
  27. public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
  28. StringRedisTemplate template = new StringRedisTemplate();
  29. template.setConnectionFactory(redisConnectionFactory);
  30. return template;
  31. }
  32. @Bean
  33. @ConditionalOnMissingBean(RedisConnectionFactory.class)
  34. public RedissonConnectionFactory redissonConnectionFactory(RedissonClient redisson) {
  35. return new RedissonConnectionFactory(redisson);
  36. }
  37. @Bean
  38. @Lazy
  39. @ConditionalOnMissingBean(RedissonReactiveClient.class)
  40. public RedissonReactiveClient redissonReactive(RedissonClient redisson) {
  41. return redisson.reactive();
  42. }
  43. @Bean
  44. @Lazy
  45. @ConditionalOnMissingBean(RedissonRxClient.class)
  46. public RedissonRxClient redissonRxJava(RedissonClient redisson) {
  47. return redisson.rxJava();
  48. }
  49. @Bean(destroyMethod = "shutdown")
  50. @ConditionalOnMissingBean(RedissonClient.class)
  51. public RedissonClient redisson() throws IOException {
  52. Config config = null;
  53. Method clusterMethod = ReflectionUtils.findMethod(RedisProperties.class, "getCluster");
  54. Method timeoutMethod = ReflectionUtils.findMethod(RedisProperties.class, "getTimeout");
  55. Object timeoutValue = ReflectionUtils.invokeMethod(timeoutMethod, redisProperties);
  56. int timeout;
  57. if(null == timeoutValue){
  58. timeout = 10000;
  59. }else if (!(timeoutValue instanceof Integer)) {
  60. Method millisMethod = ReflectionUtils.findMethod(timeoutValue.getClass(), "toMillis");
  61. timeout = ((Long) ReflectionUtils.invokeMethod(millisMethod, timeoutValue)).intValue();
  62. } else {
  63. timeout = (Integer)timeoutValue;
  64. }
  65. if (redissonProperties.getConfig() != null) {
  66. try {
  67. config = Config.fromYAML(redissonProperties.getConfig());
  68. } catch (IOException e) {
  69. try {
  70. config = Config.fromJSON(redissonProperties.getConfig());
  71. } catch (IOException e1) {
  72. throw new IllegalArgumentException("Can't parse config", e1);
  73. }
  74. }
  75. } else if (redissonProperties.getFile() != null) {
  76. try {
  77. InputStream is = getConfigStream();
  78. config = Config.fromYAML(is);
  79. } catch (IOException e) {
  80. // trying next format
  81. try {
  82. InputStream is = getConfigStream();
  83. config = Config.fromJSON(is);
  84. } catch (IOException e1) {
  85. throw new IllegalArgumentException("Can't parse config", e1);
  86. }
  87. }
  88. } else if (redisProperties.getSentinel() != null) {
  89. Method nodesMethod = ReflectionUtils.findMethod(Sentinel.class, "getNodes");
  90. Object nodesValue = ReflectionUtils.invokeMethod(nodesMethod, redisProperties.getSentinel());
  91. String[] nodes;
  92. if (nodesValue instanceof String) {
  93. nodes = convert(Arrays.asList(((String)nodesValue).split(",")));
  94. } else {
  95. nodes = convert((List<String>)nodesValue);
  96. }
  97. config = new Config();
  98. config.useSentinelServers()
  99. .setMasterName(redisProperties.getSentinel().getMaster())
  100. .addSentinelAddress(nodes)
  101. .setDatabase(redisProperties.getDatabase())
  102. .setConnectTimeout(timeout)
  103. .setPassword(redisProperties.getPassword());
  104. } else if (clusterMethod != null && ReflectionUtils.invokeMethod(clusterMethod, redisProperties) != null) {
  105. Object clusterObject = ReflectionUtils.invokeMethod(clusterMethod, redisProperties);
  106. Method nodesMethod = ReflectionUtils.findMethod(clusterObject.getClass(), "getNodes");
  107. List<String> nodesObject = (List) ReflectionUtils.invokeMethod(nodesMethod, clusterObject);
  108. String[] nodes = convert(nodesObject);
  109. config = new Config();
  110. config.useClusterServers()
  111. .addNodeAddress(nodes)
  112. .setConnectTimeout(timeout)
  113. .setPassword(redisProperties.getPassword());
  114. } else {
  115. config = new Config();
  116. String prefix = REDIS_PROTOCOL_PREFIX;
  117. Method method = ReflectionUtils.findMethod(RedisProperties.class, "isSsl");
  118. if (method != null && (Boolean)ReflectionUtils.invokeMethod(method, redisProperties)) {
  119. prefix = REDISS_PROTOCOL_PREFIX;
  120. }
  121. config.useSingleServer()
  122. .setAddress(prefix + redisProperties.getHost() + ":" + redisProperties.getPort())
  123. .setConnectTimeout(timeout)
  124. .setDatabase(redisProperties.getDatabase())
  125. .setPassword(redisProperties.getPassword());
  126. }
  127. if (redissonAutoConfigurationCustomizers != null) {
  128. for (RedissonAutoConfigurationCustomizer customizer : redissonAutoConfigurationCustomizers) {
  129. customizer.customize(config);
  130. }
  131. }
  132. return Redisson.create(config);
  133. }
  134. private String[] convert(List<String> nodesObject) {
  135. List<String> nodes = new ArrayList<String>(nodesObject.size());
  136. for (String node : nodesObject) {
  137. if (!node.startsWith(REDIS_PROTOCOL_PREFIX) && !node.startsWith(REDISS_PROTOCOL_PREFIX)) {
  138. nodes.add(REDIS_PROTOCOL_PREFIX + node);
  139. } else {
  140. nodes.add(node);
  141. }
  142. }
  143. return nodes.toArray(new String[nodes.size()]);
  144. }
  145. private InputStream getConfigStream() throws IOException {
  146. Resource resource = ctx.getResource(redissonProperties.getFile());
  147. InputStream is = resource.getInputStream();
  148. return is;
  149. }
  150. }

jar包引入后,我们可以直接通过注入的方式使用一下类: