feat(cache): 自动装配 + spring.factories 注册

This commit is contained in:
root
2026-06-26 04:59:41 +08:00
parent 037fdc4f9c
commit c4ad3670fc
3 changed files with 101 additions and 1 deletions

View File

@@ -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);
}
}

View File

@@ -1,2 +1,3 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.njcn.middle.stream.autoconfig.RedisStreamAutoConfiguration com.njcn.middle.stream.autoconfig.RedisStreamAutoConfiguration,\
com.njcn.middle.cache.autoconfig.RedisCacheAutoConfiguration

View File

@@ -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());
}
}
}