Skip to content

Commit 83469aa

Browse files
mjd507artembilan
andauthored
GH-11024: Option todisable messaging annotations processing
Fixes: #11024 By adding `spring.integration.annotations.enable=false` into the Spring environment. When disabled, the following post processors are not registered in the application context: - `MessagingAnnotationPostProcessor` - `MessagingAnnotationBeanPostProcessor` * Address Comments and update whats-new.adoc & annotations.adoc * Make Tests and Docs more precise and scoped. * Fix doc for "One sentence per line" Signed-off-by: Jiandong Ma <jiandong.ma.cn@gmail.com> Co-authored-by: Artem Bilan <artem.bilan@broadcom.com>
1 parent b699840 commit 83469aa

5 files changed

Lines changed: 144 additions & 4 deletions

File tree

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

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
2525
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
2626
import org.springframework.context.ApplicationContextException;
27+
import org.springframework.context.EnvironmentAware;
2728
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
29+
import org.springframework.core.env.Environment;
2830
import org.springframework.core.type.AnnotationMetadata;
2931
import org.springframework.integration.context.IntegrationContextUtils;
3032
import org.springframework.util.ClassUtils;
@@ -35,10 +37,11 @@
3537
* @author Artem Bilan
3638
* @author Gary Russell
3739
* @author Chris Bono
40+
* @author Jiandong Ma
3841
*
3942
* @since 4.0
4043
*/
41-
public class IntegrationRegistrar implements ImportBeanDefinitionRegistrar {
44+
public class IntegrationRegistrar implements ImportBeanDefinitionRegistrar, EnvironmentAware {
4245

4346
static {
4447
if (ClassUtils.isPresent("org.springframework.integration.dsl.support.Function", null)) {
@@ -49,6 +52,14 @@ public class IntegrationRegistrar implements ImportBeanDefinitionRegistrar {
4952
}
5053
}
5154

55+
@SuppressWarnings("NullAway.Init")
56+
private Environment environment;
57+
58+
@Override
59+
public void setEnvironment(Environment environment) {
60+
this.environment = environment;
61+
}
62+
5263
/**
5364
* Invoked by the framework when an &#64;EnableIntegration annotation is encountered.
5465
* Also called with {@code null} {@code importingClassMetadata} from {@code AbstractIntegrationNamespaceHandler}
@@ -64,7 +75,10 @@ public void registerBeanDefinitions(@Nullable AnnotationMetadata importingClassM
6475

6576
registerDefaultConfiguringBeanFactoryPostProcessor(registry);
6677
registerIntegrationConfigurationBeanFactoryPostProcessor(registry);
67-
if (importingClassMetadata != null) {
78+
79+
if (importingClassMetadata != null
80+
&& this.environment.getProperty("spring.integration.annotations.enable", Boolean.class, true)) {
81+
6882
registerMessagingAnnotationPostProcessors(registry);
6983
}
7084
registerGatewayProxyInstantiationPostProcessor(registry);

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
2828
import org.springframework.beans.factory.xml.BeanDefinitionParser;
2929
import org.springframework.beans.factory.xml.ParserContext;
30+
import org.springframework.core.env.Environment;
3031
import org.springframework.core.type.MethodMetadata;
3132
import org.springframework.integration.config.EnablePublisher;
3233
import org.springframework.integration.config.IntegrationRegistrar;
@@ -43,15 +44,20 @@
4344
* @author Mark Fisher
4445
* @author Artem Bilan
4546
* @author Gary Russell
47+
* @author Jiandong Ma
4648
*/
4749
public class AnnotationConfigParser implements BeanDefinitionParser {
4850

4951
@Override
5052
public @Nullable BeanDefinition parse(Element element, ParserContext parserContext) {
53+
Environment environment = parserContext.getReaderContext().getEnvironment();
54+
55+
IntegrationRegistrar integrationRegistrar = new IntegrationRegistrar();
56+
integrationRegistrar.setEnvironment(environment);
57+
5158
ExtendedAnnotationMetadata importingClassMetadata = new ExtendedAnnotationMetadata(element);
5259
BeanDefinitionRegistry registry = parserContext.getRegistry();
53-
new IntegrationRegistrar()
54-
.registerBeanDefinitions(importingClassMetadata, registry);
60+
integrationRegistrar.registerBeanDefinitions(importingClassMetadata, registry);
5561
if (DomUtils.getChildElementByTagName(element, "enable-publisher") != null) {
5662
new PublisherRegistrar()
5763
.registerBeanDefinitions(importingClassMetadata, registry);
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*
2+
* Copyright 2026-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.integration.config;
18+
19+
import java.beans.Introspector;
20+
21+
import org.assertj.core.api.Assertions;
22+
import org.junit.jupiter.api.Test;
23+
24+
import org.springframework.context.ApplicationContext;
25+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
26+
import org.springframework.context.annotation.Bean;
27+
import org.springframework.context.annotation.Configuration;
28+
import org.springframework.integration.annotation.ServiceActivator;
29+
import org.springframework.integration.context.IntegrationContextUtils;
30+
import org.springframework.messaging.MessageHandler;
31+
import org.springframework.test.context.support.TestPropertySourceUtils;
32+
33+
/**
34+
* @author Jiandong Ma
35+
*/
36+
class IntegrationRegistrarTests {
37+
38+
@Test
39+
void testDefaultEnableMessagingAnnotationsProcessing() {
40+
try (var context = new AnnotationConfigApplicationContext(Config.class)) {
41+
42+
assertContainsBean(context, IntegrationContextUtils.MESSAGING_ANNOTATION_POSTPROCESSOR_NAME);
43+
assertContainsBean(context, Introspector.decapitalize(MessagingAnnotationBeanPostProcessor.class.getName()));
44+
45+
assertContainsBean(context, "inputChannel");
46+
assertContainsBean(context, "customMessageHandler");
47+
assertContainsBean(context, "customMessageHandler.serviceActivator");
48+
assertContainsBean(context, "customMessageHandler.serviceActivator.handler");
49+
}
50+
}
51+
52+
@Test
53+
void testManualEnableMessagingAnnotationsProcessing() {
54+
try (var context = createApplicationContext(true)) {
55+
56+
assertContainsBean(context, IntegrationContextUtils.MESSAGING_ANNOTATION_POSTPROCESSOR_NAME);
57+
assertContainsBean(context, Introspector.decapitalize(MessagingAnnotationBeanPostProcessor.class.getName()));
58+
59+
assertContainsBean(context, "inputChannel");
60+
assertContainsBean(context, "customMessageHandler");
61+
assertContainsBean(context, "customMessageHandler.serviceActivator");
62+
assertContainsBean(context, "customMessageHandler.serviceActivator.handler");
63+
}
64+
}
65+
66+
@Test
67+
void testDisableMessagingAnnotationsProcessing() {
68+
try (var context = createApplicationContext(false)) {
69+
70+
assertDoesNotContainsBean(context, IntegrationContextUtils.MESSAGING_ANNOTATION_POSTPROCESSOR_NAME);
71+
assertDoesNotContainsBean(context, Introspector.decapitalize(MessagingAnnotationBeanPostProcessor.class.getName()));
72+
73+
assertDoesNotContainsBean(context, "inputChannel");
74+
assertContainsBean(context, "customMessageHandler");
75+
assertDoesNotContainsBean(context, "customMessageHandler.serviceActivator");
76+
assertDoesNotContainsBean(context, "customMessageHandler.serviceActivator.handler");
77+
78+
}
79+
}
80+
81+
@Configuration
82+
@EnableIntegration
83+
static class Config {
84+
85+
@Bean
86+
@ServiceActivator(inputChannel = "inputChannel")
87+
MessageHandler customMessageHandler() {
88+
return message -> {
89+
90+
};
91+
}
92+
93+
}
94+
95+
static AnnotationConfigApplicationContext createApplicationContext(boolean enableAnnotationsProcessing) {
96+
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
97+
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(context.getEnvironment(),
98+
"spring.integration.annotations.enable=" + enableAnnotationsProcessing);
99+
100+
context.register(Config.class);
101+
context.refresh();
102+
return context;
103+
}
104+
105+
static void assertContainsBean(ApplicationContext context, String beanName) {
106+
Assertions.assertThat(context.containsBean(beanName)).isTrue();
107+
}
108+
109+
static void assertDoesNotContainsBean(ApplicationContext context, String beanName) {
110+
Assertions.assertThat(context.containsBean(beanName)).isFalse();
111+
}
112+
113+
}

src/reference/antora/modules/ROOT/pages/configuration/annotations.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ public class FooService {
2020
}
2121
----
2222

23+
NOTE: Starting with version 7.1, the `spring.integration.annotations.enable` property in the Spring environment can be used to control method-level annotations processing.
24+
By default, this property is `true`.
25+
It can be set to `false` to disable messaging annotations processing.
26+
2327
Exactly what it means for the method to "`handle`" the Message depends on the particular annotation.
2428
Annotations available in Spring Integration include:
2529

src/reference/antora/modules/ROOT/pages/whats-new.adoc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ See xref:grpc.adoc[] for more information.
3535
The `MessageTransformingHandler.requiresReply` flag cannot be modified: an `UnsupportedOperationException` is thrown from the overridden `setRequiresReply()` method to indicate the transformer pattern cannot produce nulls for replies.
3636
See xref:transformer.adoc[] for more information.
3737

38+
A new `spring.integration.annotations.enable` property is introduced to control method-level annotations processing.
39+
See xref:configuration/annotations.adoc[] for more information.
40+
3841
[[x7.1-web-services-changes]]
3942
=== Web Services Support Changes
4043

0 commit comments

Comments
 (0)