Skip to content

Commit 8722103

Browse files
committed
spring-projectsGH-3111: Document @lazy for messaging annotations
Fixes spring-projects#3111 Fixes spring-projects#3130 * Fix some typos in docs * Ensure in tests that announced `@Lazy` works as expected
1 parent d13752b commit 8722103

File tree

3 files changed

+36
-17
lines changed

3 files changed

+36
-17
lines changed

spring-integration-core/src/test/java/org/springframework/integration/configuration/EnableIntegrationTests.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import org.springframework.context.annotation.ComponentScan;
5656
import org.springframework.context.annotation.Configuration;
5757
import org.springframework.context.annotation.ImportResource;
58+
import org.springframework.context.annotation.Lazy;
5859
import org.springframework.context.expression.EnvironmentAccessor;
5960
import org.springframework.context.expression.MapAccessor;
6061
import org.springframework.core.convert.converter.Converter;
@@ -65,6 +66,7 @@
6566
import org.springframework.integration.annotation.Aggregator;
6667
import org.springframework.integration.annotation.BridgeFrom;
6768
import org.springframework.integration.annotation.BridgeTo;
69+
import org.springframework.integration.annotation.EndpointId;
6870
import org.springframework.integration.annotation.Gateway;
6971
import org.springframework.integration.annotation.GatewayHeader;
7072
import org.springframework.integration.annotation.InboundChannelAdapter;
@@ -94,6 +96,7 @@
9496
import org.springframework.integration.core.MessagingTemplate;
9597
import org.springframework.integration.core.Pausable;
9698
import org.springframework.integration.endpoint.AbstractEndpoint;
99+
import org.springframework.integration.endpoint.EventDrivenConsumer;
97100
import org.springframework.integration.endpoint.MethodInvokingMessageSource;
98101
import org.springframework.integration.endpoint.PollingConsumer;
99102
import org.springframework.integration.expression.SpelPropertyAccessorRegistrar;
@@ -149,6 +152,9 @@ public class EnableIntegrationTests {
149152
@Autowired
150153
private ApplicationContext context;
151154

155+
@Autowired
156+
private ContextConfiguration2 contextConfiguration2;
157+
152158
@Autowired
153159
private PollableChannel input;
154160

@@ -284,6 +290,10 @@ public class EnableIntegrationTests {
284290
@Autowired
285291
private PublisherAnnotationBeanPostProcessor publisherAnnotationBeanPostProcessor;
286292

293+
@Autowired
294+
@Qualifier("controlBusEndpoint")
295+
private EventDrivenConsumer controlBusEndpoint;
296+
287297
@Test
288298
public void testAnnotatedServiceActivator() throws Exception {
289299
this.serviceActivatorEndpoint.start();
@@ -427,6 +437,12 @@ public void testAnnotatedServiceActivator() throws Exception {
427437
assertThat(beansOfType.keySet()
428438
.contains("enableIntegrationTests.ContextConfiguration2.controlBus.serviceActivator.handler"))
429439
.isFalse();
440+
441+
assertThat(this.controlBusEndpoint.getBeanName())
442+
.isEqualTo(this.contextConfiguration2.controlBusEndpoint.getBeanName());
443+
444+
assertThat(this.controlBusEndpoint.getHandler())
445+
.isSameAs(this.contextConfiguration2.controlBusEndpoint.getHandler());
430446
}
431447

432448
@Test
@@ -1065,13 +1081,19 @@ public MessageHandler sendAsyncHandler() {
10651081

10661082
@Bean
10671083
@ServiceActivator(inputChannel = "controlBusChannel")
1084+
@EndpointId("controlBusEndpoint")
10681085
@Role("bar")
10691086
public ExpressionControlBusFactoryBean controlBus() {
10701087
return new ExpressionControlBusFactoryBean();
10711088
}
10721089

1090+
@Autowired
1091+
@Qualifier("controlBusEndpoint")
1092+
@Lazy
1093+
private EventDrivenConsumer controlBusEndpoint;
1094+
10731095
@Bean
1074-
public Pausable pausable() {
1096+
public Pausable pausable(@Qualifier("controlBusChannel") @Lazy MessageChannel controlBusChannel) {
10751097
return new Pausable() {
10761098

10771099
private volatile boolean running;

src/reference/asciidoc/configuration.adoc

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -315,8 +315,7 @@ public class ThingService {
315315
====
316316

317317
NOTE: The value of the annotation can also be a SpEL expression (for example, `someHeader.toUpperCase()`), which is useful when you wish to manipulate the header value before injecting it.
318-
It also provides an optional `required` property, which specifies whether the attribute value must be available within
319-
the headers.
318+
It also provides an optional `required` property, which specifies whether the attribute value must be available within the headers.
320319
The default value for the `required` property is `true`.
321320

322321
For several of these annotations, when a message-handling method returns a non-null value, the endpoint tries to send a reply.
@@ -345,8 +344,9 @@ public class ThingService {
345344

346345
The processing of these annotations creates the same beans as the corresponding XML components -- `AbstractEndpoint` instances and `MessageHandler` instances (or `MessageSource` instances for the inbound channel adapter).
347346
See <<annotations_on_beans>>.
348-
The bean names are generated from the following pattern: `[componentName].[methodName].[decapitalizedAnnotationClassShortName]`
349-
(for example, for the preceding example the bean name is `thingService.otherThing.serviceActivator`) for the `AbstractEndpoint` and the same name with an additional `.handler` (`.source`) suffix for the `MessageHandler` (`MessageSource`) bean.
347+
The bean names are generated from the following pattern: `[componentName].[methodName].[decapitalizedAnnotationClassShortName]`.
348+
In the preceding example the bean name is `thingService.otherThing.serviceActivator` for the `AbstractEndpoint` and the same name with an additional `.handler` (`.source`) suffix for the `MessageHandler` (`MessageSource`) bean.
349+
Such a name can be customized using an `@EndpointId` annotation alongside with these messaging annotations.
350350
The `MessageHandler` instances (`MessageSource` instances) are also eligible to be tracked by <<./message-history.adoc#message-history,the message history>>.
351351

352352
Starting with version 4.0, all messaging annotations provide `SmartLifecycle` options (`autoStartup` and `phase`) to allow endpoint lifecycle control on application context initialization.
@@ -355,6 +355,8 @@ To change the state of an endpoint (such as ` start()` or `stop()`), you can obt
355355
Alternatively, you can send a command message to the `Control Bus` (see <<./control-bus.adoc#control-bus,Control Bus>>).
356356
For these purposes, you should use the `beanName` mentioned earlier in the preceding paragraph.
357357

358+
IMPORTANT: The auto-created channels after parsing the mentioned annotations (when no specific bean is configured) and also created internally consumer endpoints can be autowired in other services, but they have to be marked with `@Lazy` annotation - they are registered in the application context context later than regular bean definitions parsing phase.
359+
358360
[[configuration-using-poller-annotation]]
359361
==== Using the `@Poller` Annotation
360362

src/reference/asciidoc/overview.adoc

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,7 @@ The chapters that follow elaborate and provide sample code as well as configurat
136136
==== Message Transformer
137137

138138
A message transformer is responsible for converting a message's content or structure and returning the modified message.
139-
Probably the most common type of transformer is one that converts the payload of the message from one format to another (such as
140-
from XML to `java.lang.String`).
139+
Probably the most common type of transformer is one that converts the payload of the message from one format to another (such as from XML to `java.lang.String`).
141140
Similarly, a transformer can add, remove, or modify the message's header values.
142141

143142
[[overview-endpoints-filter]]
@@ -213,7 +212,7 @@ Spring Integration provides a number of channel adapters, which are described in
213212
.An inbound channel adapter endpoint connects a source system to a `MessageChannel`.
214213
image::images/source-endpoint.jpg[align="center", scaledwidth=100%]
215214

216-
NOTE: Message sources can be pollable (for example, POP3) or message-driven_ (for example, IMAP Idle).
215+
NOTE: Message sources can be pollable (for example, POP3) or message-driven (for example, IMAP Idle).
217216
In the preceding diagram, this is depicted by the "`clock`" symbol and the solid arrow (poll) and the dotted arrow (message-driven).
218217

219218
.An outbound channel adapter endpoint connects a `MessageChannel` to a target system.
@@ -294,7 +293,7 @@ Consider the following example of an annotated bean:
294293
====
295294
[source, java]
296295
----
297-
@Configuratiom
296+
@Configuration
298297
public class SomeConfiguration {
299298
300299
@Bean
@@ -317,7 +316,7 @@ Starting with version 5.0.4, you can modify these names by using the `@EndpointI
317316
====
318317
[source, java]
319318
----
320-
@Configuratiom
319+
@Configuration
321320
public class SomeConfiguration {
322321
323322
@Bean("someService.handler") <1>
@@ -405,13 +404,10 @@ For example, many endpoints consist of a `MessageHandler` bean and a `ConsumerEn
405404

406405
The first time a Spring Integration namespace element is encountered, the framework automatically declares a number of beans (a task scheduler, an implicit channel creator, and others) that are used to support the runtime environment.
407406

408-
IMPORTANT: Version 4.0 introduced the `@EnableIntegration` annotation, to allow the
409-
registration of Spring Integration infrastructure beans (see the
410-
https://docs.spring.io/spring-integration/docs/latest-ga/api/org/springframework/integration/config/EnableIntegration.html[Javadoc]).
407+
IMPORTANT: Version 4.0 introduced the `@EnableIntegration` annotation, to allow the registration of Spring Integration infrastructure beans (see the https://docs.spring.io/spring-integration/docs/latest-ga/api/org/springframework/integration/config/EnableIntegration.html[Javadoc]).
411408
This annotation is required when only Java configuration is used -- for example with Spring Boot or Spring Integration Messaging Annotation support and Spring Integration Java DSL with no XML integration configuration.
412409

413-
The `@EnableIntegration` annotation is also useful when you have a parent context with no Spring Integration components
414-
and two or more child contexts that use Spring Integration.
410+
The `@EnableIntegration` annotation is also useful when you have a parent context with no Spring Integration components and two or more child contexts that use Spring Integration.
415411
It lets these common components be declared once only, in the parent context.
416412

417413
The `@EnableIntegration` annotation registers many infrastructure components with the application context.
@@ -605,8 +601,7 @@ Its main implementations are:
605601
When you use messaging annotations or the Java DSL, you need to worry about these components, because the Framework automatically produces them with appropriate annotations and `BeanPostProcessor` implementations.
606602
When building components manually, you should use the `ConsumerEndpointFactoryBean` to help determine the target `AbstractEndpoint` consumer implementation to create, based on the provided `inputChannel` property.
607603

608-
On the other hand, the `ConsumerEndpointFactoryBean` delegates to an another first class citizen in the Framework:
609-
`org.springframework.messaging.MessageHandler`.
604+
On the other hand, the `ConsumerEndpointFactoryBean` delegates to an another first class citizen in the Framework - `org.springframework.messaging.MessageHandler`.
610605
The goal of the implementation of this interface is to handle the message consumed by the endpoint from the channel.
611606
All EIP components in Spring Integration are `MessageHandler` implementations (for example, `AggregatingMessageHandler`, `MessageTransformingHandler`, `AbstractMessageSplitter`, and others).
612607
The target protocol outbound adapters (`FileWritingMessageHandler`, `HttpRequestExecutingMessageHandler`, `AbstractMqttMessageHandler`, and others) are also `MessageHandler` implementations.

0 commit comments

Comments
 (0)