Skip to content

Commit 1502485

Browse files
committed
INT-4565: Fix IntComponentScan for profiles (#2652)
* INT-4565: Fix IntComponentScan for profiles JIRA: https://jira.spring.io/browse/INT-4565 * Propagate an `Environment` to the internal `ClassPathScanningCandidateComponentProvider` in the `IntegrationComponentScanRegistrar` for proper profiles activation * Ensure the logic works in the `GatewayInterfaceTests` * Some polishing and performance improvement for the `GatewayInterfaceTests` * Add a note about `@Profile` in the `gateway.adoc` * Polishing for the `gateway.adoc` **Cherry-pick to 5.0.x & 4.3.x** * * Add not activated by profile gateway interface into the `GatewayInterfaceTests` * More `GatewayInterfaceTests` polishing * Fix typo in the `gateway.adoc` * Fix Checkstyle violation # Conflicts: # spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayInterfaceTests.java # src/reference/asciidoc/gateway.adoc
1 parent 7a2547f commit 1502485

File tree

3 files changed

+103
-61
lines changed

3 files changed

+103
-61
lines changed

spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationComponentScanRegistrar.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,14 @@
6161
*
6262
* @author Artem Bilan
6363
* @author Gary Russell
64+
*
6465
* @since 4.0
6566
*/
6667
public class IntegrationComponentScanRegistrar implements ImportBeanDefinitionRegistrar,
6768
ResourceLoaderAware, EnvironmentAware {
6869

69-
private final Map<TypeFilter, ImportBeanDefinitionRegistrar> componentRegistrars = new HashMap<TypeFilter, ImportBeanDefinitionRegistrar>();
70+
private final Map<TypeFilter, ImportBeanDefinitionRegistrar> componentRegistrars =
71+
new HashMap<TypeFilter, ImportBeanDefinitionRegistrar>();
7072

7173
private ResourceLoader resourceLoader;
7274

@@ -98,14 +100,16 @@ public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, B
98100
basePackages = Collections.singleton(ClassUtils.getPackageName(importingClassMetadata.getClassName()));
99101
}
100102

101-
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false) {
103+
ClassPathScanningCandidateComponentProvider scanner =
104+
new ClassPathScanningCandidateComponentProvider(false, this.environment) {
102105

103-
@Override
104-
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
105-
return beanDefinition.getMetadata().isIndependent()
106-
&& !beanDefinition.getMetadata().isAnnotation();
107-
}
108-
};
106+
@Override
107+
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
108+
return beanDefinition.getMetadata().isIndependent()
109+
&& !beanDefinition.getMetadata().isAnnotation();
110+
}
111+
112+
};
109113

