diff --git a/src/main/java/com/njcn/middle/stream/autoconfig/RedisStreamAutoConfiguration.java b/src/main/java/com/njcn/middle/stream/autoconfig/RedisStreamAutoConfiguration.java index 677ba3f..ff814f1 100644 --- a/src/main/java/com/njcn/middle/stream/autoconfig/RedisStreamAutoConfiguration.java +++ b/src/main/java/com/njcn/middle/stream/autoconfig/RedisStreamAutoConfiguration.java @@ -8,6 +8,7 @@ import com.njcn.middle.stream.support.StreamTrimScheduler; import com.njcn.middle.stream.template.RedisStreamEnhanceTemplate; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; @@ -26,8 +27,9 @@ import java.util.stream.Collectors; * Phase 2 由 message-boot 注入 Processor 即生效。装配在 {@link RedisAutoConfiguration} 之后, * 确保 {@link StringRedisTemplate} 已就绪。 */ -@Configuration +@Configuration(proxyBeanMethods = false) @ConditionalOnClass(StringRedisTemplate.class) +@ConditionalOnBean(StringRedisTemplate.class) @AutoConfigureAfter(RedisAutoConfiguration.class) @EnableConfigurationProperties(RedisStreamProperties.class) public class RedisStreamAutoConfiguration { diff --git a/src/test/java/com/njcn/middle/stream/autoconfig/RedisStreamAutoConfigurationTest.java b/src/test/java/com/njcn/middle/stream/autoconfig/RedisStreamAutoConfigurationTest.java new file mode 100644 index 0000000..41dfbef --- /dev/null +++ b/src/test/java/com/njcn/middle/stream/autoconfig/RedisStreamAutoConfigurationTest.java @@ -0,0 +1,71 @@ +package com.njcn.middle.stream.autoconfig; + +import com.njcn.middle.stream.container.StreamAutoClaimer; +import com.njcn.middle.stream.container.StreamListenerContainer; +import com.njcn.middle.stream.support.StreamKeyBuilder; +import com.njcn.middle.stream.support.StreamTrimScheduler; +import com.njcn.middle.stream.template.RedisStreamEnhanceTemplate; +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; + +/** + * 自动装配测试:验证 stream starter 的 Bean 装配、用户自定义回退、以及缺 {@link StringRedisTemplate} + * 时整类优雅退场(与 cache 装配口径对齐,不因缺依赖启动失败)。 + */ +class RedisStreamAutoConfigurationTest { + + private final ApplicationContextRunner runner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + RedisAutoConfiguration.class, RedisStreamAutoConfiguration.class)) + .withPropertyValues("spring.redis.host=127.0.0.1", "spring.redis.port=6379"); + + @Test + void registersStreamBeans() { + runner.run(ctx -> { + assertThat(ctx).hasSingleBean(StreamKeyBuilder.class); + assertThat(ctx).hasSingleBean(RedisStreamEnhanceTemplate.class); + assertThat(ctx).hasSingleBean(StreamListenerContainer.class); + assertThat(ctx).hasSingleBean(StreamAutoClaimer.class); + assertThat(ctx).hasSingleBean(StreamTrimScheduler.class); + }); + } + + @Test + void backsOffWhenUserDefinesOwnTemplate() { + runner.withUserConfiguration(CustomConfig.class).run(ctx -> { + assertThat(ctx).hasSingleBean(RedisStreamEnhanceTemplate.class); + assertThat(ctx.getBean(RedisStreamEnhanceTemplate.class)) + .isSameAs(ctx.getBean("myTemplate")); + }); + } + + @Test + void backsOffWhenNoStringRedisTemplateBean() { + // 不装配 RedisAutoConfiguration,上下文内无 StringRedisTemplate Bean: + // 应整类 back off 优雅退场,而非因缺依赖启动失败(与 cache 装配口径一致)。 + new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(RedisStreamAutoConfiguration.class)) + .run(ctx -> assertThat(ctx) + .hasNotFailed() + .doesNotHaveBean(RedisStreamEnhanceTemplate.class)); + } + + @Configuration + static class CustomConfig { + @Bean + RedisStreamEnhanceTemplate myTemplate() { + return new RedisStreamEnhanceTemplate( + new StringRedisTemplate(mock(RedisConnectionFactory.class)), + new StreamKeyBuilder(false, "")); + } + } +}