Add property to disable redisson in spring boot

See original GitHub issue

Hi!

Is your feature request related to a problem? Please describe. We use redisson with spring-boot-starter in our project. Unfortunately, sometimes we need to disable caching (f.e. on some environments we don’t have redis). When it comes to a spring-data-redis we can just set property:

spring.cache.type: NONE

and caching is disabled, but if we use Redisson then his auto-configuration doesn’t let us run the application without a worked Redis connection.

Describe the solution you’d like

Disable the whole auto-configuration when

spring.cache.type: NONE

Describe alternatives you’ve considered We can add a new maven profile and exclude the redisson dependency but it doesn’t sound well because we get a new profile to maintain.

My current solution

  1. I excluded autoconfigurations:
@EnableAutoConfiguration(exclude = { RedissonAutoConfiguration.class, RedisAutoConfiguration.class })
  1. I made my own auto configuration (based on redisson’s autoconfiguration) where I’ve added @ConditionalOnExpression("'${spring.cache.type}' == 'redis'")
@Configuration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties({RedisProperties.class, RedissonProperties.class})
@ConditionalOnExpression("'${spring.cache.type}' == 'redis'")
public class RedisConfiguration {

  private static final String REDIS_PROTOCOL_PREFIX = "redis://";
  private static final String REDISS_PROTOCOL_PREFIX = "rediss://";

  @Bean
  public RedisTemplate<Object, Object> redisTemplate(
      RedisConnectionFactory redisConnectionFactory) {
    RedisTemplate<Object, Object> template = new RedisTemplate<>();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
  }

  @Bean
  @ConditionalOnMissingBean
  public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
    StringRedisTemplate template = new StringRedisTemplate();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
  }

  @Bean
  public RedissonConnectionFactory redissonConnectionFactory(RedissonClient redisson) {
    return new RedissonConnectionFactory(redisson);
  }


  @Bean(destroyMethod = "shutdown")
  @ConditionalOnMissingBean(RedissonClient.class)
  public RedissonClient redisson(RedissonProperties redissonProperties, ApplicationContext ctx,
      RedisProperties redisProperties) throws IOException {
    Config config = null;
    Method clusterMethod = ReflectionUtils.findMethod(RedisProperties.class, "getCluster");
    Method timeoutMethod = ReflectionUtils.findMethod(RedisProperties.class, "getTimeout");
    Object timeoutValue = ReflectionUtils.invokeMethod(timeoutMethod, redisProperties);
    int timeout;
    if (null == timeoutValue) {
      timeout = 10000;
    } else if (!(timeoutValue instanceof Integer)) {
      Method millisMethod = ReflectionUtils.findMethod(timeoutValue.getClass(), "toMillis");
      timeout = ((Long) ReflectionUtils.invokeMethod(millisMethod, timeoutValue)).intValue();
    } else {
      timeout = (Integer) timeoutValue;
    }

    if (redissonProperties.getFile() != null) {
      InputStream is = getConfigStream(redissonProperties, ctx);
      config = Config.fromYAML(is);

    } else if (redisProperties.getSentinel() != null) {
      Method nodesMethod = ReflectionUtils.findMethod(Sentinel.class, "getNodes");
      Object nodesValue = ReflectionUtils.invokeMethod(nodesMethod, redisProperties.getSentinel());

      String[] nodes;
      if (nodesValue instanceof String) {
        nodes = convert(Arrays.asList(((String) nodesValue).split(",")));
      } else {
        nodes = convert((List<String>) nodesValue);
      }

      config = new Config();
      config.useSentinelServers()
          .setMasterName(redisProperties.getSentinel().getMaster())
          .addSentinelAddress(nodes)
          .setDatabase(redisProperties.getDatabase())
          .setConnectTimeout(timeout)
          .setPassword(redisProperties.getPassword());
    } else if (clusterMethod != null
        && ReflectionUtils.invokeMethod(clusterMethod, redisProperties) != null) {
      Object clusterObject = ReflectionUtils.invokeMethod(clusterMethod, redisProperties);
      Method nodesMethod = ReflectionUtils.findMethod(clusterObject.getClass(), "getNodes");
      List<String> nodesObject = (List) ReflectionUtils.invokeMethod(nodesMethod, clusterObject);

      String[] nodes = convert(nodesObject);

      config = new Config();
      config.useClusterServers()
          .addNodeAddress(nodes)
          .setConnectTimeout(timeout)
          .setPassword(redisProperties.getPassword());
    } else {
      config = new Config();
      String prefix = REDIS_PROTOCOL_PREFIX;
      Method method = ReflectionUtils.findMethod(RedisProperties.class, "isSsl");
      if (method != null && (Boolean) ReflectionUtils.invokeMethod(method, redisProperties)) {
        prefix = REDISS_PROTOCOL_PREFIX;
      }

      config.useSingleServer()
          .setAddress(prefix + redisProperties.getHost() + ":" + redisProperties.getPort())
          .setConnectTimeout(timeout)
          .setDatabase(redisProperties.getDatabase())
          .setPassword(redisProperties.getPassword());
    }

    return Redisson.create(config);
  }

  private String[] convert(List<String> nodesObject) {
    List<String> nodes = new ArrayList<>(nodesObject.size());
    for (String node : nodesObject) {
      if (!node.startsWith(REDIS_PROTOCOL_PREFIX) && !node.startsWith(REDISS_PROTOCOL_PREFIX)) {
        nodes.add(REDIS_PROTOCOL_PREFIX + node);
      } else {
        nodes.add(node);
      }
    }
    return nodes.toArray(new String[nodes.size()]);
  }

  private InputStream getConfigStream(RedissonProperties redissonProperties, ApplicationContext ctx)
      throws IOException {
    Resource resource = ctx.getResource(redissonProperties.getFile());
    return resource.getInputStream();
  }
}

