ScoredRedisCacheAutoConfiguration.java
package org.oxerr.spring.cache.redis.scored.spring.boot.autoconfigure;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.oxerr.spring.cache.redis.scored.InheritableThreadLocalScoreHolder;
import org.oxerr.spring.cache.redis.scored.ScoreHolder;
import org.oxerr.spring.cache.redis.scored.ScoredRedisCacheInterceptor;
import org.oxerr.spring.cache.redis.scored.ScoredRedisCacheWriter;
import org.oxerr.spring.cache.redis.scored.score.resolver.DefaultScoreResolver;
import org.oxerr.spring.cache.redis.scored.score.resolver.ScoreResolver;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.cache.RedisCacheManagerBuilderCustomizer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.cache.interceptor.BeanFactoryCacheOperationSourceAdvisor;
import org.springframework.cache.interceptor.CacheOperationSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.CacheStatisticsCollector;
import org.springframework.data.redis.cache.RedisCacheManager.RedisCacheManagerBuilder;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
/**
* See {@code org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration}.
*
* <a href="https://docs.spring.io/spring-boot/docs/2.5.3/reference/htmlsingle/#features.caching.provider.redis">
* Spring Boot Features - Caching - Providers - Redis
* </a>
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ ScoredRedisCacheInterceptor.class, ScoredRedisCacheWriter.class })
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class ScoredRedisCacheAutoConfiguration {
@Bean
public RedisCacheManagerBuilderCustomizer redisCacheManagerBuilderCustomizer(
@NonNull final RedisConnectionFactory connectionFactory,
@NonNull final ScoreHolder scoreHolder,
@Nullable final ClassLoader classLoader
) {
return builder -> {
final ScoredRedisCacheWriter cacheWriter = new ScoredRedisCacheWriter(
connectionFactory,
CacheStatisticsCollector.none(),
scoreHolder,
this.getRedisCacheWriter(builder)
);
builder.cacheWriter(cacheWriter);
};
}
@Bean
public ScoredRedisCacheInterceptor scoredRedisCacheInterceptor(
final BeanFactoryCacheOperationSourceAdvisor cacheOperationSourceAdvisor,
final CacheOperationSource cacheOperationSource,
final ScoreHolder scoreHolder
) {
final ScoreResolver scoreResolver = new DefaultScoreResolver();
final ScoredRedisCacheInterceptor scoredRedisCacheInterceptor = new ScoredRedisCacheInterceptor(scoreResolver, scoreHolder);
scoredRedisCacheInterceptor.setCacheOperationSource(cacheOperationSource);
cacheOperationSourceAdvisor.setAdvice(scoredRedisCacheInterceptor);
return scoredRedisCacheInterceptor;
}
@Bean
public ScoreHolder scoreHolder() {
return new InheritableThreadLocalScoreHolder();
}
private RedisCacheWriter getRedisCacheWriter(RedisCacheManagerBuilder builder) {
return this.readDeclaredField(builder, "cacheWriter");
}
@SuppressWarnings("unchecked")
private <T> T readDeclaredField(RedisCacheManagerBuilder builder, String fieldName) {
try {
return (T) FieldUtils.readDeclaredField(builder, fieldName, true);
} catch (IllegalAccessException e) {
throw new IllegalArgumentException(e);
}
}
}