diff --git a/src/main/java/com/njcn/middle/cache/autoconfig/RedisCacheAutoConfiguration.java b/src/main/java/com/njcn/middle/cache/autoconfig/RedisCacheAutoConfiguration.java new file mode 100644 index 0000000..e456ecb --- /dev/null +++ b/src/main/java/com/njcn/middle/cache/autoconfig/RedisCacheAutoConfiguration.java @@ -0,0 +1,45 @@ +package com.njcn.middle.cache.autoconfig; + +import com.njcn.middle.cache.support.CacheKeyBuilder; +import com.njcn.middle.cache.support.CacheValueCodec; +import com.njcn.middle.cache.template.RedisCacheEnhanceTemplate; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.core.StringRedisTemplate; + +/** + * Redis 缓存自动装配。装配在 {@link RedisAutoConfiguration} 之后,确保 {@link StringRedisTemplate} 就绪。 + * 与 stream 装配互不引用;纯模板、无后台线程。 + */ +@Configuration +@ConditionalOnClass(StringRedisTemplate.class) +@AutoConfigureAfter(RedisAutoConfiguration.class) +@EnableConfigurationProperties(RedisCacheProperties.class) +public class RedisCacheAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + public CacheKeyBuilder cacheKeyBuilder(RedisCacheProperties props) { + return new CacheKeyBuilder(props.getKeyPrefix(), props.isEnvIsolation(), props.getEnv()); + } + + @Bean + @ConditionalOnMissingBean + public CacheValueCodec cacheValueCodec() { + return new CacheValueCodec(); + } + + @Bean + @ConditionalOnMissingBean + public RedisCacheEnhanceTemplate redisCacheEnhanceTemplate(StringRedisTemplate redis, + CacheKeyBuilder cacheKeyBuilder, + CacheValueCodec cacheValueCodec, + RedisCacheProperties props) { + return new RedisCacheEnhanceTemplate(redis, cacheKeyBuilder, cacheValueCodec, props); + } +} diff --git a/src/main/resources/META-INF/spring.factories b/src/main/resources/META-INF/spring.factories index fc231e6..5f036af 100644 --- a/src/main/resources/META-INF/spring.factories +++ b/src/main/resources/META-INF/spring.factories @@ -1,2 +1,3 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -com.njcn.middle.stream.autoconfig.RedisStreamAutoConfiguration +com.njcn.middle.stream.autoconfig.RedisStreamAutoConfiguration,\ +com.njcn.middle.cache.autoconfig.RedisCacheAutoConfiguration diff --git a/src/test/java/com/njcn/middle/cache/autoconfig/RedisCacheAutoConfigurationTest.java b/src/test/java/com/njcn/middle/cache/autoconfig/RedisCacheAutoConfigurationTest.java new file mode 100644 index 0000000..275d03d --- /dev/null +++ b/src/test/java/com/njcn/middle/cache/autoconfig/RedisCacheAutoConfigurationTest.java @@ -0,0 +1,54 @@ +package com.njcn.middle.cache.autoconfig; + +import com.njcn.middle.cache.support.CacheKeyBuilder; +import com.njcn.middle.cache.support.CacheValueCodec; +import com.njcn.middle.cache.template.RedisCacheEnhanceTemplate; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.StringRedisTemplate; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +class RedisCacheAutoConfigurationTest { + + private final ApplicationContextRunner runner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + RedisAutoConfiguration.class, RedisCacheAutoConfiguration.class)) + .withPropertyValues("spring.redis.host=127.0.0.1", "spring.redis.port=6379"); + + @Test + void registersCacheBeans() { + runner.run(ctx -> { + assertThat(ctx).hasSingleBean(RedisCacheEnhanceTemplate.class); + assertThat(ctx).hasSingleBean(CacheKeyBuilder.class); + assertThat(ctx).hasSingleBean(CacheValueCodec.class); + }); + } + + @Test + void backsOffWhenUserDefinesOwnTemplate() { + runner.withUserConfiguration(CustomConfig.class).run(ctx -> { + assertThat(ctx).hasSingleBean(RedisCacheEnhanceTemplate.class); + assertThat(ctx.getBean(RedisCacheEnhanceTemplate.class)) + .isSameAs(ctx.getBean("myTemplate")); + }); + } + + @Configuration + static class CustomConfig { + @Bean + RedisCacheEnhanceTemplate myTemplate() { + return new RedisCacheEnhanceTemplate( + new StringRedisTemplate(mock(RedisConnectionFactory.class)), + new CacheKeyBuilder("cache:", false, ""), + new CacheValueCodec(), + new RedisCacheProperties()); + } + } +}