If you agree then I will push a pull request with changes.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:1
  • Comments:8 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
JanCizmarcommented, Jul 10, 2021

Hi, To improve the workaround…

If you don’t want to duplicate all the logic in the RedissonAutoConfiguration just extend it with @ConditionalOnProperty or @ConditionalOnExpression.

@Configuration
@ConditionalOnClass(Redisson::class, RedisOperations::class)
@AutoConfigureBefore(RedisAutoConfiguration::class)
@EnableConfigurationProperties(RedissonProperties::class, RedisProperties::class)
@ConditionalOnProperty(name = ["my.property.use_redis"], havingValue = "true")
class ConditionalRedissonAutoConfiguration : RedissonAutoConfiguration()
0reactions
Us0tsukicommented, Jul 27, 2022

@satsg55

As a solution you can just remove Redisson jar from classpath. RedissonAutoConfiguration won’t start then.

Will this work for you?

I have my own implementation of Redisson Bean, which is @Conditional on an external Spring property. So excluding the jar is not an option. Now the phenomenon is if I “turn on” the property, my own bean is created, otherwise the autoconfiguration is triggered. Is there any workout?

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to disable Redis cache with Spring Boot? - Stack Overflow
I had a requirement to enable/disable Redis auto configuration from spring.cache.type property. The below code solved my issue.
Read more >
How to disable Redis loading in Spring boot - develop with
If you want to disable the auto connection for redis, add the following line to your application definition. @EnableAutoConfiguration(exclude = ...
Read more >
Disabling Redis Auto-configuration in Spring Boot applications
Configuring a Spring Boot application to exclude RedisTemplate auto-configuration. Learn how to disable Spring Boot's auto-configuration for ...
Read more >
A Guide to Redis with Redisson - Baeldung
3.1. Java Configuration ... We specify Redisson configurations in an instance of a Config object and then pass it to the create method....
Read more >
Spring Data Redis
Add the following location of the Spring Milestone repository for Maven ... a PropertySource , which lets you set the following properties:.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found