1919import static org .mockito .ArgumentMatchers .*;
2020import static org .mockito .Mockito .*;
2121
22+ import java .util .Map ;
2223import java .util .concurrent .atomic .AtomicReference ;
2324import java .util .function .Consumer ;
2425
2526import org .junit .jupiter .api .Test ;
27+ import org .mockito .ArgumentCaptor ;
2628
2729import org .springframework .beans .factory .BeanCreationException ;
2830import org .springframework .beans .factory .NoSuchBeanDefinitionException ;
2931import org .springframework .context .ApplicationContext ;
3032import org .springframework .context .annotation .AnnotationConfigApplicationContext ;
3133import org .springframework .context .annotation .Bean ;
3234import org .springframework .context .annotation .Configuration ;
35+ import org .springframework .core .env .MapPropertySource ;
3336import org .springframework .data .redis .config .RedisListenerConfigUtils ;
3437import org .springframework .data .redis .config .RedisListenerEndpointRegistry ;
3538import org .springframework .data .redis .listener .RedisMessageListenerContainer ;
4043 *
4144 * @author Ilyass Bougati
4245 * @author Mark Paluch
46+ * @author Dongliang Xie
4347 */
4448class RedisListenerAnnotationBeanPostProcessorIntegrationTests {
4549
@@ -62,6 +66,24 @@ void registersListenerWithDefaultContainer() {
6266 assertThat (registryRef .get ().isRunning ()).isFalse ();
6367 }
6468
69+ @ Test // GH-3393
70+ void resolvesListenerTopicPlaceholder () {
71+
72+ try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext ()) {
73+ context .getEnvironment ().getPropertySources ()
74+ .addFirst (new MapPropertySource ("redis-listener-test" , Map .of ("app.my-channel" , "my-channel" )));
75+ context .register (DefaultConfig .class , PlaceholderTopicService .class );
76+ context .refresh ();
77+
78+ RedisMessageListenerContainer container = context .getBean ("redisMessageListenerContainer" ,
79+ RedisMessageListenerContainer .class );
80+ ArgumentCaptor <Topic > topicCaptor = ArgumentCaptor .forClass (Topic .class );
81+
82+ verify (container ).addMessageListener (any (), topicCaptor .capture ());
83+ assertThat (topicCaptor .getValue ().getTopic ()).isEqualTo ("my-channel" );
84+ }
85+ }
86+
6587 @ Test // GH-3340
6688 void registersListenerWithNamedContainer () {
6789
@@ -140,6 +162,13 @@ public void handle(String msg) {}
140162
141163 }
142164
165+ static class PlaceholderTopicService {
166+
167+ @ RedisListener (topic = "${app.my-channel}" )
168+ public void handle (String msg ) {}
169+
170+ }
171+
143172 static class UnnamedContainerService {
144173
145174 @ RedisListener (topic = "test-topic" , container = "" )
0 commit comments