110114
if ((boolean) componentScan.get("useDefaultFilters")) {
111115
for (TypeFilter typeFilter : this.componentRegistrars.keySet()) {

spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayInterfaceTests.java

Lines changed: 77 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import static org.junit.Assert.assertFalse;
2424
import static org.junit.Assert.assertNotEquals;
2525
import static org.junit.Assert.assertNotNull;
26+
import static org.junit.Assert.assertNotSame;
2627
import static org.junit.Assert.assertNull;
2728
import static org.junit.Assert.assertSame;
2829
import static org.junit.Assert.assertThat;
@@ -59,6 +60,7 @@
5960
import org.springframework.context.annotation.ComponentScan;
6061
import org.springframework.context.annotation.Configuration;
6162
import org.springframework.context.annotation.FilterType;
63+
import org.springframework.context.annotation.Profile;
6264
import org.springframework.context.support.ClassPathXmlApplicationContext;
6365
import org.springframework.core.task.AsyncTaskExecutor;
6466
import org.springframework.core.task.SimpleAsyncTaskExecutor;
@@ -77,6 +79,7 @@
7779
import org.springframework.integration.context.IntegrationProperties;
7880
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
7981
import org.springframework.integration.handler.BridgeHandler;
82+
import org.springframework.integration.handler.DelayHandler;
8083
import org.springframework.integration.support.MessageBuilder;
8184
import org.springframework.integration.test.util.TestUtils;
8285
import org.springframework.lang.Nullable;
@@ -93,6 +96,7 @@
9396
import org.springframework.scheduling.annotation.AsyncResult;
9497
import org.springframework.stereotype.Component;
9598
import org.springframework.test.annotation.DirtiesContext;
99+
import org.springframework.test.context.ActiveProfiles;
96100
import org.springframework.test.context.ContextConfiguration;
97101
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
98102
import org.springframework.util.concurrent.ListenableFuture;
@@ -107,6 +111,7 @@
107111
@ContextConfiguration(classes = GatewayInterfaceTests.TestConfig.class)
108112
@RunWith(SpringJUnit4ClassRunner.class)
109113
@DirtiesContext
114+
@ActiveProfiles("gatewayTest")
110115
public class GatewayInterfaceTests {
111116

112117
private static final String IGNORE_HEADER = "ignoreHeader";
@@ -153,19 +158,23 @@ public class GatewayInterfaceTests {
153158
@Autowired
154159
private IgnoredHeaderGateway ignoredHeaderGateway;
155160

161+
@Autowired(required = false)
162+
private NotActivatedByProfileGateway notActivatedByProfileGateway;
163+
156164
@Test
157165
public void testWithServiceSuperclassAnnotatedMethod() throws Exception {
158-
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
166+
ConfigurableApplicationContext ac =
167+
new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", getClass());
159168
DirectChannel channel = ac.getBean("requestChannelFoo", DirectChannel.class);
160169
final Method fooMethod = Foo.class.getMethod("foo", String.class);
161170
final AtomicBoolean called = new AtomicBoolean();
162171
MessageHandler handler = message -> {
163-
assertThat((String) message.getHeaders().get("name"), equalTo("foo"));
164-
assertThat(
165-
(String) message.getHeaders().get("string"),
166-
equalTo("public abstract void org.springframework.integration.gateway.GatewayInterfaceTests$Foo.foo(java.lang.String)"));
167-
assertThat((Method) message.getHeaders().get("object"), equalTo(fooMethod));
168-
assertThat((String) message.getPayload(), equalTo("hello"));
172+
assertThat(message.getHeaders().get("name"), equalTo("foo"));
173+
assertThat(message.getHeaders().get("string"),
174+
equalTo("public abstract void org.springframework.integration.gateway." +
175+
"GatewayInterfaceTests$Foo.foo(java.lang.String)"));
176+
assertThat(message.getHeaders().get("object"), equalTo(fooMethod));
177+
assertThat(message.getPayload(), equalTo("hello"));
169178
assertThat(new MessageHeaderAccessor(message).getErrorChannel(), equalTo("errorChannel"));
170179
called.set(true);
171180
};
@@ -180,17 +189,18 @@ public void testWithServiceSuperclassAnnotatedMethod() throws Exception {
180189

181190
@Test
182191
public void testWithServiceSuperclassAnnotatedMethodOverridePE() throws Exception {
183-
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests2-context.xml", this.getClass());
192+
ConfigurableApplicationContext ac =
193+
new ClassPathXmlApplicationContext("GatewayInterfaceTests2-context.xml", getClass());
184194
DirectChannel channel = ac.getBean("requestChannelFoo", DirectChannel.class);
185195
final Method fooMethod = Foo.class.getMethod("foo", String.class);
186196
final AtomicBoolean called = new AtomicBoolean();
187197
MessageHandler handler = message -> {
188-
assertThat((String) message.getHeaders().get("name"), equalTo("foo"));
189-
assertThat(
190-
(String) message.getHeaders().get("string"),
191-
equalTo("public abstract void org.springframework.integration.gateway.GatewayInterfaceTests$Foo.foo(java.lang.String)"));
192-
assertThat((Method) message.getHeaders().get("object"), equalTo(fooMethod));
193-
assertThat((String) message.getPayload(), equalTo("foo"));
198+
assertThat(message.getHeaders().get("name"), equalTo("foo"));
199+
assertThat(message.getHeaders().get("string"),
200+
equalTo("public abstract void org.springframework.integration.gateway." +
201+
"GatewayInterfaceTests$Foo.foo(java.lang.String)"));
202+
assertThat(message.getHeaders().get("object"), equalTo(fooMethod));
203+
assertThat(message.getPayload(), equalTo("foo"));
194204
called.set(true);
195205
};
196206
channel.subscribe(handler);
@@ -202,7 +212,8 @@ public void testWithServiceSuperclassAnnotatedMethodOverridePE() throws Exceptio
202212

203213
@Test
204214
public void testWithServiceAnnotatedMethod() {
205-
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
215+
ConfigurableApplicationContext ac =
216+
new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", getClass());
206217
DirectChannel channel = ac.getBean("requestChannelBar", DirectChannel.class);
207218
MessageHandler handler = mock(MessageHandler.class);
208219
channel.subscribe(handler);
@@ -214,15 +225,17 @@ public void testWithServiceAnnotatedMethod() {
214225

215226
@Test
216227
public void testWithServiceSuperclassUnAnnotatedMethod() throws Exception {
217-
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
228+
ConfigurableApplicationContext ac =
229+
new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", getClass());
218230
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
219231
final Method bazMethod = Foo.class.getMethod("baz", String.class);
220232
final AtomicBoolean called = new AtomicBoolean();
221233
MessageHandler handler = message -> {
222234
assertThat((String) message.getHeaders().get("name"), equalTo("overrideGlobal"));
223235
assertThat(
224236
(String) message.getHeaders().get("string"),
225-
equalTo("public abstract void org.springframework.integration.gateway.GatewayInterfaceTests$Foo.baz(java.lang.String)"));
237+
equalTo("public abstract void org.springframework.integration.gateway." +
238+
"GatewayInterfaceTests$Foo.baz(java.lang.String)"));
226239
assertThat((Method) message.getHeaders().get("object"), equalTo(bazMethod));
227240
assertThat((String) message.getPayload(), equalTo("hello"));
228241
called.set(true);
@@ -236,15 +249,17 @@ public void testWithServiceSuperclassUnAnnotatedMethod() throws Exception {
236249

237250
@Test
238251
public void testWithServiceUnAnnotatedMethodGlobalHeaderDoesntOverride() throws Exception {
239-
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
252+
ConfigurableApplicationContext ac =
253+
new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", getClass());
240254
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
241255
final Method quxMethod = Bar.class.getMethod("qux", String.class, String.class);
242256
final AtomicBoolean called = new AtomicBoolean();
243257
MessageHandler handler = message -> {
244258
assertThat((String) message.getHeaders().get("name"), equalTo("arg1"));
245259
assertThat(
246260
(String) message.getHeaders().get("string"),
247-
equalTo("public abstract void org.springframework.integration.gateway.GatewayInterfaceTests$Bar.qux(java.lang.String,java.lang.String)"));
261+
equalTo("public abstract void org.springframework.integration.gateway." +
262+
"GatewayInterfaceTests$Bar.qux(java.lang.String,java.lang.String)"));
248263
assertThat((Method) message.getHeaders().get("object"), equalTo(quxMethod));
249264
assertThat((String) message.getPayload(), equalTo("hello"));
250265
called.set(true);
@@ -258,7 +273,8 @@ public void testWithServiceUnAnnotatedMethodGlobalHeaderDoesntOverride() throws
258273

259274
@Test
260275
public void testWithServiceCastAsSuperclassAnnotatedMethod() {
261-
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
276+
ConfigurableApplicationContext ac =
277+
new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", getClass());
262278
DirectChannel channel = ac.getBean("requestChannelFoo", DirectChannel.class);
263279
MessageHandler handler = mock(MessageHandler.class);
264280
channel.subscribe(handler);
@@ -270,7 +286,8 @@ public void testWithServiceCastAsSuperclassAnnotatedMethod() {
270286

271287
@Test
272288
public void testWithServiceCastAsSuperclassUnAnnotatedMethod() {
273-
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
289+
ConfigurableApplicationContext ac =
290+
new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", getClass());
274291
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
275292
MessageHandler handler = mock(MessageHandler.class);
276293
channel.subscribe(handler);
@@ -281,8 +298,9 @@ public void testWithServiceCastAsSuperclassUnAnnotatedMethod() {
281298
}
282299

283300
@Test
284-
public void testWithServiceHashcode() throws Exception {
285-
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
301+
public void testWithServiceHashcode() {
302+
ConfigurableApplicationContext ac =
303+
new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", getClass());
286304
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
287305
MessageHandler handler = mock(MessageHandler.class);
288306
channel.subscribe(handler);
@@ -294,7 +312,8 @@ public void testWithServiceHashcode() throws Exception {
294312

295313
@Test
296314
public void testWithServiceToString() {
297-
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
315+
ConfigurableApplicationContext ac =
316+
new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", getClass());
298317
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
299318
MessageHandler handler = mock(MessageHandler.class);
300319
channel.subscribe(handler);
@@ -306,27 +325,29 @@ public void testWithServiceToString() {
306325

307326
@Test
308327
public void testWithServiceEquals() throws Exception {
309-
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
328+
ConfigurableApplicationContext ac =
329+
new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", getClass());
310330
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
311331
MessageHandler handler = mock(MessageHandler.class);
312332
channel.subscribe(handler);
313333
Bar bar = ac.getBean(Bar.class);
314-
assertTrue(bar.equals(ac.getBean(Bar.class)));
334+
assertSame(bar, ac.getBean(Bar.class));
315335
GatewayProxyFactoryBean fb = new GatewayProxyFactoryBean(Bar.class);
316336
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
317337
bf.registerSingleton("requestChannelBar", channel);
318338
bf.registerSingleton("requestChannelBaz", channel);
319339
bf.registerSingleton("requestChannelFoo", channel);
320340
fb.setBeanFactory(bf);
321341
fb.afterPropertiesSet();
322-
assertFalse(bar.equals(fb.getObject()));
342+
assertNotSame(bar, fb.getObject());
323343
verify(handler, times(0)).handleMessage(Mockito.any(Message.class));
324344
ac.close();
325345
}
326346

327347
@Test
328348
public void testWithServiceGetClass() {
329-
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
349+
ConfigurableApplicationContext ac =
350+
new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", getClass());
330351
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
331352
MessageHandler handler = mock(MessageHandler.class);
332353
channel.subscribe(handler);
@@ -343,11 +364,12 @@ public void testWithServiceAsNotAnInterface() {
343364

344365
@Test
345366
public void testWithCustomMapper() {
346-
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
367+
ConfigurableApplicationContext ac =
368+
new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", getClass());
347369
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
348370
final AtomicBoolean called = new AtomicBoolean();
349371
MessageHandler handler = message -> {
350-
assertThat((String) message.getPayload(), equalTo("fizbuz"));
372+
assertThat(message.getPayload(), equalTo("fizbuz"));
351373
called.set(true);
352374
};
353375
channel.subscribe(handler);
@@ -359,8 +381,13 @@ public void testWithCustomMapper() {
359381

360382
@Test
361383
public void testLateReply() throws Exception {
362-
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml",
363-
this.getClass());
384+
ConfigurableApplicationContext ac =
385+
new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", getClass());
386+
387+
DelayHandler delayHandler = ac.getBean(DelayHandler.class);
388+
delayHandler.setMaxAttempts(2);
389+
delayHandler.setRetryDelay(10);
390+
364391
Bar baz = ac.getBean(Bar.class);
365392
String reply = baz.lateReply("hello", 1000, 0);
366393
assertNull(reply);
@@ -438,14 +465,15 @@ public void testAutoCreateChannelGateway() {
438465
@SuppressWarnings("rawtypes")
439466
public void testAnnotationGatewayProxyFactoryBean() {
440467
assertNotNull(this.gatewayByAnnotationGPFB);
468+
assertNull(this.notActivatedByProfileGateway);
441469

442470
assertSame(this.exec, this.annotationGatewayProxyFactoryBean.getAsyncExecutor());
443-
assertEquals(1111L, TestUtils
444-
.getPropertyValue(this.annotationGatewayProxyFactoryBean, "defaultRequestTimeout", Expression.class)
445-
.getValue());
446-
assertEquals(222L, TestUtils
447-
.getPropertyValue(this.annotationGatewayProxyFactoryBean, "defaultReplyTimeout", Expression.class)
448-
.getValue());
471+
assertEquals(1111L,
472+
TestUtils.getPropertyValue(this.annotationGatewayProxyFactoryBean,
473+
"defaultRequestTimeout", Expression.class).getValue());
474+
assertEquals(222L,
475+
TestUtils.getPropertyValue(this.annotationGatewayProxyFactoryBean,
476+
"defaultReplyTimeout", Expression.class).getValue());
449477

450478
Collection<MessagingGatewaySupport> messagingGateways =
451479
this.annotationGatewayProxyFactoryBean.getGateways().values();
@@ -549,7 +577,7 @@ public interface NoArgumentsGateway {
549577
public static class BazMapper implements MethodArgsMessageMapper {
550578

551579
@Override
552-
public Message<?> toMessage(MethodArgsHolder object, @Nullable Map<String, Object> headers) throws Exception {
580+
public Message<?> toMessage(MethodArgsHolder object, @Nullable Map<String, Object> headers) {
553581
return MessageBuilder.withPayload("fizbuz")
554582
.copyHeadersIfAbsent(headers)
555583
.build();
@@ -637,6 +665,7 @@ public GatewayProxyFactoryBean annotationGatewayProxyFactoryBean() {
637665

638666
@MessagingGateway
639667
@TestMessagingGateway
668+
@Profile("gatewayTest")
640669
public interface Int2634Gateway {
641670

642671
@Gateway(requestChannel = "gatewayChannel", payloadExpression = "#args[0]")
@@ -650,6 +679,15 @@ public interface Int2634Gateway {
650679

651680
}
652681

682+
@MessagingGateway(defaultRequestChannel = "errorChannel")
683+
@TestMessagingGateway
684+
@Profile("notActiveProfile")
685+
public interface NotActivatedByProfileGateway {
686+
687+
void send(String payload);
688+
689+
}
690+
653691
@MessagingGateway(asyncExecutor = "exec")
654692
@TestMessagingGateway
655693
public interface ExecGateway {

0 commit comments

Comments
 (0)