You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Resolve listener payload type during container setup (#1548)
Resolve payload types during container initialization by analyzing
@SqsListener method signatures, removing the need for type headers by default.
With this change, the resolved payload type is available earlier in the flow,
and components such as MessageInterceptors, ErrorHandlers, and
AcknowledgementResultCallback receive the deserialized payload even when no
type header is present.
This removes coupling to producer-specific type names (which often differ across
services) and reduces risk from trusting type headers.
Supported patterns:
- Simple types: MyEvent
- Generic types: List<MyEvent>, Message<MyEvent>, List<Message<MyEvent>>
- Explicit @payload annotations
The SqsTemplate JavaType header is deprecated and ignored by default, with
documented options to restore the previous behavior. Polymorphic payloads
(interfaces, Object, @SqsHandler) require configuring a custom
payloadTypeMapper in SqsMessagingMessageConverter for type resolution.
Fixes#1546
The `isDefault = true` parameter designates a method as the fallback handler for messages that don't match any other handler's parameter type.
662
662
663
+
To determine which handler method to invoke, the framework needs to know the payload type before deserialization.
664
+
A custom `PayloadTypeMapper` should be configured to map incoming messages to their concrete types.
665
+
See <<Custom Payload Type Mapping>> for an example.
666
+
667
+
[NOTE]
668
+
====
669
+
Since 4.0.0, the default type header sent by `SqsTemplate` is deprecated and is no longer used to deserialize the payload.
670
+
A custom mapper is necessary to disambiguate between different payload types in multi-handler listeners.
671
+
Alternatively, automatic inference can be disabled to restore header-based type resolution.
672
+
See <<Automatic Payload Type Inference>> for more information.
673
+
====
674
+
663
675
===== SNS Messages
664
676
665
677
Since 3.1.1, when receiving SNS messages through the `@SqsListener`, the message includes all attributes of the `SnsNotification`. To only receive need the `Message` part of the payload, you can utilize the `@SnsNotificationMessage` annotation.
@@ -1609,16 +1621,55 @@ NOTE: When using Spring Boot's auto-configuration, if there's a single `ObjectMa
1609
1621
This includes the one provided by Spring Boot's auto-configuration itself.
1610
1622
For configuring a different `ObjectMapper`, see <<Global Configuration for @SqsListeners>>.
1611
1623
1612
-
For manually created `MessageListeners`, `MessageInterceptor` and `ErrorHandler` components, or more fine-grained conversion such as using `interfaces` or `inheritance` in listener methods, type mapping is required for payload deserialization.
1624
+
==== Automatic Payload Type Inference
1625
+
1626
+
Since 4.0.0, by default, the framework automatically infers the payload type from the `@SqsListener` method signature at the `MessageSource` level.
1627
+
This allows payloads to be deserialized early in the message processing flow without requiring type information in message headers.
1628
+
1629
+
This enables accessing the deserialized payload in components such as `MessageInterceptor`, `ErrorHandler`, and `AcknowledgementResultCallback` without type headers.
1630
+
1631
+
The inference supports simple types, generic types like `List<MyEvent>`, `Message<MyEvent>`, and `List<Message<MyEvent>>`.
1632
+
Parameters annotated with `@Payload` are explicitly recognized as the payload parameter.
1633
+
1634
+
For polymorphic types (interfaces, `Object`, or `@SqsHandler` methods), a custom mapper is required.
1635
+
See <<Custom Payload Type Mapping>>.
1636
+
1637
+
[NOTE]
1638
+
====
1639
+
The `JavaType` header automatically set by `SqsTemplate` is deprecated since 4.0.0 and will be removed in a future version.
1640
+
When automatic payload type inference is enabled, the `JavaType` header is ignored by default.
1641
+
For backward compatibility, `SqsTemplate` still sends this header, allowing applications to roll back if needed.
1642
+
====
1643
+
1644
+
==== Customizing Type Resolution
1645
+
1646
+
Type resolution can be customized at two levels:
1613
1647
1614
-
By default, the framework looks for a `MessageHeader` named `Sqs_MA_JavaType` containing the fully qualified class name (`FQCN`) for which the payload should be deserialized to.
1615
-
If such header is found, the message is automatically deserialized to the provided class.
1648
+
*Per-converter:* Configure `setPayloadTypeMapper` or `setPayloadTypeHeader` on a `MessagingMessageConverter`.
1649
+
Any custom type mapper takes precedence over automatic inference for that converter.
1650
+
Note that, by default, all containers share the same SqsMessagingMessageConverter instance.
1616
1651
1617
-
Further configuration can be achieved by providing a configured `MessagingMessageConverter` instance in the `SqsContainerOptions`.
1652
+
*Framework-wide:* Provide a custom `MethodPayloadTypeInferrer` implementation via a `SqsListenerConfigurer`.
1653
+
See <<Global Configuration for @SqsListeners>>.
1618
1654
1619
-
NOTE: If type mapping is setup or type information is added to the headers, payloads are deserialized right after the message is polled.
1620
-
Otherwise, for `@SqsListener` annotated methods, payloads are deserialized right before the message is sent to the listener.
1621
-
For providing custom `MessageConverter` instances to be used by `@SqsListener` methods, see <<Global Configuration for @SqsListeners>>
1655
+
==== Disabling Automatic Inference
1656
+
1657
+
*Per-converter:* To restore header-based type mapping for specific converters, call `setPayloadTypeHeader` on the converter:
Copy file name to clipboardExpand all lines: spring-cloud-aws-sqs/src/main/java/io/awspring/cloud/sqs/annotation/AbstractListenerAnnotationBeanPostProcessor.java
+4Lines changed: 4 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -99,6 +99,8 @@ public abstract class AbstractListenerAnnotationBeanPostProcessor<A extends Anno
0 commit comments