如何使用Spring Boot禁用Redis缓存?

问题描述 投票:0回答:3

使用 Spring Boot 2.1,我使用 Java 配置在配置文件中定义 RedisCacheManager bean。一切正常,但我有时想禁用它,例如在测试中。 Spring Boot 提供了

spring.cache.type=NONE
来禁用缓存,根据此 documentation。然而,这个属性将不起作用,因为我已经定义了一个 CacheManager,因此 Spring Boot 不会配置我想要的 NoOpCacheManager(
@ConditionalOnMissingBean(CacheManager.class)
上有一个
NoOpCacheConfiguration
,其优先级低于
RedisCacheConfiguration
)。

在定义缓存时,无论提供者是什么(例如 Caffeine),我们通常将它们定义为 beans,然后由 Spring Boot 的自动配置解析为

SimpleCacheManager
。 比如说

    @Bean
    public Cache myCache() {
        return new CaffeineCache(
                "my-cache",
                Caffeine.newBuilder()
                        .maximumSize(10)
                        .build());
    }

不幸的是,这对于 Redis 来说是不可能的,因为它的

Cache
实现
RedisCache
不是公开的。

我们喜欢做的另一件事是定义一个 bean

CacheManagerCustomizer<?>
,例如使用 Caffeine

    @Bean
    public CacheManagerCustomizer<CaffeineCacheManager> caffeineCacheManager() {
        return cacheManager -> cacheManager
                .setCaffeine(Caffeine.newBuilder()
                        .expireAfterWrite(1, TimeUnit.MINUTES));
    }

这对于 Redis 来说是不可能的,因为

RedisCacheManager
不可变的

所以现在唯一的解决方案是创建我们自己的RedisCacheManager,但这会阻止使用

spring.cache.type: NONE

这是我的问题。使用 Spring Boot 配置 Redis 缓存以便我们可以根据需要禁用它的最佳方法是什么?

spring spring-boot spring-test spring-data-redis spring-cache
3个回答
13
投票

我需要从

spring.cache.type
属性启用/禁用 Redis 自动配置。下面的代码解决了我的问题。这可能对那些想通过更改单个属性来禁用/启用 Redis 的人有所帮助,在我的例子中是
spring.cache.type=redis
。以下是主要配置。

@SpringBootApplication(exclude = {RedisAutoConfiguration.class})
public class SpringBootApp extends SpringBootServletInitializer {

}
@ConditionalOnProperty(prefix = "spring", name = "cache.type", havingValue = "redis")
@Configuration
@Import({ RedisAutoConfiguration.class })
public class ApplicationRedisConfig {

}

要从

application.yaml

启用自动配置
spring:
  cache:
    type: redis
  redis.host: redis

当 redis 不可用时,健康检查会给出以下响应,这表明自动配置已包含在内。

{
  "status": "DOWN",
  "details": {
    "diskSpace": {
      "status": "UP",
      "details": {
        "total": 486730272768,
        "free": 216405499904,
        "threshold": 10485760
      }
    },
    "db": {
      "status": "UP",
      "details": {
        "database": "PostgreSQL",
        "hello": 1
      }
    },
    "elasticsearch": {
      "status": "UP"
    },
    "redis": {
      "status": "DOWN",
      "details": {
        "error": "org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to redis:6379"
      }
    }
  }
}

要禁用自动配置

application.yaml

spring:
  cache:
    type: simple
  redis.host: redis

健康检查给出以下响应,表明 redis 已被排除在自动配置之外。

{
  "status": "UP",
  "details": {
    "diskSpace": {
      "status": "UP",
      "details": {
        "total": 486730272768,
        "free": 215928782848,
        "threshold": 10485760
      }
    },
    "db": {
      "status": "UP",
      "details": {
        "database": "PostgreSQL",
        "hello": 1
      }
    },
    "elasticsearch": {
      "status": "UP"
    }
  }
}

0
投票

排除

@SpringBootApplication
注释的属性,例如:
@SpringBootApplication( exclude = { RedisAutoConfiguration.class } )

和 设置:

spring.data.redis.repositories.enabled=false


0
投票

您可以使用resilience4j-spring-boot2依赖项 org.springframework.cache.annotation.CachingConfigurer。 该解决方案适用于最新的 Spring-boot 版本 6.x。 它对我有用。 以下是代码片段:

Pom.xml:

<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot2</artifactId>
 <version>2.1.0</version>
</dependency>
    

缓存配置类:

package com.redis.sample;
    import org.springframework.cache.annotation.CachingConfigurer;
    import org.springframework.cache.interceptor.CacheErrorHandler;
    import org.springframework.context.annotation.Configuration;

    @Configuration
    public class CachingConfiguration implements CachingConfigurer        {  
        @Override
        public CacheErrorHandler errorHandler() {
            return new CustomCacheErrorHandler();
        }
    }

CustomCacheErrorHandler 类:

package com.redis.sample;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.cache.Cache;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.stereotype.Component;

@Component
public class CustomCacheErrorHandler implements CacheErrorHandler {
    
      
    
     
    @Override
    public void handleCacheGetError(RuntimeException exception, Cache cache, Object key) {
        //do something as per usecase
    }

    @Override
    public void handleCachePutError(RuntimeException exception, Cache cache, Object key, Object value) {
        //do something as per usecase
    }

    @Override
    public void handleCacheEvictError(RuntimeException exception, Cache cache, Object key) {
        //do something as per usecase
    }

    @Override
    public void handleCacheClearError(RuntimeException exception, Cache cache) {
        //do something as per usecase
    }
}

CircuitBreakerConfig.java 配置类 包 com.redis.sample;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
@Configuration
public class CircuitBreakerConfig {

    @Bean
    public CircuitBreakerRegistry circuitBreakerRegistry() {
        io.github.resilience4j.circuitbreaker.CircuitBreakerConfig config =  io.github.resilience4j.circuitbreaker.CircuitBreakerConfig.custom()
                .failureRateThreshold(6)
                .permittedNumberOfCallsInHalfOpenState(2)
                .slidingWindowSize(5)
                .minimumNumberOfCalls(5)
                .build();
        return CircuitBreakerRegistry.of(config);
    }
    
     
    @Bean
     public CircuitBreaker defaultCircuitBreaker() {
        io.github.resilience4j.circuitbreaker.CircuitBreakerConfig config = io.github.resilience4j.circuitbreaker.CircuitBreakerConfig.custom()
                .minimumNumberOfCalls(2)
                .build();
        return CircuitBreaker.of("default", config);
     }
}
© www.soinside.com 2019 - 2024. All rights reserved.