(window.webpackJsonp=window.webpackJsonp||[]).push([[116],{545:function(e,t,n){"use strict";n.r(t);var a=n(56),r=Object(a.a)({},(function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[n("h1",{attrs:{id:"change-history"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#change-history"}},[e._v("#")]),e._v(" Change History")]),e._v(" "),n("h2",{attrs:{id:"change-history-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#change-history-2"}},[e._v("#")]),e._v(" Change History")]),e._v(" "),n("h3",{attrs:{id:"changes-between-5-3-and-5-4"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#changes-between-5-3-and-5-4"}},[e._v("#")]),e._v(" Changes between 5.3 and 5.4")]),e._v(" "),n("h3",{attrs:{id:"new-components"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#new-components"}},[e._v("#")]),e._v(" New Components")]),e._v(" "),n("h4",{attrs:{id:"channel-adapters-for-apache-kafka"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#channel-adapters-for-apache-kafka"}},[e._v("#")]),e._v(" Channel Adapters for Apache Kafka")]),e._v(" "),n("p",[e._v("The standalone "),n("a",{attrs:{href:"https://projects.spring.io/spring-integration-kafka/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Integration for Apache Kafka"),n("OutboundLink")],1),e._v(" project has been merged as a "),n("code",[e._v("spring-integration-kafka")]),e._v(" module to this project.")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("KafkaProducerMessageHandler")]),e._v(" "),n("code",[e._v("sendTimeoutExpression")]),e._v(" default has changed.")]),e._v(" "),n("p",[e._v("You can now access the "),n("code",[e._v("Future")]),e._v(" for underlying "),n("code",[e._v("send()")]),e._v(" operations.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/kafka.html#kafka"}},[e._v("Spring for Apache Kafka Support")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"r2dbc-channel-adapters"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#r2dbc-channel-adapters"}},[e._v("#")]),e._v(" R2DBC Channel Adapters")]),e._v(" "),n("p",[e._v("The Channel Adapters for R2DBC database interaction have been introduced.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/r2dbc.html#r2dbc"}},[e._v("R2DBC Support")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"redis-stream-support"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#redis-stream-support"}},[e._v("#")]),e._v(" Redis Stream Support")]),e._v(" "),n("p",[e._v("The Channel Adapters for Redis Stream support have been introduced.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/redis.html#redis-stream-outbound"}},[e._v("Redis Stream Outbound Channel Adapter")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"renewable-lock-registry"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#renewable-lock-registry"}},[e._v("#")]),e._v(" Renewable Lock Registry")]),e._v(" "),n("p",[e._v("A Renewable lock registry has been introduced to allow renew lease of a distributed lock.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/jdbc.html#jdbc-lock-registry"}},[e._v("JDBC implementation")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"zeromq-support"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#zeromq-support"}},[e._v("#")]),e._v(" ZeroMQ Support")]),e._v(" "),n("p",[n("code",[e._v("ZeroMqChannel")]),e._v(", "),n("code",[e._v("ZeroMqMessageHandler")]),e._v(" and "),n("code",[e._v("ZeroMqMessageProducer")]),e._v(" have been introduced.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/zeromq.html#zeromq"}},[e._v("ZeroMQ Support")]),e._v(" for more information.")],1),e._v(" "),n("h3",{attrs:{id:"general-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#general-changes"}},[e._v("#")]),e._v(" General Changes")]),e._v(" "),n("p",[e._v("The one-way messaging gateway (the "),n("code",[e._v("void")]),e._v(" method return type) now sets a "),n("code",[e._v("nullChannel")]),e._v(" explicitly into the "),n("code",[e._v("replyChannel")]),e._v(" header to ignore any possible downstream replies.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/gateway.html#gateway-default-reply-channel"}},[e._v("Setting the Default Reply Channel")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("Also the gateway method invokers ("),n("code",[e._v("GatewayProxyFactoryBean.MethodInvocationGateway")]),e._v(") are now supplied with the managed bean name as a combination of gateway proxy bean name plus method signature.\nFor example: "),n("code",[e._v("sampleGateway#echo(String)")]),e._v(".\nThis effects message history and metrics exposed for the gateway method calls and also give fine-grained logs during start and close of application context.")]),e._v(" "),n("p",[e._v("The aggregator (and resequencer) can now expire orphaned groups (groups in a persistent store where no new messages arrive after an application restart).\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/aggregator.html#aggregator-expiring-groups"}},[e._v("Aggregator Expiring Groups")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("The legacy metrics that were replaced by Micrometer meters have been removed.")]),e._v(" "),n("p",[e._v("The "),n("RouterLink",{attrs:{to:"/en/spring-integration/barrier.html#barrier"}},[e._v("Thread Barrier")]),e._v(" has now two separate timeout options: "),n("code",[e._v("requestTimeout")]),e._v(" and "),n("code",[e._v("triggerTimeout")]),e._v(".")],1),e._v(" "),n("h3",{attrs:{id:"tcp-udp-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#tcp-udp-changes"}},[e._v("#")]),e._v(" TCP/UDP Changes")]),e._v(" "),n("p",[e._v("Connection factories now support multiple sending components ("),n("code",[e._v("TcpSender")]),e._v("); they remain limited to one receiving component ("),n("code",[e._v("TcpListener")]),e._v(").\nThis allows, for example, an inbound gateway and outbound channel adapter to share the same factory, supporting both request/reply and arbitrary messaging from the server to the client.\nShared factories should not be used with outbound gateways, unless single-use connections or the "),n("code",[e._v("ThreadAffinityClientConnectionFactory")]),e._v(" are being used.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ip.html#ip-collaborating-adapters"}},[e._v("Collaborating Channel Adapters")]),e._v(" and "),n("RouterLink",{attrs:{to:"/en/spring-integration/ip.html#tcp-gateways"}},[e._v("TCP Gateways")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("The UDP channel adapters can now be configured with a "),n("code",[e._v("SocketCustomizer")]),e._v(" which allows the setting of socket properties that are not directly supported by the adapters.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ip.html#udp-adapters"}},[e._v("UDP Adapters")]),e._v(" for more information.")],1),e._v(" "),n("h3",{attrs:{id:"rmi-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#rmi-changes"}},[e._v("#")]),e._v(" RMI Changes")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("spring-integration-rmi")]),e._v(" module is deprecated with no replacement and is going to be removed in the next major version.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/rmi.html#rmi"}},[e._v("RMI Support")]),e._v(" for more information.")],1),e._v(" "),n("h3",{attrs:{id:"amqp-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#amqp-changes"}},[e._v("#")]),e._v(" AMQP Changes")]),e._v(" "),n("p",[e._v("The outbound endpoints now have a new mechanism for handling publisher confirms and returns.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/amqp.html#alternative-confirms-returns"}},[e._v("Alternative Mechanism for Publisher Confirms and Returns")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("A new "),n("code",[e._v("BatchMode.EXTRACT_PAYLOAD_WITH_HEADERS")]),e._v(" is supported by the "),n("code",[e._v("AmqpInboundChannelAdapter")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/amqp.html#amqp-inbound-channel-adapter"}},[e._v("Inbound Channel Adapter")]),e._v(" for more information.")],1),e._v(" "),n("h3",{attrs:{id:"mail-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#mail-changes"}},[e._v("#")]),e._v(" Mail Changes")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("AbstractMailReceiver")]),e._v(" can now produce the "),n("code",[e._v("MimeMessage")]),e._v(" as-is without eager fetching its content.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/mail.html#mail-inbound"}},[e._v("Mail-receiving Channel Adapter")]),e._v(" for more information.")],1),e._v(" "),n("h3",{attrs:{id:"changes-between-5-2-and-5-3"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#changes-between-5-2-and-5-3"}},[e._v("#")]),e._v(" Changes between 5.2 and 5.3")]),e._v(" "),n("h3",{attrs:{id:"new-components-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#new-components-2"}},[e._v("#")]),e._v(" New Components")]),e._v(" "),n("h4",{attrs:{id:"integration-pattern"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#integration-pattern"}},[e._v("#")]),e._v(" Integration Pattern")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("IntegrationPattern")]),e._v(" abstraction has been introduced to indicate which enterprise integration pattern (an "),n("code",[e._v("IntegrationPatternType")]),e._v(") and category a Spring Integration component belongs to.\nSee its JavaDocs and "),n("RouterLink",{attrs:{to:"/en/spring-integration/graph.html#integration-graph"}},[e._v("Integration Graph")]),e._v(" for more information about this abstraction and its use-cases.")],1),e._v(" "),n("h4",{attrs:{id:"reactivemessagehandler"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#reactivemessagehandler"}},[e._v("#")]),e._v(" "),n("code",[e._v("ReactiveMessageHandler")])]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("ReactiveMessageHandler")]),e._v(" is now natively supported in the framework.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/reactive-streams.html#reactive-message-handler"}},[e._v("ReactiveMessageHandler")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"reactivemessagesourceproducer"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#reactivemessagesourceproducer"}},[e._v("#")]),e._v(" "),n("code",[e._v("ReactiveMessageSourceProducer")])]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("ReactiveMessageSourceProducer")]),e._v(" is a reactive implementation of the "),n("code",[e._v("MessageProducerSupport")]),e._v(" to wrap a provided "),n("code",[e._v("MessageSource")]),e._v(" into a "),n("code",[e._v("Flux")]),e._v(" for on demand "),n("code",[e._v("receive()")]),e._v(" calls.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/reactive-streams.html#reactive-streams"}},[e._v("Reactive Streams Support")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"java-dsl-extensions"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#java-dsl-extensions"}},[e._v("#")]),e._v(" Java DSL Extensions")]),e._v(" "),n("p",[e._v("A new "),n("code",[e._v("IntegrationFlowExtension")]),e._v(" API has been introduced to allow extension of the existing Java DSL with custom or composed EIP-operators.\nThis also can be used to introduce customizers for any out-of-the-box "),n("code",[e._v("IntegrationComponentSpec")]),e._v(" extensions.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/dsl.html#java-dsl-extensions"}},[e._v("DSL Extensions")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"kotlin-dsl"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#kotlin-dsl"}},[e._v("#")]),e._v(" Kotlin DSL")]),e._v(" "),n("p",[e._v("The Kotlin DSL for integration flow configurations has been introduced.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/kotlin-dsl.html#kotlin-dsl"}},[e._v("Kotlin DSL Chapter")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"reactiverequesthandleradvice"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#reactiverequesthandleradvice"}},[e._v("#")]),e._v(" ReactiveRequestHandlerAdvice")]),e._v(" "),n("p",[e._v("A "),n("code",[e._v("ReactiveRequestHandlerAdvice")]),e._v(" is provided to customize "),n("code",[e._v("Mono")]),e._v(" replies from message handlers.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/handler-advice.html#reactive-advice"}},[e._v("Reactive Advice")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"handlemessageadviceadapter"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#handlemessageadviceadapter"}},[e._v("#")]),e._v(" HandleMessageAdviceAdapter")]),e._v(" "),n("p",[e._v("A "),n("code",[e._v("HandleMessageAdviceAdapter")]),e._v(" is provided to wrap any "),n("code",[e._v("MethodInterceptor")]),e._v(" for applying on the "),n("code",[e._v("MessageHandler.handleMessage()")]),e._v(" instead of a default "),n("code",[e._v("AbstractReplyProducingMessageHandler.RequestHandler.handleRequestMessage()")]),e._v(" behavior.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/handler-advice.html#handle-message-advice"}},[e._v("Handling Message Advice")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"mongodb-reactive-channel-adapters"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#mongodb-reactive-channel-adapters"}},[e._v("#")]),e._v(" MongoDB Reactive Channel Adapters")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("spring-integration-mongodb")]),e._v(" module now provides channel adapter implementations for the Reactive MongoDb driver support in Spring Data.\nAlso, a reactive implementation for MongoDb change stream support is present with the "),n("code",[e._v("MongoDbChangeStreamMessageProducer")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/mongodb.html#mongodb"}},[e._v("MongoDB Support")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"receivemessageadvice"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#receivemessageadvice"}},[e._v("#")]),e._v(" ReceiveMessageAdvice")]),e._v(" "),n("p",[e._v("A special "),n("code",[e._v("ReceiveMessageAdvice")]),e._v(" has been introduced to proxy exactly "),n("code",[e._v("MessageSource.receive()")]),e._v(" or "),n("code",[e._v("PollableChannel.receive()")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/polling-consumer.html#smart-polling"}},[e._v("Smart Polling")]),e._v(" for more information.")],1),e._v(" "),n("h3",{attrs:{id:"general-changes-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#general-changes-2"}},[e._v("#")]),e._v(" General Changes")]),e._v(" "),n("p",[e._v("The gateway proxy now doesn’t proxy "),n("code",[e._v("default")]),e._v(" methods by default.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/gateway.html#gateway-calling-default-methods"}},[e._v("Invoking "),n("code",[e._v("default")]),e._v(" Methods")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("Internal components (such as "),n("code",[e._v("_org.springframework.integration.errorLogger")]),e._v(") now have a shortened name when they are represented in the integration graph.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/graph.html#integration-graph"}},[e._v("Integration Graph")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("In the aggregator, when the "),n("code",[e._v("MessageGroupProcessor")]),e._v(" returns a "),n("code",[e._v("Message")]),e._v(", the "),n("code",[e._v("MessageBuilder.popSequenceDetails()")]),e._v(" is performed on the output message if the "),n("code",[e._v("sequenceDetails")]),e._v(" matches the header in the first message of the group.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/aggregator.html#aggregator-api"}},[e._v("Aggregator Programming Model")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("A new "),n("code",[e._v("publishSubscribeChannel()")]),e._v(" operator, based on the "),n("code",[e._v("BroadcastCapableChannel")]),e._v(" and "),n("code",[e._v("BroadcastPublishSubscribeSpec")]),e._v(", was added into Java DSL.\nThis fluent API has its advantage when we configure sub-flows as pub-sub subscribers for broker-backed channels like "),n("code",[e._v("SubscribableJmsChannel")]),e._v(", "),n("code",[e._v("SubscribableRedisChannel")]),e._v(" etc.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/dsl.html#java-dsl-subflows"}},[e._v("Sub-flows support")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("Transactional support in Spring Integration now also includes options to configure a "),n("code",[e._v("ReactiveTransactionManager")]),e._v(" if a "),n("code",[e._v("MessageSource")]),e._v(" or "),n("code",[e._v("MessageHandler")]),e._v(" implementation produces a reactive type for payload to send.\nSee "),n("code",[e._v("TransactionInterceptorBuilder")]),e._v(" for more information.\nSee also "),n("RouterLink",{attrs:{to:"/en/spring-integration/transactions.html#reactive-transactions"}},[e._v("Reactive Transactions")]),e._v(".")],1),e._v(" "),n("p",[e._v("A new "),n("code",[e._v("intercept()")]),e._v(" operator to register "),n("code",[e._v("ChannelInterceptor")]),e._v(" instances without creating explicit channels was added into Java DSL.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/dsl.html#java-dsl-intercept"}},[e._v("Operator intercept()")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("The "),n("code",[e._v("MessageStoreSelector")]),e._v(" has a new mechanism to compare an old and new value.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/handler-advice.html#idempotent-receiver"}},[e._v("Idempotent Receiver Enterprise Integration Pattern")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("The "),n("code",[e._v("MessageProducerSupport")]),e._v(" base class now has a "),n("code",[e._v("subscribeToPublisher(Publisher>)")]),e._v(" API to allow implementation of message-driven producer endpoints which emit messages via reactive "),n("code",[e._v("Publisher")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/reactive-streams.html#reactive-streams"}},[e._v("Reactive Streams Support")]),e._v(" for more information.")],1),e._v(" "),n("h3",{attrs:{id:"amqp-changes-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#amqp-changes-2"}},[e._v("#")]),e._v(" AMQP Changes")]),e._v(" "),n("p",[e._v("The outbound channel adapter has a new property "),n("code",[e._v("multiSend")]),e._v(" allowing multiple messages to be sent within the scope of one "),n("code",[e._v("RabbitTemplate")]),e._v(" invocation.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/amqp.html#amqp-outbound-channel-adapter"}},[e._v("AMQP Outbound Channel Adapter")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("The inbound channel adapter now supports a listener container with the "),n("code",[e._v("consumerBatchEnabled")]),e._v(" property set to "),n("code",[e._v("true")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/amqp.html#amqp-inbound-channel-adapter"}},[e._v("AMQP Inbound Channel Adapter")])],1),e._v(" "),n("h3",{attrs:{id:"http-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#http-changes"}},[e._v("#")]),e._v(" HTTP Changes")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("encodeUri")]),e._v(" property on the "),n("code",[e._v("AbstractHttpRequestExecutingMessageHandler")]),e._v(" has been deprecated in favor of newly introduced "),n("code",[e._v("encodingMode")]),e._v(".\nSee "),n("code",[e._v("DefaultUriBuilderFactory.EncodingMode")]),e._v(" JavaDocs and "),n("RouterLink",{attrs:{to:"/en/spring-integration/http.html#http-uri-encoding"}},[e._v("Controlling URI Encoding")]),e._v(" for more information.\nThis also affects "),n("code",[e._v("WebFluxRequestExecutingMessageHandler")]),e._v(", respective Java DSL and XML configuration.\nThe same option is added into an "),n("code",[e._v("AbstractWebServiceOutboundGateway")]),e._v(".")],1),e._v(" "),n("h3",{attrs:{id:"web-services-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#web-services-changes"}},[e._v("#")]),e._v(" Web Services Changes")]),e._v(" "),n("p",[e._v("Java DSL support has been added for Web Service components.\nThe "),n("code",[e._v("encodeUri")]),e._v(" property on the "),n("code",[e._v("AbstractWebServiceOutboundGateway")]),e._v(" has been deprecated in favor of newly introduced "),n("code",[e._v("encodingMode")]),e._v(" - similar to HTTP changes above.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ws.html#ws"}},[e._v("Web Services Support")]),e._v(" for more information.")],1),e._v(" "),n("h3",{attrs:{id:"tcp-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#tcp-changes"}},[e._v("#")]),e._v(" TCP Changes")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("FailoverClientConnectionFactory")]),e._v(" no longer fails back, by default, until the current connection fails.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ip.html#failover-cf"}},[e._v("TCP Failover Client Connection Factory")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("The "),n("code",[e._v("TcpOutboundGateway")]),e._v(" now supports asynchronous request/reply.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ip.html#tcp-gateways"}},[e._v("TCP Gateways")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("You can now configure client connections to perform some arbitrary test on new connections.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ip.html#testing-connections"}},[e._v("Testing Connections")]),e._v(" for more information.")],1),e._v(" "),n("h3",{attrs:{id:"rsocket-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#rsocket-changes"}},[e._v("#")]),e._v(" RSocket Changes")]),e._v(" "),n("p",[e._v("A "),n("code",[e._v("decodeFluxAsUnit")]),e._v(" option has been added to the "),n("code",[e._v("RSocketInboundGateway")]),e._v(" with the meaning to decode incoming "),n("code",[e._v("Flux")]),e._v(" as a single unit or apply decoding for each event in it.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/rsocket.html#rsocket-inbound"}},[e._v("RSocket Inbound Gateway")]),e._v(" for more information.")],1),e._v(" "),n("h3",{attrs:{id:"zookeeper-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#zookeeper-changes"}},[e._v("#")]),e._v(" Zookeeper Changes")]),e._v(" "),n("p",[e._v("A "),n("code",[e._v("LeaderInitiatorFactoryBean")]),e._v(" (as well as its XML "),n("code",[e._v("")]),e._v(") exposes a "),n("code",[e._v("candidate")]),e._v(" option for more control over a "),n("code",[e._v("Candidate")]),e._v(" configuration.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/zookeeper.html#zk-leadership"}},[e._v("Leadership event handling")]),e._v(" for more information.")],1),e._v(" "),n("h3",{attrs:{id:"mqtt-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#mqtt-changes"}},[e._v("#")]),e._v(" MQTT Changes")]),e._v(" "),n("p",[e._v("The inbound channel adapter can now be configured to provide user control over when a message is acknowledged as being delivered.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/mqtt.html#mqtt-ack-mode"}},[e._v("Manual Acks")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("The outbound adapter now publishes a "),n("code",[e._v("MqttConnectionFailedEvent")]),e._v(" when a connection can’t be created, or is lost.\nPreviously, only the inbound adapter did so.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/mqtt.html#mqtt-events"}},[e._v("MQTT Events")]),e._v(".")],1),e._v(" "),n("h3",{attrs:{id:"ftp-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#ftp-changes"}},[e._v("#")]),e._v(" FTP Changes")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("FileTransferringMessageHandler")]),e._v(" (for FTP and SFTP, for example) in addition to "),n("code",[e._v("File")]),e._v(", "),n("code",[e._v("byte[]")]),e._v(", "),n("code",[e._v("String")]),e._v(" and "),n("code",[e._v("InputStream")]),e._v(" now also supports an "),n("code",[e._v("org.springframework.core.io.Resource")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/sftp.html#sftp"}},[e._v("SFTP Support")]),e._v(" and "),n("RouterLink",{attrs:{to:"/en/spring-integration/ftp.html#ftp"}},[e._v("FTP Support")]),e._v(" for more information.")],1),e._v(" "),n("h3",{attrs:{id:"file-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#file-changes"}},[e._v("#")]),e._v(" File Changes")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("FileSplitter")]),e._v(" doesn’t require a Jackson processor (or similar) dependency any more for the "),n("code",[e._v("markersJson")]),e._v(" mode.\nIt uses a "),n("code",[e._v("SimpleJsonSerializer")]),e._v(" for a straightforward string representation of the "),n("code",[e._v("FileSplitter.FileMarker")]),e._v(" instances.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/file.html#file-splitter"}},[e._v("FileSplitter")]),e._v(" for more information.")],1),e._v(" "),n("h3",{attrs:{id:"changes-between-5-1-and-5-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#changes-between-5-1-and-5-2"}},[e._v("#")]),e._v(" Changes between 5.1 and 5.2")]),e._v(" "),n("h3",{attrs:{id:"package-and-class-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#package-and-class-changes"}},[e._v("#")]),e._v(" Package and Class Changes")]),e._v(" "),n("p",[n("code",[e._v("Pausable")]),e._v(" has been moved from "),n("code",[e._v("o.s.i.endpoint")]),e._v(" to "),n("code",[e._v("o.s.i.core")]),e._v(".")]),e._v(" "),n("h3",{attrs:{id:"behavior-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#behavior-changes"}},[e._v("#")]),e._v(" Behavior Changes")]),e._v(" "),n("p",[e._v("See the "),n("a",{attrs:{href:"https://github.com/spring-projects/spring-integration/wiki/Spring-Integration-5.1-to-5.2-Migration-Guide",target:"_blank",rel:"noopener noreferrer"}},[e._v("Migration Guide"),n("OutboundLink")],1),e._v(" about behavior changes in this version.")]),e._v(" "),n("h3",{attrs:{id:"new-components-3"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#new-components-3"}},[e._v("#")]),e._v(" New Components")]),e._v(" "),n("h4",{attrs:{id:"rsocket-support"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#rsocket-support"}},[e._v("#")]),e._v(" RSocket Support")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("spring-integration-rsocket")]),e._v(" module is now available with channel adapter implementations for RSocket protocol support.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/rsocket.html#rsocket"}},[e._v("RSocket Support")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"rate-limit-advice-support"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#rate-limit-advice-support"}},[e._v("#")]),e._v(" Rate Limit Advice Support")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("RateLimiterRequestHandlerAdvice")]),e._v(" is now available for limiting requests rate on handlers.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/handler-advice.html#rate-limiter-advice"}},[e._v("Rate Limiter Advice")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"caching-advice-support"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#caching-advice-support"}},[e._v("#")]),e._v(" Caching Advice Support")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("CacheRequestHandlerAdvice")]),e._v(" is now available for caching request results on handlers.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/handler-advice.html#cache-advice"}},[e._v("Caching Advice")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"kotlin-scripts-support"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#kotlin-scripts-support"}},[e._v("#")]),e._v(" Kotlin Scripts Support")]),e._v(" "),n("p",[e._v("The JSR223 scripting module now includes a support for Kotlin scripts.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/scripting.html#scripting"}},[e._v("Scripting Support")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"flux-aggregator-support"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#flux-aggregator-support"}},[e._v("#")]),e._v(" Flux Aggregator Support")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("FluxAggregatorMessageHandler")]),e._v(" is now available for grouping and windowing messages logic based on the Project Reactor "),n("code",[e._v("Flux")]),e._v(" operators.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/aggregator.html#flux-aggregator"}},[e._v("Flux Aggregator")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"ftp-sftp-event-publisher"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#ftp-sftp-event-publisher"}},[e._v("#")]),e._v(" FTP/SFTP Event Publisher")]),e._v(" "),n("p",[e._v("The FTP and SFTP modules now provide an event listener for certain Apache Mina FTP/SFTP server events.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ftp.html#ftp-server-events"}},[e._v("Apache Mina FTP Server Events")]),e._v(" and "),n("RouterLink",{attrs:{to:"/en/spring-integration/sftp.html#sftp-server-events"}},[e._v("Apache Mina SFTP Server Events")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"avro-transformers"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#avro-transformers"}},[e._v("#")]),e._v(" Avro Transformers")]),e._v(" "),n("p",[e._v("Simple Apache Avro transformers are now provided.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/transformers.html#avro-transformers"}},[e._v("Avro Transformers")]),e._v(" for more information.")],1),e._v(" "),n("h3",{attrs:{id:"general-changes-3"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#general-changes-3"}},[e._v("#")]),e._v(" General Changes")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("JsonToObjectTransformer")]),e._v(" now supports generics for the target object to deserialize into.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/transformer.html#json-transformers"}},[e._v("JSON Transformers")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("The "),n("code",[e._v("splitter")]),e._v(" now supports a "),n("code",[e._v("discardChannel")]),e._v(" configuration option.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/splitter.html#splitter"}},[e._v("Splitter")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("The Control Bus can now handle "),n("code",[e._v("Pausable")]),e._v(" (extension of "),n("code",[e._v("Lifecycle")]),e._v(") operations.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/control-bus.html#control-bus"}},[e._v("Control Bus")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("The "),n("code",[e._v("Function>")]),e._v(" strategy has been introduced for the aggregator component to merge and compute headers for output messages.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/aggregator.html#aggregator-api"}},[e._v("Aggregator Programming Model")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("All the "),n("code",[e._v("MessageHandlingException")]),e._v(" s thrown in the framework, includes now a bean resource and source for back tracking a configuration part in case no end-user code involved.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/error-handling.html#error-handling"}},[e._v("Error Handling")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("For better end-user experience, Java DSL now provides a configurer variant for starting flow with a gateway interface.\nSee "),n("code",[e._v("IntegrationFlows.from(Class serviceInterface, Consumer endpointConfigurer)")]),e._v(" JavaDocs for more information.\nAlso a "),n("code",[e._v("MethodArgsHolder")]),e._v(" is now a root object for evaluation context for all the expressions in the "),n("code",[e._v("GatewayProxyFactoryBean")]),e._v(".\nThe "),n("code",[e._v("#args")]),e._v(" and "),n("code",[e._v("#method")]),e._v(" evaluation context variables are now deprecated.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/gateway.html#gateway"}},[e._v("Messaging Gateways")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"amqp-changes-3"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#amqp-changes-3"}},[e._v("#")]),e._v(" AMQP Changes")]),e._v(" "),n("p",[e._v('The outbound endpoints can now be configured to synthesize a "nack" if no publisher confirm is received within a timeout.\nSee '),n("RouterLink",{attrs:{to:"/en/spring-integration/amqp.html#amqp-outbound-endpoints"}},[e._v("Outbound Channel Adapter")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("The inbound channel adapter can now receive batched messages as a "),n("code",[e._v("List")]),e._v(" payload instead of receiving a discrete message for each batch fragment.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/amqp.html#amqp-debatching"}},[e._v("Batched Messages")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("The outbound channel adapter can now be configured to block the calling thread until a publisher confirm (acknowledgment) is received.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/amqp.html#amqp-outbound-channel-adapter"}},[e._v("Outbound Channel Adapter")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"file-changes-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#file-changes-2"}},[e._v("#")]),e._v(" File Changes")]),e._v(" "),n("p",[e._v("Some improvements to filtering remote files have been made.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/file.html#remote-persistent-flf"}},[e._v("Remote Persistent File List Filters")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"tcp-changes-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#tcp-changes-2"}},[e._v("#")]),e._v(" TCP Changes")]),e._v(" "),n("p",[e._v("The length header used by the "),n("code",[e._v("ByteArrayLengthHeaderSerializer")]),e._v(" can now include the length of the header in addition to the payload.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ip.html#tcp-codecs"}},[e._v("Message Demarcation (Serializers and Deserializers)")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("When using a "),n("code",[e._v("TcpNioServerConnectionFactory")]),e._v(", priority is now given to accepting new connections over reading from existing connections, but it is configurable.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ip.html#note-nio"}},[e._v("About Non-blocking I/O (NIO)")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("The outbound gateway has a new property "),n("code",[e._v("closeStreamAfterSend")]),e._v("; when used with a new connection for each request/reply it signals EOF to the server, without closing the connection.\nThis is useful for servers that use the EOF to signal end of message instead of some delimiter in the data.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ip.html#tcp-gateways"}},[e._v("TCP Gateways")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("The client connection factories now support "),n("code",[e._v("connectTimeout")]),e._v(" which causes an exception to be thrown if the connection is not established in that time.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ip.html#tcp-connection-factory"}},[e._v("TCP Connection Factories")]),e._v(" for more information.")],1),e._v(" "),n("p",[n("code",[e._v("SoftEndOfStreamException")]),e._v(" is now a "),n("code",[e._v("RuntimeException")]),e._v(" instead of extending "),n("code",[e._v("IOException")]),e._v(".")]),e._v(" "),n("h4",{attrs:{id:"mail-changes-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#mail-changes-2"}},[e._v("#")]),e._v(" Mail Changes")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("AbstractMailReceiver")]),e._v(" has now an "),n("code",[e._v("autoCloseFolder")]),e._v(" option ("),n("code",[e._v("true")]),e._v(" by default), to disable an automatic folder close after a fetch, but populate "),n("code",[e._v("IntegrationMessageHeaderAccessor.CLOSEABLE_RESOURCE")]),e._v(" header instead for downstream interaction.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/mail.html#mail-inbound"}},[e._v("Mail-receiving Channel Adapter")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"http-changes-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#http-changes-2"}},[e._v("#")]),e._v(" HTTP Changes")]),e._v(" "),n("p",[e._v("The HTTP inbound endpoint now support a request payload validation.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/http.html#http"}},[e._v("HTTP Support")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"webflux-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#webflux-changes"}},[e._v("#")]),e._v(" WebFlux Changes")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("WebFluxRequestExecutingMessageHandler")]),e._v(" now supports a "),n("code",[e._v("Publisher")]),e._v(", "),n("code",[e._v("Resource")]),e._v(" and "),n("code",[e._v("MultiValueMap")]),e._v(" as a request message "),n("code",[e._v("payload")]),e._v(".\nThe "),n("code",[e._v("WebFluxInboundEndpoint")]),e._v(" now supports a request payload validation.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/webflux.html#webflux"}},[e._v("WebFlux Support")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"mongodb-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#mongodb-changes"}},[e._v("#")]),e._v(" MongoDb Changes")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("MongoDbMessageStore")]),e._v(" can now be configured with custom converters.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/mongodb.html#mongodb"}},[e._v("MongoDB Support")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"router-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#router-changes"}},[e._v("#")]),e._v(" Router Changes")]),e._v(" "),n("p",[e._v("You can now disable falling back to the channel key as the channel bean name.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/router.html#dynamic-routers"}},[e._v("Dynamic Routers")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"ftp-sftp-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#ftp-sftp-changes"}},[e._v("#")]),e._v(" FTP/SFTP Changes")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("RotatingServerAdvice")]),e._v(" is decoupled now from the "),n("code",[e._v("RotationPolicy")]),e._v(" and its "),n("code",[e._v("StandardRotationPolicy")]),e._v(".")]),e._v(" "),n("p",[e._v("The remote file information, including host/port and directory are included now into message headers in the "),n("code",[e._v("AbstractInboundFileSynchronizingMessageSource")]),e._v(" and "),n("code",[e._v("AbstractRemoteFileStreamingMessageSource")]),e._v(" implementations.\nAlso this information is included into headers in the read operations results of the "),n("code",[e._v("AbstractRemoteFileOutboundGateway")]),e._v(" implementations.\nThe FTP outbound endpoints now support "),n("code",[e._v("chmod")]),e._v(" to change permissions on the uploaded file.\n(SFTP already supported it since version 4.3).\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ftp.html#ftp"}},[e._v("FTP(S) Support")]),e._v(" and "),n("RouterLink",{attrs:{to:"/en/spring-integration/sftp.html#sftp"}},[e._v("SFTP Support")]),e._v(" for more information.")],1),e._v(" "),n("h3",{attrs:{id:"changes-between-5-0-and-5-1"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#changes-between-5-0-and-5-1"}},[e._v("#")]),e._v(" Changes between 5.0 and 5.1")]),e._v(" "),n("h4",{attrs:{id:"new-components-4"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#new-components-4"}},[e._v("#")]),e._v(" New Components")]),e._v(" "),n("p",[e._v("The following components are new in 5.1:")]),e._v(" "),n("ul",[n("li",[n("a",{attrs:{href:"#x5.1-AmqpDedicatedChannelAdvice"}},[n("code",[e._v("AmqpDedicatedChannelAdvice")])])])]),e._v(" "),n("h5",{attrs:{id:"amqpdedicatedchanneladvice"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#amqpdedicatedchanneladvice"}},[e._v("#")]),e._v(" "),n("code",[e._v("AmqpDedicatedChannelAdvice")])]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/amqp.html#amqp-strict-ordering"}},[e._v("Strict Message Ordering")]),e._v(".")],1),e._v(" "),n("h5",{attrs:{id:"improved-function-support"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#improved-function-support"}},[e._v("#")]),e._v(" Improved Function Support")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("java.util.function")]),e._v(" interfaces now have improved integration support in the Framework components.\nAlso Kotlin lambdas now can be used for handler and source methods.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/functions-support.html#functions-support"}},[n("code",[e._v("java.util.function")]),e._v(" Interfaces Support")]),e._v(".")],1),e._v(" "),n("h5",{attrs:{id:"longrunningtest"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#longrunningtest"}},[e._v("#")]),e._v(" "),n("code",[e._v("@LongRunningTest")])]),e._v(" "),n("p",[e._v("A JUnit 5 "),n("code",[e._v("@LongRunningTest")]),e._v(" conditional annotation is provided to check the environment or system properties for the "),n("code",[e._v("RUN_LONG_INTEGRATION_TESTS")]),e._v(" entry with the value of "),n("code",[e._v("true")]),e._v(" to determine if test should be run or skipped.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/testing.html#test-junit-rules"}},[e._v("JUnit Rules and Conditions")]),e._v(".")],1),e._v(" "),n("h4",{attrs:{id:"general-changes-4"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#general-changes-4"}},[e._v("#")]),e._v(" General Changes")]),e._v(" "),n("p",[e._v("The following changes have been made in version 5.1:")]),e._v(" "),n("ul",[n("li",[n("p",[n("a",{attrs:{href:"#x5.1-java-dsl"}},[e._v("Java DSL")])])]),e._v(" "),n("li",[n("p",[n("a",{attrs:{href:"#x5.1-dispatcher-exceptions"}},[e._v("Dispatcher Exceptions")])])]),e._v(" "),n("li",[n("p",[n("a",{attrs:{href:"#x5.1-global-channel-interceptors"}},[e._v("Global Channel Interceptors")])])]),e._v(" "),n("li",[n("p",[n("a",{attrs:{href:"#x5.1-object-to-json-transformer"}},[n("code",[e._v("ObjectToJsonTransformer")])])])]),e._v(" "),n("li",[n("p",[n("a",{attrs:{href:"#x5.1-integration-flows-generated-bean-names"}},[e._v("Integration Flows: Generated Bean Names")])])]),e._v(" "),n("li",[n("p",[n("a",{attrs:{href:"#x5.1-aggregator"}},[e._v("Aggregator Changes")])])]),e._v(" "),n("li",[n("p",[n("a",{attrs:{href:"#x5.1-publisher"}},[e._v("@Publisher annotation changes")])])]),e._v(" "),n("li",[n("p",[n("a",{attrs:{href:"#x51.-integration-graph"}},[e._v("Integration Graph Customization")])])]),e._v(" "),n("li",[n("p",[n("a",{attrs:{href:"#x51.-global-properties"}},[e._v("Integration Global Properties")])])]),e._v(" "),n("li",[n("p",[n("a",{attrs:{href:"#x51.-poller-annotation"}},[e._v("The "),n("code",[e._v("receiveTimeout")]),e._v(" for "),n("code",[e._v("@Poller")])])])])]),e._v(" "),n("h5",{attrs:{id:"java-dsl"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#java-dsl"}},[e._v("#")]),e._v(" Java DSL")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("IntegrationFlowContext")]),e._v(" is now an interface and "),n("code",[e._v("IntegrationFlowRegistration")]),e._v(" is an inner interface of "),n("code",[e._v("IntegrationFlowContext")]),e._v(".")]),e._v(" "),n("p",[e._v("A new "),n("code",[e._v("logAndReply()")]),e._v(" operator has been introduced for convenience when you wish to log at the end of a flow for request-reply configurations.\nThis avoid confusion with "),n("code",[e._v("log()")]),e._v(" which is treated as a one-way end flow component.")]),e._v(" "),n("p",[e._v("A generated bean name for any "),n("code",[e._v("NamedComponent")]),e._v(" within an integration flow is now based on the component type for better readability from visual tools, logs analyzers and metrics collectors.")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("GenericHandler.handle()")]),e._v(" now excepts a "),n("code",[e._v("MessageHeaders")]),e._v(" type for the second argument.")]),e._v(" "),n("h5",{attrs:{id:"dispatcher-exceptions"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#dispatcher-exceptions"}},[e._v("#")]),e._v(" Dispatcher Exceptions")]),e._v(" "),n("p",[e._v("Exceptions caught and re-thrown by "),n("code",[e._v("AbstractDispatcher")]),e._v(" are now more consistent:")]),e._v(" "),n("ul",[n("li",[n("p",[e._v("A "),n("code",[e._v("MessagingException")]),e._v(" of any kind that has a "),n("code",[e._v("failedMessage")]),e._v(" property is re-thrown unchanged.")])]),e._v(" "),n("li",[n("p",[e._v("All other exceptions are wrapped in a "),n("code",[e._v("MessageDeliveryException")]),e._v(" with the "),n("code",[e._v("failedMessage")]),e._v(" property set.")])])]),e._v(" "),n("p",[e._v("Previously:")]),e._v(" "),n("ul",[n("li",[n("p",[e._v("A "),n("code",[e._v("MessagingException")]),e._v(" of any kind that has a "),n("code",[e._v("failedMessage")]),e._v(" property was re-thrown unchanged")])]),e._v(" "),n("li",[n("p",[e._v("A "),n("code",[e._v("MessagingException")]),e._v(" that had no "),n("code",[e._v("failedMessage")]),e._v(" property was wrapped in a "),n("code",[e._v("MessagingException")]),e._v(" with the "),n("code",[e._v("failedMessage")]),e._v(" property set.")])]),e._v(" "),n("li",[n("p",[e._v("Other "),n("code",[e._v("RuntimeException")]),e._v(" instances were re-thrown unchanged.")])]),e._v(" "),n("li",[n("p",[e._v("Checked exceptions were wrapped in a "),n("code",[e._v("MessageDeliveryException")]),e._v(" with the "),n("code",[e._v("failedMessage")]),e._v(" property set.")])])]),e._v(" "),n("h5",{attrs:{id:"global-channel-interceptors"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#global-channel-interceptors"}},[e._v("#")]),e._v(" Global Channel Interceptors")]),e._v(" "),n("p",[e._v("Global channel interceptors now apply to dynamically registered channels, such as through the "),n("code",[e._v("IntegrationFlowContext")]),e._v(" when using the Java DSL or beans that are initialized using "),n("code",[e._v("beanFactory.initializeBean()")]),e._v(".\nPreviously, when beans were created after the application context was refreshed, interceptors were not applied.")]),e._v(" "),n("h5",{attrs:{id:"channel-interceptors"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#channel-interceptors"}},[e._v("#")]),e._v(" Channel Interceptors")]),e._v(" "),n("p",[n("code",[e._v("ChannelInterceptor.postReceive()")]),e._v(" is no longer called when no message is received; it is no longer necessary to check for a "),n("code",[e._v("null")]),e._v(" "),n("code",[e._v("Message")]),e._v(".\nPreviously, the method was called.\nIf you have an interceptor that relies on the previous behavior, implement "),n("code",[e._v("afterReceiveCompleted()")]),e._v(" instead, since that method is invoked, regardless of whether a message is received or not.\nFurthermore, the "),n("code",[e._v("PolledAmqpChannel")]),e._v(" and "),n("code",[e._v("PolledJmsChannel")]),e._v(" previously did not invoke "),n("code",[e._v("afterReceiveCompleted()")]),e._v(" with "),n("code",[e._v("null")]),e._v("; they now do.")]),e._v(" "),n("h5",{attrs:{id:"objecttojsontransformer"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#objecttojsontransformer"}},[e._v("#")]),e._v(" "),n("code",[e._v("ObjectToJsonTransformer")])]),e._v(" "),n("p",[e._v("A new "),n("code",[e._v("ResultType.BYTES")]),e._v(" mode is introduced for the "),n("code",[e._v("ObjectToJsonTransformer")]),e._v(".")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/transformer.html#json-transformers"}},[e._v("JSON Transformers")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"integration-flows-generated-bean-names"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#integration-flows-generated-bean-names"}},[e._v("#")]),e._v(" Integration Flows: Generated Bean Names")]),e._v(" "),n("p",[e._v("Starting with version 5.0.5, generated bean names for the components in an "),n("code",[e._v("IntegrationFlow")]),e._v(" include the flow bean name, followed by a dot, as a prefix.\nFor example, if a flow bean were named "),n("code",[e._v("flowBean")]),e._v(", a generated bean might be named "),n("code",[e._v("flowBean.generatedBean")]),e._v(".")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/dsl.html#java-dsl-flows"}},[e._v("Working With Message Flows")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"aggregator-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#aggregator-changes"}},[e._v("#")]),e._v(" Aggregator Changes")]),e._v(" "),n("p",[e._v("If the "),n("code",[e._v("groupTimeout")]),e._v(" is evaluated to a negative value, an aggregator now expires the group immediately.\nOnly "),n("code",[e._v("null")]),e._v(" is considered as a signal to do nothing for the current message.")]),e._v(" "),n("p",[e._v("A new "),n("code",[e._v("popSequence")]),e._v(" property has been introduced to allow (by default) to call a "),n("code",[e._v("MessageBuilder.popSequenceDetails()")]),e._v(" for the output message.\nAlso an "),n("code",[e._v("AbstractAggregatingMessageGroupProcessor")]),e._v(" returns now an "),n("code",[e._v("AbstractIntegrationMessageBuilder")]),e._v(" instead of the whole "),n("code",[e._v("Message")]),e._v(" for optimization.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/aggregator.html#aggregator"}},[e._v("Aggregator")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"publisher-annotation-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#publisher-annotation-changes"}},[e._v("#")]),e._v(" @Publisher annotation changes")]),e._v(" "),n("p",[e._v("Starting with version 5.1, you must explicitly turn on the "),n("code",[e._v("@Publisher")]),e._v(" AOP functionality by using "),n("code",[e._v("@EnablePublisher")]),e._v(" or by using the "),n("code",[e._v("")]),e._v(" child element on "),n("code",[e._v("")]),e._v(".\nAlso the "),n("code",[e._v("proxy-target-class")]),e._v(" and "),n("code",[e._v("order")]),e._v(" attributes have been added for tuning the "),n("code",[e._v("ProxyFactory")]),e._v(" configuration.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/message-publishing.html#publisher-annotation"}},[e._v("Annotation-driven Configuration with the "),n("code",[e._v("@Publisher")]),e._v(" Annotation")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"files-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#files-changes"}},[e._v("#")]),e._v(" Files Changes")]),e._v(" "),n("p",[e._v("If you are using "),n("code",[e._v("FileExistsMode.APPEND")]),e._v(" or "),n("code",[e._v("FileExistsMode.APPEND_NO_FLUSH")]),e._v(" you can provide a "),n("code",[e._v("newFileCallback")]),e._v(" that will be called when creating a new file.\nThis callback receives the newly created file and the message that triggered the callback.\nThis could be used to write a CSV header, for an example.")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("FileReadingMessageSource")]),e._v(" now doesn’t check and create a directory until its "),n("code",[e._v("start()")]),e._v(" is called.\nSo, if an Inbound Channel Adapter for the "),n("code",[e._v("FileReadingMessageSource")]),e._v(" has "),n("code",[e._v("autoStartup = false")]),e._v(", there are no failures against the file system during application start up.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/file.html#files"}},[e._v("File Support")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"amqp-changes-4"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#amqp-changes-4"}},[e._v("#")]),e._v(" AMQP Changes")]),e._v(" "),n("p",[e._v("We have made "),n("code",[e._v("ID")]),e._v(" and "),n("code",[e._v("Timestamp")]),e._v(" header mapping changes in the "),n("code",[e._v("DefaultAmqpHeaderMapper")]),e._v(".\nSee the note near the bottom of "),n("RouterLink",{attrs:{to:"/en/spring-integration/amqp.html#amqp-message-headers"}},[e._v("AMQP Message Headers")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("The "),n("code",[e._v("contentType")]),e._v(" header is now correctly mapped as an entry in the general headers map.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/amqp.html#amqp-content-type"}},[e._v("contentType Header")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("Starting with version 5.1.3, if a message conversion exception occurs when using manual acknowledgments, and an error channel is defined, the payload is a "),n("code",[e._v("ManualAckListenerExecutionFailedException")]),e._v(" with additional "),n("code",[e._v("channel")]),e._v(" and "),n("code",[e._v("deliveryTag")]),e._v(" properties.\nThis enables the error flow to ack/nack the original message.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/amqp.html#amqp-conversion-inbound"}},[e._v("Inbound Message Conversion")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"jdbc-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#jdbc-changes"}},[e._v("#")]),e._v(" JDBC Changes")]),e._v(" "),n("p",[e._v("A confusing "),n("code",[e._v("max-rows-per-poll")]),e._v(" property on the JDBC Inbound Channel Adapter and JDBC Outbound Gateway has been deprecated in favor of the newly introduced "),n("code",[e._v("max-rows")]),e._v(" property.")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("JdbcMessageHandler")]),e._v(" supports now a "),n("code",[e._v("batchUpdate")]),e._v(" functionality when the payload of the request message is an instance of an "),n("code",[e._v("Iterable")]),e._v(" type.")]),e._v(" "),n("p",[e._v("The indexes for the "),n("code",[e._v("INT_CHANNEL_MESSAGE")]),e._v(" table (for the "),n("code",[e._v("JdbcChannelMessageStore")]),e._v(") have been optimized.\nIf you have large message groups in such a store, you may wish to alter the indexes.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/jdbc.html#jdbc"}},[e._v("JDBC Support")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"ftp-and-sftp-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#ftp-and-sftp-changes"}},[e._v("#")]),e._v(" FTP and SFTP Changes")]),e._v(" "),n("p",[e._v("A "),n("code",[e._v("RotatingServerAdvice")]),e._v(" is now available to poll multiple servers and directories with the inbound channel adapters.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ftp.html#ftp-rotating-server-advice"}},[e._v("Inbound Channel Adapters: Polling Multiple Servers and Directories")]),e._v(" and "),n("RouterLink",{attrs:{to:"/en/spring-integration/sftp.html#sftp-rotating-server-advice"}},[e._v("Inbound Channel Adapters: Polling Multiple Servers and Directories")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("Also, inbound adapter "),n("code",[e._v("localFilenameExpression")]),e._v(" instances can contain the "),n("code",[e._v("#remoteDirectory")]),e._v(" variable, which contains the remote directory being polled.\nThe generic type of the comparators (used to sort the fetched file list for the streaming adapters) has changed from "),n("code",[e._v("Comparator>")]),e._v(" to "),n("code",[e._v("Comparator")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ftp.html#ftp-streaming"}},[e._v("FTP Streaming Inbound Channel Adapter")]),e._v(" and "),n("RouterLink",{attrs:{to:"/en/spring-integration/sftp.html#sftp-streaming"}},[e._v("SFTP Streaming Inbound Channel Adapter")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("In addition, the synchronizers for inbound channel adapters can now be provided with a "),n("code",[e._v("Comparator")]),e._v(".\nThis is useful when using "),n("code",[e._v("maxFetchSize")]),e._v(" to limit the files retrieved.")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("CachingSessionFactory")]),e._v(" has a new property "),n("code",[e._v("testSession")]),e._v(" which, when true, causes the factory to perform a "),n("code",[e._v("test()")]),e._v(" operation on the "),n("code",[e._v("Session")]),e._v(" when checking out an existing session from the cache.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/sftp.html#sftp-session-caching"}},[e._v("SFTP Session Caching")]),e._v(" and "),n("RouterLink",{attrs:{to:"/en/spring-integration/ftp.html#ftp-session-caching"}},[e._v("FTP Session Caching")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("The outbound gateway MPUT command now supports a message payload with a collection of files or strings.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/sftp.html#sftp-outbound-gateway"}},[e._v("SFTP Outbound Gateway")]),e._v(" and "),n("RouterLink",{attrs:{to:"/en/spring-integration/ftp.html#ftp-outbound-gateway"}},[e._v("FTP Outbound Gateway")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"tcp-support"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#tcp-support"}},[e._v("#")]),e._v(" TCP Support")]),e._v(" "),n("p",[e._v("When using SSL, host verification is now enabled, by default, to prevent man-in-the-middle attacks with a trusted certificate.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ip.html#tcp-ssl-host-verification"}},[e._v("Host Verification")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("In addition the key and trust store types can now be configured on the "),n("code",[e._v("DefaultTcpSSLContextSupport")]),e._v(".")]),e._v(" "),n("h4",{attrs:{id:"twitter-support"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#twitter-support"}},[e._v("#")]),e._v(" Twitter Support")]),e._v(" "),n("p",[e._v("Since the Spring Social project has moved to "),n("a",{attrs:{href:"https://spring.io/blog/2018/07/03/spring-social-end-of-life-announcement",target:"_blank",rel:"noopener noreferrer"}},[e._v("end of life status"),n("OutboundLink")],1),e._v(", Twitter support in Spring Integration has been moved to the Extensions project.\nSee "),n("a",{attrs:{href:"https://github.com/spring-projects/spring-integration-extensions/tree/main/spring-integration-social-twitter",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Integration Social Twitter"),n("OutboundLink")],1),e._v(" for more information.")]),e._v(" "),n("h4",{attrs:{id:"jms-support"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#jms-support"}},[e._v("#")]),e._v(" JMS Support")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("JmsSendingMessageHandler")]),e._v(" now provides "),n("code",[e._v("deliveryModeExpression")]),e._v(" and "),n("code",[e._v("timeToLiveExpression")]),e._v(" options to determine respective QoS options for JMS message to send at runtime.\nThe "),n("code",[e._v("DefaultJmsHeaderMapper")]),e._v(" now allows to map inbound "),n("code",[e._v("JMSDeliveryMode")]),e._v(" and "),n("code",[e._v("JMSExpiration")]),e._v(" properties via setting to "),n("code",[e._v("true")]),e._v(" respective "),n("code",[e._v("setMapInboundDeliveryMode()")]),e._v(" and "),n("code",[e._v("setMapInboundExpiration()")]),e._v(" options.\nWhen a "),n("code",[e._v("JmsMessageDrivenEndpoint")]),e._v(" or "),n("code",[e._v("JmsInboundGateway")]),e._v(" is stopped, the associated listener container is now shut down; this closes its shared connection and any consumers.\nYou can configure the endpoints to revert to the previous behavior.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/jms.html#jms"}},[e._v("JMS Support")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"http-webflux-support"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#http-webflux-support"}},[e._v("#")]),e._v(" HTTP/WebFlux Support")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("statusCodeExpression")]),e._v(" (and "),n("code",[e._v("Function")]),e._v(") is now supplied with the "),n("code",[e._v("RequestEntity")]),e._v(" as a root object for evaluation context, so request headers, method, URI and body are available for target status code calculation.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/http.html#http"}},[e._v("HTTP Support")]),e._v(" and "),n("RouterLink",{attrs:{to:"/en/spring-integration/webflux.html#webflux"}},[e._v("WebFlux Support")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"jmx-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#jmx-changes"}},[e._v("#")]),e._v(" JMX Changes")]),e._v(" "),n("p",[e._v("Object name key values are now quoted if they contain any characters other than those allowed in a Java identifier (or period "),n("code",[e._v(".")]),e._v(").\nFor example "),n("code",[e._v("org.springframework.integration:type=MessageChannel,")]),e._v(" "),n("code",[e._v('name="input:foo.myGroup.errors"')]),e._v('.\nThis has the side effect that previously "allowed" names, with such characters, will now be quoted.\nFor example '),n("code",[e._v("org.springframework.integration:type=MessageChannel,")]),e._v(" "),n("code",[e._v('name="input#foo.myGroup.errors"')]),e._v(".")]),e._v(" "),n("h4",{attrs:{id:"micrometer-support-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#micrometer-support-changes"}},[e._v("#")]),e._v(" Micrometer Support Changes")]),e._v(" "),n("p",[e._v("It is now simpler to customize the standard Micrometer meters created by the framework.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/metrics.html#micrometer-integration"}},[e._v("Micrometer Integration")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"integration-graph-customization"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#integration-graph-customization"}},[e._v("#")]),e._v(" Integration Graph Customization")]),e._v(" "),n("p",[e._v("It is now possible to add additional properties to the "),n("code",[e._v("IntegrationNode")]),e._v(" s via "),n("code",[e._v("Function> additionalPropertiesCallback")]),e._v(" on the "),n("code",[e._v("IntegrationGraphServer")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/graph.html#integration-graph"}},[e._v("Integration Graph")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"integration-global-properties"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#integration-global-properties"}},[e._v("#")]),e._v(" Integration Global Properties")]),e._v(" "),n("p",[e._v("The Integration global properties (including defaults) can now be printed in the logs, when a "),n("code",[e._v("DEBUG")]),e._v(" logic level is turned on for the "),n("code",[e._v("org.springframework.integration")]),e._v(" category.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/configuration.html#global-properties"}},[e._v("Global Properties")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"the-receivetimeout-for-poller"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#the-receivetimeout-for-poller"}},[e._v("#")]),e._v(" The "),n("code",[e._v("receiveTimeout")]),e._v(" for "),n("code",[e._v("@Poller")])]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("@Poller")]),e._v(" annotation now provides a "),n("code",[e._v("receiveTimeout")]),e._v(" option for convenience.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/configuration.html#configuration-using-poller-annotation"}},[e._v("Using the "),n("code",[e._v("@Poller")]),e._v(" Annotation")]),e._v(" for more information.")],1),e._v(" "),n("h3",{attrs:{id:"changes-between-4-3-and-5-0"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#changes-between-4-3-and-5-0"}},[e._v("#")]),e._v(" Changes between 4.3 and 5.0")]),e._v(" "),n("p",[e._v("See the "),n("a",{attrs:{href:"https://github.com/spring-projects/spring-integration/wiki/Spring-Integration-4.3-to-5.0-Migration-Guide",target:"_blank",rel:"noopener noreferrer"}},[e._v("Migration Guide"),n("OutboundLink")],1),e._v(" for important changes that might affect your applications.\nYou can find migration guides for all versions back to 2.1 on the "),n("a",{attrs:{href:"https://github.com/spring-projects/spring-integration/wiki",target:"_blank",rel:"noopener noreferrer"}},[e._v("wiki"),n("OutboundLink")],1),e._v(".")]),e._v(" "),n("h4",{attrs:{id:"new-components-5"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#new-components-5"}},[e._v("#")]),e._v(" New Components")]),e._v(" "),n("p",[e._v("Version 5.0 added a number of new components.")]),e._v(" "),n("h5",{attrs:{id:"java-dsl-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#java-dsl-2"}},[e._v("#")]),e._v(" Java DSL")]),e._v(" "),n("p",[e._v("The separate "),n("a",{attrs:{href:"https://github.com/spring-projects/spring-integration-java-dsl",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Integration Java DSL"),n("OutboundLink")],1),e._v(" project has now been merged into the core Spring Integration project.\nThe "),n("code",[e._v("IntegrationComponentSpec")]),e._v(" implementations for channel adapters and gateways are distributed to their specific modules.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/dsl.html#java-dsl"}},[e._v("Java DSL")]),e._v(" for more information about Java DSL support.\nSee also the "),n("a",{attrs:{href:"https://github.com/spring-projects/spring-integration/wiki/Spring-Integration-4.3-to-5.0-Migration-Guide#java-dsl",target:"_blank",rel:"noopener noreferrer"}},[e._v("4.3 to 5.0 Migration Guide"),n("OutboundLink")],1),e._v(" for the required steps to move to Spring Integration 5.0.")],1),e._v(" "),n("h5",{attrs:{id:"testing-support"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#testing-support"}},[e._v("#")]),e._v(" Testing Support")]),e._v(" "),n("p",[e._v("We created a new Spring Integration Test Framework to help with testing Spring Integration applications.\nNow, with the "),n("code",[e._v("@SpringIntegrationTest")]),e._v(" annotation on test classes and the "),n("code",[e._v("MockIntegration")]),e._v(" factory, you can make your JUnit tests for integration flows somewhat easier.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/testing.html#testing"}},[e._v("Testing support")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"mongodb-outbound-gateway"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#mongodb-outbound-gateway"}},[e._v("#")]),e._v(" MongoDB Outbound Gateway")]),e._v(" "),n("p",[e._v("The new "),n("code",[e._v("MongoDbOutboundGateway")]),e._v(" lets you make queries to the database on demand by sending a message to its request channel.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/mongodb.html#mongodb-outbound-gateway"}},[e._v("MongoDB Outbound Gateway")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"webflux-gateways-and-channel-adapters"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#webflux-gateways-and-channel-adapters"}},[e._v("#")]),e._v(" WebFlux Gateways and Channel Adapters")]),e._v(" "),n("p",[e._v("We introduced the new WebFlux support module for Spring WebFlux Framework gateways and channel adapters.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/webflux.html#webflux"}},[e._v("WebFlux Support")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"content-type-conversion"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#content-type-conversion"}},[e._v("#")]),e._v(" Content Type Conversion")]),e._v(" "),n("p",[e._v("Now that we use the new "),n("code",[e._v("InvocableHandlerMethod")]),e._v("-based infrastructure for service method invocations, we can perform "),n("code",[e._v("contentType")]),e._v(" conversion from the payload to a target method argument.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/endpoint.html#content-type-conversion"}},[e._v("Content Type Conversion")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"errormessagepublisher-and-errormessagestrategy"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#errormessagepublisher-and-errormessagestrategy"}},[e._v("#")]),e._v(" "),n("code",[e._v("ErrorMessagePublisher")]),e._v(" and "),n("code",[e._v("ErrorMessageStrategy")])]),e._v(" "),n("p",[e._v("We added "),n("code",[e._v("ErrorMessagePublisher")]),e._v(" and the "),n("code",[e._v("ErrorMessageStrategy")]),e._v(" for creating "),n("code",[e._v("ErrorMessage")]),e._v(" instances.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/error-handling.html#error-handling"}},[e._v("Error Handling")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"jdbc-metadata-store"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#jdbc-metadata-store"}},[e._v("#")]),e._v(" JDBC Metadata Store")]),e._v(" "),n("p",[e._v("We added a JDBC implementation of the "),n("code",[e._v("MetadataStore")]),e._v(" implementation.\nThis is useful when you need to ensure transactional boundaries for metadata.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/jdbc.html#jdbc-metadata-store"}},[e._v("JDBC Metadata Store")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"general-changes-5"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#general-changes-5"}},[e._v("#")]),e._v(" General Changes")]),e._v(" "),n("p",[e._v("Spring Integration is now fully based on Spring Framework "),n("code",[e._v("5.0")]),e._v(" and Project Reactor "),n("code",[e._v("3.1")]),e._v(".\nPrevious Project Reactor versions are no longer supported.")]),e._v(" "),n("h5",{attrs:{id:"core-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#core-changes"}},[e._v("#")]),e._v(" Core Changes")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("@Poller")]),e._v(" annotation now has the "),n("code",[e._v("errorChannel")]),e._v(" attribute for easier configuration of the underlying "),n("code",[e._v("MessagePublishingErrorHandler")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/configuration.html#annotations"}},[e._v("Annotation Support")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("All the request-reply endpoints (based on "),n("code",[e._v("AbstractReplyProducingMessageHandler")]),e._v(") can now start transactions and, therefore, make the whole downstream flow transactional.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/handler-advice.html#tx-handle-message-advice"}},[e._v("Transaction Support")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("The "),n("code",[e._v("SmartLifecycleRoleController")]),e._v(" now provides methods to obtain status of endpoints in roles.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/endpoint.html#endpoint-roles"}},[e._v("Endpoint Roles")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("By default, POJO methods are now invoked by using an "),n("code",[e._v("InvocableHandlerMethod")]),e._v(", but you can configure them to use SpEL, as before.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/overview.html#pojo-invocation"}},[e._v("POJO Method invocation")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("When targeting POJO methods as message handlers, you can now mark one of the service methods with the "),n("code",[e._v("@Default")]),e._v(" annotation to provide a fallback mechanism for non-matched conditions.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/service-activator.html#service-activator-namespace"}},[e._v("Configuring Service Activator")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("We added a simple "),n("code",[e._v("PassThroughTransactionSynchronizationFactory")]),e._v(" to always store a polled message in the current transaction context.\nThat message is used as a "),n("code",[e._v("failedMessage")]),e._v(" property of the "),n("code",[e._v("MessagingException")]),e._v(", which wraps any raw exception thrown during transaction completion.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/transactions.html#transaction-synchronization"}},[e._v("Transaction Synchronization")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("The aggregator expression-based "),n("code",[e._v("ReleaseStrategy")]),e._v(" now evaluates the expression against the "),n("code",[e._v("MessageGroup")]),e._v(" instead of just the collection of "),n("code",[e._v("Message")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/aggregator.html#aggregator-spel"}},[e._v("Aggregators and Spring Expression Language (SpEL)")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("You can now supply the "),n("code",[e._v("ObjectToMapTransformer")]),e._v(" with a customized "),n("code",[e._v("JsonObjectMapper")]),e._v(".")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/aggregator.html#aggregator-spel"}},[e._v("Aggregators and Spring Expression Language (SpEL)")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("The "),n("code",[e._v("@GlobalChannelInterceptor")]),e._v(" annotation and "),n("code",[e._v("")]),e._v(" now support negative patterns (via "),n("code",[e._v("!")]),e._v(" prepending) for component names matching.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/channel.html#global-channel-configuration-interceptors"}},[e._v("Global Channel Interceptor Configuration")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("When a candidate failed to acquire the lock, the "),n("code",[e._v("LockRegistryLeaderInitiator")]),e._v(" now emits a new "),n("code",[e._v("OnFailedToAcquireMutexEvent")]),e._v(" through "),n("code",[e._v("DefaultLeaderEventPublisher")]),e._v(".\nSee "),n("code",[e._v("[Leadership Event Handling](./endpoint.html#leadership-event-handling)")]),e._v(" for more information.")]),e._v(" "),n("h5",{attrs:{id:"gateway-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#gateway-changes"}},[e._v("#")]),e._v(" Gateway Changes")]),e._v(" "),n("p",[e._v("When the gateway method has a "),n("code",[e._v("void")]),e._v(" return type and an error channel is provided, the gateway now correctly sets the "),n("code",[e._v("errorChannel")]),e._v(" header.\nPreviously, the header was not populated.\nThis caused synchronous downstream flows (running on the calling thread) to send the exception to the configured channel, but an exception on an asynchronous downstream flow would be sent to the default "),n("code",[e._v("errorChannel")]),e._v(" instead.")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("RequestReplyExchanger")]),e._v(" interface now has a "),n("code",[e._v("throws MessagingException")]),e._v(" clause to meet the proposed messages exchange contract.")]),e._v(" "),n("p",[e._v("You can now specify the request and reply timeouts with SpEL expressions.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/gateway.html#gateway"}},[e._v("Messaging Gateways")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"aggregator-performance-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#aggregator-performance-changes"}},[e._v("#")]),e._v(" Aggregator Performance Changes")]),e._v(" "),n("p",[e._v("By default, aggregators now use a "),n("code",[e._v("SimpleSequenceSizeReleaseStrategy")]),e._v(", which is more efficient, especially with large groups.\nEmpty groups are now scheduled for removal after "),n("code",[e._v("empty-group-min-timeout")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/aggregator.html#aggregator"}},[e._v("Aggregator")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"splitter-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#splitter-changes"}},[e._v("#")]),e._v(" Splitter Changes")]),e._v(" "),n("p",[e._v("The splitter component can now handle and split Java "),n("code",[e._v("Stream")]),e._v(" and Reactive Streams "),n("code",[e._v("Publisher")]),e._v(" objects.\nIf the output channel is a "),n("code",[e._v("ReactiveStreamsSubscribableChannel")]),e._v(", the "),n("code",[e._v("AbstractMessageSplitter")]),e._v(" builds a "),n("code",[e._v("Flux")]),e._v(" for subsequent iteration instead of a regular "),n("code",[e._v("Iterator")]),e._v(", independent of the object being split.\nIn addition, "),n("code",[e._v("AbstractMessageSplitter")]),e._v(" provides "),n("code",[e._v("protected obtainSizeIfPossible()")]),e._v(" methods to allow determination of the size of the "),n("code",[e._v("Iterable")]),e._v(" and "),n("code",[e._v("Iterator")]),e._v(" objects, if that is possible.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/splitter.html#splitter"}},[e._v("Splitter")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"jms-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#jms-changes"}},[e._v("#")]),e._v(" JMS Changes")]),e._v(" "),n("p",[e._v("Previously, Spring Integration JMS XML configuration used a default bean name of "),n("code",[e._v("connectionFactory")]),e._v(" for the JMS connection factory, letting the property be omitted from component definitions.\nWe renamed it to "),n("code",[e._v("jmsConnectionFactory")]),e._v(", which is the bean name used by Spring Boot to auto-configure the JMS connection factory bean.")]),e._v(" "),n("p",[e._v("If your application relies on the previous behavior, you can rename your "),n("code",[e._v("connectionFactory")]),e._v(" bean to "),n("code",[e._v("jmsConnectionFactory")]),e._v(" or specifically configure your components to use your bean by using its current name.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/jms.html#jms"}},[e._v("JMS Support")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"mail-changes-3"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#mail-changes-3"}},[e._v("#")]),e._v(" Mail Changes")]),e._v(" "),n("p",[e._v("Some inconsistencies with rendering IMAP mail content have been resolved.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/mail.html#imap-format-important"}},[e._v("the note in the “Mail-receiving Channel Adapter” section")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"feed-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#feed-changes"}},[e._v("#")]),e._v(" Feed Changes")]),e._v(" "),n("p",[e._v("Instead of the "),n("code",[e._v("com.rometools.fetcher.FeedFetcher")]),e._v(", which is deprecated in ROME, we introduced a new "),n("code",[e._v("Resource")]),e._v(" property for the "),n("code",[e._v("FeedEntryMessageSource")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/feed.html#feed"}},[e._v("Feed Adapter")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"file-changes-3"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#file-changes-3"}},[e._v("#")]),e._v(" File Changes")]),e._v(" "),n("p",[e._v("We introduced the new "),n("code",[e._v("FileHeaders.RELATIVE_PATH")]),e._v(" message header to represent relative path in "),n("code",[e._v("FileReadingMessageSource")]),e._v(".")]),e._v(" "),n("p",[e._v("The tail adapter now supports "),n("code",[e._v("idleEventInterval")]),e._v(" to emit events when there is no data in the file during that period.")]),e._v(" "),n("p",[e._v("The flush predicates for the "),n("code",[e._v("FileWritingMessageHandler")]),e._v(" now have an additional parameter.")]),e._v(" "),n("p",[e._v("The file outbound channel adapter and gateway ("),n("code",[e._v("FileWritingMessageHandler")]),e._v(") now support the "),n("code",[e._v("REPLACE_IF_MODIFIED")]),e._v(" "),n("code",[e._v("FileExistsMode")]),e._v(".")]),e._v(" "),n("p",[e._v("They also now support setting file permissions on the newly written file.")]),e._v(" "),n("p",[e._v("A new "),n("code",[e._v("FileSystemMarkerFilePresentFileListFilter")]),e._v(" is now available.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/file.html#file-incomplete"}},[e._v("Dealing With Incomplete Data")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("The "),n("code",[e._v("FileSplitter")]),e._v(" now provides a "),n("code",[e._v("firstLineAsHeader")]),e._v(" option to carry the first line of content as a header in the messages emitted for the remaining lines.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/file.html#files"}},[e._v("File Support")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"ftp-and-sftp-changes-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#ftp-and-sftp-changes-2"}},[e._v("#")]),e._v(" FTP and SFTP Changes")]),e._v(" "),n("p",[e._v("The inbound channel adapters now have a property called "),n("code",[e._v("max-fetch-size")]),e._v(", which is used to limit the number of files fetched during a poll when no files are currently in the local directory.\nBy default, they also are configured with a "),n("code",[e._v("FileSystemPersistentAcceptOnceFileListFilter")]),e._v(" in the "),n("code",[e._v("local-filter")]),e._v(".")]),e._v(" "),n("p",[e._v("You can also provide a custom "),n("code",[e._v("DirectoryScanner")]),e._v(" implementation to inbound channel adapters by setting the newly introduced "),n("code",[e._v("scanner")]),e._v(" attribute.")]),e._v(" "),n("p",[e._v("You can now configure the regex and pattern filters to always pass directories.\nThis can be useful when you use recursion in the outbound gateways.")]),e._v(" "),n("p",[e._v("By default, all the inbound channel adapters (streaming and synchronization-based) now use an appropriate "),n("code",[e._v("AbstractPersistentAcceptOnceFileListFilter")]),e._v(" implementation to prevent duplicate downloads of remote files.")]),e._v(" "),n("p",[e._v("The FTP and SFTP outbound gateways now support the "),n("code",[e._v("REPLACE_IF_MODIFIED")]),e._v(" "),n("code",[e._v("FileExistsMode")]),e._v(" when fetching remote files.")]),e._v(" "),n("p",[e._v("The FTP and SFTP streaming inbound channel adapters now add remote file information in a message header.")]),e._v(" "),n("p",[e._v("The FTP and SFTP outbound channel adapters (as well as the "),n("code",[e._v("PUT")]),e._v(" command for outbound gateways) now support "),n("code",[e._v("InputStream")]),e._v(" as "),n("code",[e._v("payload")]),e._v(", too.")]),e._v(" "),n("p",[e._v("The inbound channel adapters can now build file trees locally by using a newly introduced "),n("code",[e._v("RecursiveDirectoryScanner")]),e._v(".\nSee the "),n("code",[e._v("scanner")]),e._v(" option in the "),n("RouterLink",{attrs:{to:"/en/spring-integration/ftp.html#ftp-inbound"}},[e._v("FTP Inbound Channel Adapter")]),e._v(" section for injection.\nAlso, you can now switch these adapters to the "),n("code",[e._v("WatchService")]),e._v(" instead.")],1),e._v(" "),n("p",[e._v("We added The "),n("code",[e._v("NLST")]),e._v(" command to the "),n("code",[e._v("AbstractRemoteFileOutboundGateway")]),e._v(" to perform the list files names remote command.")]),e._v(" "),n("p",[e._v("You can now supply the "),n("code",[e._v("FtpOutboundGateway")]),e._v(" with "),n("code",[e._v("workingDirExpression")]),e._v(" to change the FTP client working directory for the current request message.")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("RemoteFileTemplate")]),e._v(" is supplied now with the "),n("code",[e._v("invoke(OperationsCallback action)")]),e._v(" to perform several "),n("code",[e._v("RemoteFileOperations")]),e._v(" calls in the scope of the same, thread-bounded, "),n("code",[e._v("Session")]),e._v(".")]),e._v(" "),n("p",[e._v("We added new filters for detecting incomplete remote files.")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("FtpOutboundGateway")]),e._v(" and "),n("code",[e._v("SftpOutboundGateway")]),e._v(" now support an option to remove the remote file after a successful transfer by using the "),n("code",[e._v("GET")]),e._v(" or "),n("code",[e._v("MGET")]),e._v(" commands.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/ftp.html#ftp"}},[e._v("FTP/FTPS Adapters")]),e._v(" and "),n("RouterLink",{attrs:{to:"/en/spring-integration/sftp.html#sftp"}},[e._v("SFTP Adapters")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"integration-properties"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#integration-properties"}},[e._v("#")]),e._v(" Integration Properties")]),e._v(" "),n("p",[e._v("Version 4.3.2 added a new "),n("code",[e._v("spring.integration.readOnly.headers")]),e._v(" global property to let you customize the list of headers that should not be copied to a newly created "),n("code",[e._v("Message")]),e._v(" by the "),n("code",[e._v("MessageBuilder")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/configuration.html#global-properties"}},[e._v("Global Properties")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"stream-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#stream-changes"}},[e._v("#")]),e._v(" Stream Changes")]),e._v(" "),n("p",[e._v("We added a new option on the "),n("code",[e._v("CharacterStreamReadingMessageSource")]),e._v(" to let it be used to “pipe” stdin and publish an application event when the pipe is closed.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/stream.html#stream-reading"}},[e._v("Reading from Streams")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"barrier-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#barrier-changes"}},[e._v("#")]),e._v(" Barrier Changes")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("BarrierMessageHandler")]),e._v(" now supports a discard channel to which late-arriving trigger messages are sent.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/barrier.html#barrier"}},[e._v("Thread Barrier")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"amqp-changes-5"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#amqp-changes-5"}},[e._v("#")]),e._v(" AMQP Changes")]),e._v(" "),n("p",[e._v("The AMQP outbound endpoints now support setting a delay expression when you use the RabbitMQ Delayed Message Exchange plugin.")]),e._v(" "),n("p",[e._v("The inbound endpoints now support the Spring AMQP "),n("code",[e._v("DirectMessageListenerContainer")]),e._v(".")]),e._v(" "),n("p",[e._v("Pollable AMQP-backed channels now block the poller thread for the poller’s configured "),n("code",[e._v("receiveTimeout")]),e._v(" (default: one second).")]),e._v(" "),n("p",[e._v("Headers, such as "),n("code",[e._v("contentType")]),e._v(", that are added to message properties by the message converter are now used in the final message.\nPreviously, it depended on the converter type as to which headers and message properties appeared in the final message.\nTo override the headers set by the converter, set the "),n("code",[e._v("headersMappedLast")]),e._v(" property to "),n("code",[e._v("true")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/amqp.html#amqp"}},[e._v("AMQP Support")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"http-changes-3"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#http-changes-3"}},[e._v("#")]),e._v(" HTTP Changes")]),e._v(" "),n("p",[e._v("By default, the "),n("code",[e._v("DefaultHttpHeaderMapper.userDefinedHeaderPrefix")]),e._v(" property is now an empty string instead of "),n("code",[e._v("X-")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/http.html#http-header-mapping"}},[e._v("HTTP Header Mappings")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("By default, "),n("code",[e._v("uriVariablesExpression")]),e._v(" now uses a "),n("code",[e._v("SimpleEvaluationContext")]),e._v(" (since 5.0.4).")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/http.html#mapping-uri-variables"}},[e._v("Mapping URI Variables")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"mqtt-changes-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#mqtt-changes-2"}},[e._v("#")]),e._v(" MQTT Changes")]),e._v(" "),n("p",[e._v("Inbound messages are now mapped with the "),n("code",[e._v("RECEIVED_TOPIC")]),e._v(", "),n("code",[e._v("RECEIVED_QOS")]),e._v(", and "),n("code",[e._v("RECEIVED_RETAINED")]),e._v(" headers to avoid inadvertent propagation to outbound messages when an application relays messages.")]),e._v(" "),n("p",[e._v("The outbound channel adapter now supports expressions for the topic, qos, and retained properties.\nThe defaults remain the same.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/mqtt.html#mqtt"}},[e._v("MQTT Support")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"stomp-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#stomp-changes"}},[e._v("#")]),e._v(" STOMP Changes")]),e._v(" "),n("p",[e._v("We changed the STOMP module to use "),n("code",[e._v("ReactorNettyTcpStompClient")]),e._v(", based on the Project Reactor "),n("code",[e._v("3.1")]),e._v(" and "),n("code",[e._v("reactor-netty")]),e._v(" extension.\nWe renamed "),n("code",[e._v("Reactor2TcpStompSessionManager")]),e._v(" to "),n("code",[e._v("ReactorNettyTcpStompSessionManager")]),e._v(", according to the "),n("code",[e._v("ReactorNettyTcpStompClient")]),e._v(" foundation.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/stomp.html#stomp"}},[e._v("STOMP Support")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"web-services-changes-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#web-services-changes-2"}},[e._v("#")]),e._v(" Web Services Changes")]),e._v(" "),n("p",[e._v("You can now supply "),n("code",[e._v("WebServiceOutboundGateway")]),e._v(" instances with an externally configured "),n("code",[e._v("WebServiceTemplate")]),e._v(" instances.")]),e._v(" "),n("p",[n("code",[e._v("DefaultSoapHeaderMapper")]),e._v(" can now map a "),n("code",[e._v("javax.xml.transform.Source")]),e._v(" user-defined header to a SOAP header element.")]),e._v(" "),n("p",[e._v("Simple WebService inbound and outbound gateways can now deal with the complete "),n("code",[e._v("WebServiceMessage")]),e._v(" as a "),n("code",[e._v("payload")]),e._v(", allowing the manipulation of MTOM attachments.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/ws.html#ws"}},[e._v("Web Services Support")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"redis-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#redis-changes"}},[e._v("#")]),e._v(" Redis Changes")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("RedisStoreWritingMessageHandler")]),e._v(" is supplied now with additional "),n("code",[e._v("String")]),e._v("-based setters for SpEL expressions (for convenience with Java configuration).\nYou can now configure the "),n("code",[e._v("zsetIncrementExpression")]),e._v(" on the "),n("code",[e._v("RedisStoreWritingMessageHandler")]),e._v(" as well.\nIn addition, this property has been changed from "),n("code",[e._v("true")]),e._v(" to "),n("code",[e._v("false")]),e._v(" since the "),n("code",[e._v("INCR")]),e._v(" option on "),n("code",[e._v("ZADD")]),e._v(" Redis command is optional.")]),e._v(" "),n("p",[e._v("You can now supply the "),n("code",[e._v("RedisInboundChannelAdapter")]),e._v(" with an "),n("code",[e._v("Executor")]),e._v(" for executing Redis listener invokers.\nIn addition, the received messages now contain a "),n("code",[e._v("RedisHeaders.MESSAGE_SOURCE")]),e._v(" header to indicate the source of the message (topic or pattern).")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/redis.html#redis"}},[e._v("Redis Support")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"tcp-changes-3"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#tcp-changes-3"}},[e._v("#")]),e._v(" TCP Changes")]),e._v(" "),n("p",[e._v("We added a new "),n("code",[e._v("ThreadAffinityClientConnectionFactory")]),e._v(" to bind TCP connections to threads.")]),e._v(" "),n("p",[e._v("You can now configure the TCP connection factories to support "),n("code",[e._v("PushbackInputStream")]),e._v(" instances, letting deserializers “unread” (push back) bytes after “reading ahead”.")]),e._v(" "),n("p",[e._v("We added a "),n("code",[e._v("ByteArrayElasticRawDeserializer")]),e._v(" without "),n("code",[e._v("maxMessageSize")]),e._v(" to control and buffer incoming data as needed.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/ip.html#ip"}},[e._v("TCP and UDP Support")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"gemfire-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#gemfire-changes"}},[e._v("#")]),e._v(" Gemfire Changes")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("GemfireMetadataStore")]),e._v(" now implements "),n("code",[e._v("ListenableMetadataStore")]),e._v(", letting you listen to cache events by providing "),n("code",[e._v("MetadataStoreListener")]),e._v(" instances to the store.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/gemfire.html#gemfire"}},[e._v("Pivotal GemFire and Apache Geode Support")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"jdbc-changes-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#jdbc-changes-2"}},[e._v("#")]),e._v(" JDBC Changes")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("JdbcMessageChannelStore")]),e._v(" now provides a setter for "),n("code",[e._v("ChannelMessageStorePreparedStatementSetter")]),e._v(", letting you customize message insertion in the store.")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("ExpressionEvaluatingSqlParameterSourceFactory")]),e._v(" now provides a setter for "),n("code",[e._v("sqlParameterTypes")]),e._v(", letting you customize the SQL types of the parameters.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/jdbc.html#jdbc"}},[e._v("JDBC Support")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"metrics-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#metrics-changes"}},[e._v("#")]),e._v(" Metrics Changes")]),e._v(" "),n("p",[n("a",{attrs:{href:"https://micrometer.io/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Micrometer"),n("OutboundLink")],1),e._v(" application monitoring is now supported (since version 5.0.2).\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/metrics.html#micrometer-integration"}},[e._v("Micrometer Integration")]),e._v(" for more information.")],1),e._v(" "),n("table",[n("thead",[n("tr",[n("th"),e._v(" "),n("th",[e._v("Changes were made to the Micrometer "),n("code",[e._v("Meters")]),e._v(" in version 5.0.3 to make them more suitable for use in dimensional systems."),n("br"),e._v("Further changes were made in 5.0.4."),n("br"),e._v("If you use Micrometer, we recommend a minimum of version 5.0.4.")])])]),e._v(" "),n("tbody")]),e._v(" "),n("h5",{attrs:{id:"endpointid-annotations"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#endpointid-annotations"}},[e._v("#")]),e._v(" "),n("code",[e._v("@EndpointId")]),e._v(" Annotations")]),e._v(" "),n("p",[e._v("Introduced in version 5.0.4, this annotation provides control over bean naming when you use Java configuration.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/overview.html#endpoint-bean-names"}},[e._v("Endpoint Bean Names")]),e._v(" for more information.")],1),e._v(" "),n("h3",{attrs:{id:"changes-between-4-2-and-4-3"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#changes-between-4-2-and-4-3"}},[e._v("#")]),e._v(" Changes between 4.2 and 4.3")]),e._v(" "),n("p",[e._v("See the "),n("a",{attrs:{href:"https://github.com/spring-projects/spring-integration/wiki/Spring-Integration-4.2-to-4.3-Migration-Guide",target:"_blank",rel:"noopener noreferrer"}},[e._v("Migration Guide"),n("OutboundLink")],1),e._v("for important changes that might affect your applications.\nYou can find migration guides for all versions back to 2.1 on the "),n("a",{attrs:{href:"https://github.com/spring-projects/spring-integration/wiki",target:"_blank",rel:"noopener noreferrer"}},[e._v("Wiki"),n("OutboundLink")],1),e._v(".")]),e._v(" "),n("h4",{attrs:{id:"new-components-6"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#new-components-6"}},[e._v("#")]),e._v(" New Components")]),e._v(" "),n("p",[e._v("Version 4.3 added a number of new components.")]),e._v(" "),n("h5",{attrs:{id:"amqp-async-outbound-gateway"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#amqp-async-outbound-gateway"}},[e._v("#")]),e._v(" AMQP Async Outbound Gateway")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/amqp.html#amqp-async-outbound-gateway"}},[e._v("Asynchronous Outbound Gateway")]),e._v(".")],1),e._v(" "),n("h5",{attrs:{id:"messagegroupfactory"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#messagegroupfactory"}},[e._v("#")]),e._v(" "),n("code",[e._v("MessageGroupFactory")])]),e._v(" "),n("p",[e._v("We introduced the "),n("code",[e._v("MessageGroupFactory")]),e._v(" strategy to allow control over "),n("code",[e._v("MessageGroup")]),e._v(" instances in "),n("code",[e._v("MessageGroupStore")]),e._v(" logic.\nWe added "),n("code",[e._v("SimpleMessageGroupFactory")]),e._v(" implementation for the "),n("code",[e._v("SimpleMessageGroup")]),e._v(", with the "),n("code",[e._v("GroupType.HASH_SET")]),e._v(" as the default\nfactory for the standard "),n("code",[e._v("MessageGroupStore")]),e._v(" implementations.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/message-store.html#message-store"}},[e._v("Message Store")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"persistentmessagegroup"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#persistentmessagegroup"}},[e._v("#")]),e._v(" "),n("code",[e._v("PersistentMessageGroup")])]),e._v(" "),n("p",[e._v("We added the "),n("code",[e._v("PersistentMessageGroup")]),e._v(" (lazy-load proxy) implementation for persistent "),n("code",[e._v("MessageGroupStore")]),e._v(" instances,\nwhich return this instance for the "),n("code",[e._v("getMessageGroup()")]),e._v(" when their "),n("code",[e._v("lazyLoadMessageGroups")]),e._v(" is "),n("code",[e._v("true")]),e._v(" (the default).\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/message-store.html#message-store"}},[e._v("Message Store")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"ftp-and-sftp-streaming-inbound-channel-adapters"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#ftp-and-sftp-streaming-inbound-channel-adapters"}},[e._v("#")]),e._v(" FTP and SFTP Streaming Inbound Channel Adapters")]),e._v(" "),n("p",[e._v("We added inbound channel adapters that return an "),n("code",[e._v("InputStream")]),e._v(" for each file, letting you retrieve remote files without writing them to the local file system.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ftp.html#ftp-streaming"}},[e._v("FTP Streaming Inbound Channel Adapter")]),e._v(" and "),n("RouterLink",{attrs:{to:"/en/spring-integration/sftp.html#sftp-streaming"}},[e._v("SFTP Streaming Inbound Channel Adapter")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"streamtransformer"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#streamtransformer"}},[e._v("#")]),e._v(" "),n("code",[e._v("StreamTransformer")])]),e._v(" "),n("p",[e._v("We added "),n("code",[e._v("StreamTransformer")]),e._v(" to transform an "),n("code",[e._v("InputStream")]),e._v(" payload to either a "),n("code",[e._v("byte[]")]),e._v(" or a "),n("code",[e._v("String")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/transformer.html#stream-transformer"}},[e._v("Stream Transformer")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"integration-graph"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#integration-graph"}},[e._v("#")]),e._v(" Integration Graph")]),e._v(" "),n("p",[e._v("We added "),n("code",[e._v("IntegrationGraphServer")]),e._v(", together with the "),n("code",[e._v("IntegrationGraphController")]),e._v(" REST service, to expose the runtime model of a Spring Integration application as a graph.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/graph.html#integration-graph"}},[e._v("Integration Graph")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"jdbc-lock-registry"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#jdbc-lock-registry"}},[e._v("#")]),e._v(" JDBC Lock Registry")]),e._v(" "),n("p",[e._v("We added "),n("code",[e._v("JdbcLockRegistry")]),e._v(" for distributed locks shared through a database table.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/jdbc.html#jdbc-lock-registry"}},[e._v("JDBC Lock Registry")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"leaderinitiator-for-lockregistry"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#leaderinitiator-for-lockregistry"}},[e._v("#")]),e._v(" "),n("code",[e._v("LeaderInitiator")]),e._v(" for "),n("code",[e._v("LockRegistry")])]),e._v(" "),n("p",[e._v("We added "),n("code",[e._v("LeaderInitiator")]),e._v(" implementation based on the "),n("code",[e._v("LockRegistry")]),e._v(" strategy.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/endpoint.html#leadership-event-handling"}},[e._v("Leadership Event Handling")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"general-changes-6"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#general-changes-6"}},[e._v("#")]),e._v(" General Changes")]),e._v(" "),n("p",[e._v("This section describes general changes that version 4.3 brought to Spring Integration.")]),e._v(" "),n("h5",{attrs:{id:"core-changes-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#core-changes-2"}},[e._v("#")]),e._v(" Core Changes")]),e._v(" "),n("p",[e._v("This section describes general changes to the core of Spring Integration.")]),e._v(" "),n("h6",{attrs:{id:"outbound-gateway-within-a-chain"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#outbound-gateway-within-a-chain"}},[e._v("#")]),e._v(" Outbound Gateway within a Chain")]),e._v(" "),n("p",[e._v("Previously, you could specify a "),n("code",[e._v("reply-channel")]),e._v(" on an outbound gateway within a chain.\nIt was completely ignored.\nThe gateway’s reply goes to the next chain element or, if the gateway is the last element, to the chain’s output channel.\nThis condition is now detected and disallowed.\nIf you have such a configuration, remove the "),n("code",[e._v("reply-channel")]),e._v(".")]),e._v(" "),n("h6",{attrs:{id:"asynchronous-service-activator"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#asynchronous-service-activator"}},[e._v("#")]),e._v(" Asynchronous Service Activator")]),e._v(" "),n("p",[e._v("We added an option to make the service activator be synchronous.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/service-activator.html#async-service-activator"}},[e._v("Asynchronous Service Activator")]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"messaging-annotation-support-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#messaging-annotation-support-changes"}},[e._v("#")]),e._v(" Messaging Annotation Support changes")]),e._v(" "),n("p",[e._v("The messaging annotation support does not require a "),n("code",[e._v("@MessageEndpoint")]),e._v(" (or any other "),n("code",[e._v("@Component")]),e._v(") annotation declaration on the class level.\nTo restore the previous behavior, set the "),n("code",[e._v("spring.integration.messagingAnnotations.require.componentAnnotation")]),e._v(" of"),n("code",[e._v("spring.integration.properties")]),e._v(" to "),n("code",[e._v("true")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/configuration.html#global-properties"}},[e._v("Global Properties")]),e._v(" and "),n("RouterLink",{attrs:{to:"/en/spring-integration/configuration.html#annotations"}},[e._v("Annotation Support")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"mail-changes-4"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#mail-changes-4"}},[e._v("#")]),e._v(" Mail Changes")]),e._v(" "),n("p",[e._v("This section describes general changes to the Spring Integration Mail functionality.")]),e._v(" "),n("h6",{attrs:{id:"customizable-user-flag"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#customizable-user-flag"}},[e._v("#")]),e._v(" Customizable User Flag")]),e._v(" "),n("p",[e._v("The customizable "),n("code",[e._v("userFlag")]),e._v(" (added in 4.2.2 to provide customization of the flag used to denote that the mail has been\nseen) is now available in the XML namespace.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/mail.html#imap-seen"}},[e._v("Marking IMAP Messages When "),n("code",[e._v("\\Recent")]),e._v(" Is Not Supported")]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"mail-message-mapping"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#mail-message-mapping"}},[e._v("#")]),e._v(" Mail Message Mapping")]),e._v(" "),n("p",[e._v("You can now map inbound mail messages with the "),n("code",[e._v("MessageHeaders")]),e._v(" containing the mail headers and the payload containing the email content.\nPreviously, the payload was always the raw "),n("code",[e._v("MimeMessage")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/mail.html#mail-mapping"}},[e._v("Inbound Mail Message Mapping")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"jms-changes-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#jms-changes-2"}},[e._v("#")]),e._v(" JMS Changes")]),e._v(" "),n("p",[e._v("This section describes general changes to the Spring Integration JMS functionality.")]),e._v(" "),n("h6",{attrs:{id:"header-mapper"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#header-mapper"}},[e._v("#")]),e._v(" Header Mapper")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("DefaultJmsHeaderMapper")]),e._v(" now maps the standard "),n("code",[e._v("correlationId")]),e._v(" header as a message property by invoking its "),n("code",[e._v("toString()")]),e._v(" method.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/jms.html#jms-header-mapping"}},[e._v("Mapping Message Headers to and from JMS Message")]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"asynchronous-gateway"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#asynchronous-gateway"}},[e._v("#")]),e._v(" Asynchronous Gateway")]),e._v(" "),n("p",[e._v("The JMS outbound gateway now has an "),n("code",[e._v("async")]),e._v(" property.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/jms.html#jms-async-gateway"}},[e._v("Async Gateway")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"aggregator-changes-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#aggregator-changes-2"}},[e._v("#")]),e._v(" Aggregator Changes")]),e._v(" "),n("p",[e._v("There is a change in behavior when a POJO aggregator releases a collection of "),n("code",[e._v("Message")]),e._v(" objects.\nThis is rare, but, if your application does that, you need to make a small change to your POJO.\nSee this "),n("RouterLink",{attrs:{to:"/en/spring-integration/aggregator.html#agg-message-collection"}},[e._v("IMPORTANT: The "),n("code",[e._v("SimpleMessageGroup.getMessages()")]),e._v(" method returns an "),n("code",[e._v("unmodifiableCollection")]),e._v(".")]),e._v(" note for more information.")],1),e._v(" "),n("h5",{attrs:{id:"tcp-udp-changes-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#tcp-udp-changes-2"}},[e._v("#")]),e._v(" TCP/UDP Changes")]),e._v(" "),n("p",[e._v("This section describes general changes to the Spring Integration TCP/UDP functionality.")]),e._v(" "),n("h6",{attrs:{id:"events"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#events"}},[e._v("#")]),e._v(" Events")]),e._v(" "),n("p",[e._v("A new "),n("code",[e._v("TcpConnectionServerListeningEvent")]),e._v(" is emitted when a server connection factory is started.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ip.html#tcp-events"}},[e._v("TCP Connection Events")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("You can now use the "),n("code",[e._v("destination-expression")]),e._v(" and "),n("code",[e._v("socket-expression")]),e._v(" attributes on "),n("code",[e._v("")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ip.html#udp-adapters"}},[e._v("UDP Adapters")]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"stream-deserializers"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#stream-deserializers"}},[e._v("#")]),e._v(" Stream Deserializers")]),e._v(" "),n("p",[e._v("The various deserializers that cannot allocate the final buffer until the whole message has been assembled now support pooling the raw buffer into which the data is received rather than creating and discarding a buffer for each message.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ip.html#tcp-connection-factories"}},[e._v("TCP Connection Factories")]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"tcp-message-mapper"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#tcp-message-mapper"}},[e._v("#")]),e._v(" TCP Message Mapper")]),e._v(" "),n("p",[e._v("The message mapper now, optionally, sets a configured content type header.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ip.html#ip-msg-headers"}},[e._v("IP Message Headers")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"file-changes-4"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#file-changes-4"}},[e._v("#")]),e._v(" File Changes")]),e._v(" "),n("p",[e._v("This section describes general changes to the Spring Integration File functionality.")]),e._v(" "),n("h6",{attrs:{id:"destination-directory-creation"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#destination-directory-creation"}},[e._v("#")]),e._v(" Destination Directory Creation")]),e._v(" "),n("p",[e._v("The generated file name for the "),n("code",[e._v("FileWritingMessageHandler")]),e._v(" can represent a sub-path to save the desired directory structure for a file in the target directory.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/file.html#file-writing-file-names"}},[e._v("Generating File Names")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("The "),n("code",[e._v("FileReadingMessageSource")]),e._v(" now hides the "),n("code",[e._v("WatchService")]),e._v(" directory scanning logic in the inner class.\nWe added the "),n("code",[e._v("use-watch-service")]),e._v(" and "),n("code",[e._v("watch-events")]),e._v(" options to enable this behavior.\nWe deprecated the top-level "),n("code",[e._v("WatchServiceDirectoryScanner")]),e._v(" because of inconsistency around the API.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/file.html#watch-service-directory-scanner"}},[n("code",[e._v("WatchServiceDirectoryScanner")])]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"buffer-size"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#buffer-size"}},[e._v("#")]),e._v(" Buffer Size")]),e._v(" "),n("p",[e._v("When writing files, you can now specify the buffer size.")]),e._v(" "),n("h6",{attrs:{id:"appending-and-flushing"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#appending-and-flushing"}},[e._v("#")]),e._v(" Appending and Flushing")]),e._v(" "),n("p",[e._v("You can now avoid flushing files when appending and use a number of strategies to flush the data during idle periods.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/file.html#file-flushing"}},[e._v("Flushing Files When Using "),n("code",[e._v("APPEND_NO_FLUSH")])]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"preserving-timestamps"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#preserving-timestamps"}},[e._v("#")]),e._v(" Preserving Timestamps")]),e._v(" "),n("p",[e._v("You can now configure the outbound channel adapter to set the destination file’s "),n("code",[e._v("lastmodified")]),e._v(" timestamp.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/file.html#file-timestamps"}},[e._v("File Timestamps")]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"splitter-changes-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#splitter-changes-2"}},[e._v("#")]),e._v(" Splitter Changes")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("FileSplitter")]),e._v(" now automatically closes an FTP or SFTP session when the file is completely read.\nThis applies when the outbound gateway returns an "),n("code",[e._v("InputStream")]),e._v(" or when you use the new FTP or SFTP streaming channel adapters.\nWe also introduced a new "),n("code",[e._v("markers-json")]),e._v(" option to convert "),n("code",[e._v("FileSplitter.FileMarker")]),e._v(" to JSON "),n("code",[e._v("String")]),e._v(" for relaxed downstream network interaction.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/file.html#file-splitter"}},[e._v("File Splitter")]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"file-filters"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#file-filters"}},[e._v("#")]),e._v(" File Filters")]),e._v(" "),n("p",[e._v("We added "),n("code",[e._v("ChainFileListFilter")]),e._v(" as an alternative to "),n("code",[e._v("CompositeFileListFilter")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/file.html#file-reading"}},[e._v("Reading Files")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"amqp-changes-6"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#amqp-changes-6"}},[e._v("#")]),e._v(" AMQP Changes")]),e._v(" "),n("p",[e._v("This section describes general changes to the Spring Integration AMQP functionality.")]),e._v(" "),n("h6",{attrs:{id:"content-type-message-converter"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#content-type-message-converter"}},[e._v("#")]),e._v(" Content Type Message Converter")]),e._v(" "),n("p",[e._v("The outbound endpoints now support a "),n("code",[e._v("RabbitTemplate")]),e._v(" configured with a "),n("code",[e._v("ContentTypeDelegatingMessageConverter")]),e._v(" such\nthat you can choose the converter based on the message content type.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/amqp.html#content-type-conversion-outbound"}},[e._v("Outbound Message Conversion")]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"headers-for-delayed-message-handling"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#headers-for-delayed-message-handling"}},[e._v("#")]),e._v(" Headers for Delayed Message Handling")]),e._v(" "),n("p",[e._v("Spring AMQP 1.6 adds support for "),n("a",{attrs:{href:"https://www.rabbitmq.com/blog/2015/04/16/scheduling-messages-with-rabbitmq/",target:"_blank",rel:"noopener noreferrer"}},[e._v("delayed message exchanges"),n("OutboundLink")],1),e._v(".\nHeader mapping now supports the headers ("),n("code",[e._v("amqp_delay")]),e._v(" and "),n("code",[e._v("amqp_receivedDelay")]),e._v(") used by this feature.")]),e._v(" "),n("h6",{attrs:{id:"amqp-backed-channels"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#amqp-backed-channels"}},[e._v("#")]),e._v(" AMQP-Backed Channels")]),e._v(" "),n("p",[e._v("AMQP-backed channels now support message mapping.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/amqp.html#amqp-channels"}},[e._v("AMQP-backed Message Channels")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"redis-changes-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#redis-changes-2"}},[e._v("#")]),e._v(" Redis Changes")]),e._v(" "),n("p",[e._v("This section describes general changes to the Spring Integration Redis functionality.")]),e._v(" "),n("h6",{attrs:{id:"list-push-pop-direction"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#list-push-pop-direction"}},[e._v("#")]),e._v(" List Push/Pop Direction")]),e._v(" "),n("p",[e._v("Previously, the queue channel adapters always used the Redis list in a fixed direction, pushing to the left end and reading from the right end.\nYou can now configure the reading and writing direction with the "),n("code",[e._v("rightPop")]),e._v(" and "),n("code",[e._v("leftPush")]),e._v(" options for the"),n("code",[e._v("RedisQueueMessageDrivenEndpoint")]),e._v(" and "),n("code",[e._v("RedisQueueOutboundChannelAdapter")]),e._v(", respectively.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/redis.html#redis-queue-inbound-channel-adapter"}},[e._v("Redis Queue Inbound Channel Adapter")]),e._v(" and "),n("RouterLink",{attrs:{to:"/en/spring-integration/redis.html#redis-queue-outbound-channel-adapter"}},[e._v("Redis Queue Outbound Channel Adapter")]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"queue-inbound-gateway-default-serializer"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#queue-inbound-gateway-default-serializer"}},[e._v("#")]),e._v(" Queue Inbound Gateway Default Serializer")]),e._v(" "),n("p",[e._v("The default serializer in the inbound gateway has been changed to a "),n("code",[e._v("JdkSerializationRedisSerializer")]),e._v(" for compatibility with the outbound gateway.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/redis.html#redis-queue-inbound-gateway"}},[e._v("Redis Queue Inbound Gateway")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"http-changes-4"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#http-changes-4"}},[e._v("#")]),e._v(" HTTP Changes")]),e._v(" "),n("p",[e._v("Previously, with requests that had a body (such as "),n("code",[e._v("POST")]),e._v(") that had no "),n("code",[e._v("content-type")]),e._v(" header, the body was ignored.\nWith this release, the content type of such requests is considered to be "),n("code",[e._v("application/octet-stream")]),e._v(" as recommended\nby RFC 2616.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/http.html#http-inbound"}},[e._v("Http Inbound Components")]),e._v(" for more information.")],1),e._v(" "),n("p",[n("code",[e._v("uriVariablesExpression")]),e._v(" now uses a "),n("code",[e._v("SimpleEvaluationContext")]),e._v(" by default (since 4.3.15).\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/http.html#mapping-uri-variables"}},[e._v("Mapping URI Variables")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"sftp-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#sftp-changes"}},[e._v("#")]),e._v(" SFTP Changes")]),e._v(" "),n("p",[e._v("This section describes general changes to the Spring Integration SFTP functionality.")]),e._v(" "),n("h6",{attrs:{id:"factory-bean"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#factory-bean"}},[e._v("#")]),e._v(" Factory Bean")]),e._v(" "),n("p",[e._v("We added a new factory bean to simplify the configuration of Jsch proxies for SFTP.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/sftp.html#sftp-proxy-factory-bean"}},[e._v("Proxy Factory Bean")]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"chmod-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#chmod-changes"}},[e._v("#")]),e._v(" "),n("code",[e._v("chmod")]),e._v(" Changes")]),e._v(" "),n("p",[e._v("The SFTP outbound gateway (for "),n("code",[e._v("put")]),e._v(" and "),n("code",[e._v("mput")]),e._v(" commands) and the SFTP outbound channel adapter now support the "),n("code",[e._v("chmod")]),e._v(" attribute to change the remote file permissions after uploading.\nSee "),n("code",[e._v("[SFTP Outbound Channel Adapter](./sftp.html#sftp-outbound)")]),e._v(" and "),n("code",[e._v("[SFTP Outbound Gateway](./sftp.html#sftp-outbound-gateway)")]),e._v(" for more information.")]),e._v(" "),n("h5",{attrs:{id:"ftp-changes-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#ftp-changes-2"}},[e._v("#")]),e._v(" FTP Changes")]),e._v(" "),n("p",[e._v("This section describes general changes to the Spring Integration FTP functionality.")]),e._v(" "),n("h6",{attrs:{id:"session-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#session-changes"}},[e._v("#")]),e._v(" Session Changes")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("FtpSession")]),e._v(" now supports "),n("code",[e._v("null")]),e._v(" for the "),n("code",[e._v("list()")]),e._v(" and "),n("code",[e._v("listNames()")]),e._v(" methods, since underlying FTP Client can use it.\nWith that, you can now configure the "),n("code",[e._v("FtpOutboundGateway")]),e._v(" without the "),n("code",[e._v("remoteDirectory")]),e._v(" expression.\nYou can also configure the "),n("code",[e._v("")]),e._v(" without "),n("code",[e._v("remote-directory")]),e._v(" or "),n("code",[e._v("remote-directory-expression")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ftp.html#ftp"}},[e._v("FTP/FTPS Adapters")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"router-changes-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#router-changes-2"}},[e._v("#")]),e._v(" Router Changes")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("ErrorMessageExceptionTypeRouter")]),e._v(" now supports the "),n("code",[e._v("Exception")]),e._v(" superclass mappings to avoid duplication for the same channel in case of multiple inheritors.\nFor this purpose, the "),n("code",[e._v("ErrorMessageExceptionTypeRouter")]),e._v(" loads mapping classes during initialization to fail-fast for a "),n("code",[e._v("ClassNotFoundException")]),e._v(".")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/router.html#router"}},[e._v("Routers")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"header-mapping"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#header-mapping"}},[e._v("#")]),e._v(" Header Mapping")]),e._v(" "),n("p",[e._v("This section describes the changes to header mapping between version 4.2 and 4.3.")]),e._v(" "),n("h6",{attrs:{id:"general"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#general"}},[e._v("#")]),e._v(" General")]),e._v(" "),n("p",[e._v("AMQP, WS, and XMPP header mappings (such as "),n("code",[e._v("request-header-mapping")]),e._v(" and "),n("code",[e._v("reply-header-mapping")]),e._v(") now support negated patterns.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/amqp.html#amqp-message-headers"}},[e._v("AMQP Message Headers")]),e._v(", "),n("RouterLink",{attrs:{to:"/en/spring-integration/ws.html#ws-message-headers"}},[e._v("WS Message Headers")]),e._v(", and "),n("RouterLink",{attrs:{to:"/en/spring-integration/xmpp.html#xmpp-message-headers"}},[e._v("XMPP Message Headers")]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"amqp-header-mapping"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#amqp-header-mapping"}},[e._v("#")]),e._v(" AMQP Header Mapping")]),e._v(" "),n("p",[e._v("Previously, only standard AMQP headers were mapped by default.\nYou had to explicitly enable mapping of user-defined headers.\nWith this release, all headers are mapped by default.\nIn addition, the inbound "),n("code",[e._v("amqp_deliveryMode")]),e._v(" header is no longer mapped by default.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/amqp.html#amqp-message-headers"}},[e._v("AMQP Message Headers")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"groovy-scripts"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#groovy-scripts"}},[e._v("#")]),e._v(" Groovy Scripts")]),e._v(" "),n("p",[e._v("You can now configure groovy scripts with the "),n("code",[e._v("compile-static")]),e._v(" hint or any other "),n("code",[e._v("CompilerConfiguration")]),e._v(" options.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/groovy.html#groovy-config"}},[e._v("Groovy Configuration")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"inboundchanneladapter-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#inboundchanneladapter-changes"}},[e._v("#")]),e._v(" "),n("code",[e._v("@InboundChannelAdapter")]),e._v(" Changes")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("@InboundChannelAdapter")]),e._v(" now has an alias "),n("code",[e._v("channel")]),e._v(" attribute for the regular "),n("code",[e._v("value")]),e._v(".\nIn addition, the target "),n("code",[e._v("SourcePollingChannelAdapter")]),e._v(" components can now resolve the target "),n("code",[e._v("outputChannel")]),e._v(" bean from its provided name ("),n("code",[e._v("outputChannelName")]),e._v(" options) in a late-binding manner.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/configuration.html#annotations"}},[e._v("Annotation Support")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"xmpp-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#xmpp-changes"}},[e._v("#")]),e._v(" XMPP Changes")]),e._v(" "),n("p",[e._v("The XMPP channel adapters now support the XMPP Extensions (XEP).\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/xmpp.html#xmpp-extensions"}},[e._v("XMPP Extensions")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"wiretap-late-binding"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#wiretap-late-binding"}},[e._v("#")]),e._v(" WireTap Late Binding")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("WireTap")]),e._v(" "),n("code",[e._v("ChannelInterceptor")]),e._v(" now can accept a "),n("code",[e._v("channelName")]),e._v(" that is resolved to the target "),n("code",[e._v("MessageChannel")]),e._v("later, during the first active interceptor operation.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/channel.html#channel-wiretap"}},[e._v("Wire Tap")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"channelmessagestorequeryprovider-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#channelmessagestorequeryprovider-changes"}},[e._v("#")]),e._v(" "),n("code",[e._v("ChannelMessageStoreQueryProvider")]),e._v(" Changes")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("ChannelMessageStoreQueryProvider")]),e._v(" now supports H2 databases.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/jdbc.html#jdbc-message-store-channels"}},[e._v("Backing Message Channels")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"websocket-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#websocket-changes"}},[e._v("#")]),e._v(" WebSocket Changes")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("ServerWebSocketContainer")]),e._v(" now exposes an "),n("code",[e._v("allowedOrigins")]),e._v(" option, and "),n("code",[e._v("SockJsServiceOptions")]),e._v(" exposes a "),n("code",[e._v("suppressCors")]),e._v(" option.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/web-sockets.html#web-sockets"}},[e._v("WebSockets Support")]),e._v(" for more information.")],1),e._v(" "),n("h3",{attrs:{id:"changes-between-4-1-and-4-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#changes-between-4-1-and-4-2"}},[e._v("#")]),e._v(" Changes between 4.1 and 4.2")]),e._v(" "),n("p",[e._v("See the "),n("a",{attrs:{href:"https://github.com/spring-projects/spring-integration/wiki/Spring-Integration-4.1-to-4.2-Migration-Guide",target:"_blank",rel:"noopener noreferrer"}},[e._v("Migration Guide"),n("OutboundLink")],1),e._v(" for important changes that might affect your applications.\nYou can find migration guides for all versions back to 2.1 on the "),n("a",{attrs:{href:"https://github.com/spring-projects/spring-integration/wiki",target:"_blank",rel:"noopener noreferrer"}},[e._v("wiki"),n("OutboundLink")],1),e._v(".")]),e._v(" "),n("h4",{attrs:{id:"new-components-7"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#new-components-7"}},[e._v("#")]),e._v(" New Components")]),e._v(" "),n("p",[e._v("Version 4.2 added a number of new components.")]),e._v(" "),n("h5",{attrs:{id:"major-management-jmx-rework"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#major-management-jmx-rework"}},[e._v("#")]),e._v(" Major Management/JMX Rework")]),e._v(" "),n("p",[e._v("We added a new "),n("code",[e._v("MetricsFactory")]),e._v(" strategy interface.\nThis change, together with other changes in the JMX and management infrastructure, provides much more control over management configuration and runtime performance.")]),e._v(" "),n("p",[e._v("However, this has some important implications for (some) user environments.")]),e._v(" "),n("p",[e._v("For complete details, see "),n("RouterLink",{attrs:{to:"/en/spring-integration/metrics.html#metrics-management"}},[e._v("Metrics and Management")]),e._v(" and "),n("RouterLink",{attrs:{to:"/en/spring-integration/jmx.html#jmx-42-improvements"}},[e._v("JMX Improvements")]),e._v(".")],1),e._v(" "),n("h5",{attrs:{id:"mongodb-metadata-store"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#mongodb-metadata-store"}},[e._v("#")]),e._v(" MongoDB Metadata Store")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("MongoDbMetadataStore")]),e._v(" is now available.\nFor more information, see "),n("RouterLink",{attrs:{to:"/en/spring-integration/mongodb.html#mongodb-metadata-store"}},[e._v("MongoDB Metadata Store")]),e._v(".")],1),e._v(" "),n("h5",{attrs:{id:"securedchannel-annotation"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#securedchannel-annotation"}},[e._v("#")]),e._v(" SecuredChannel Annotation")]),e._v(" "),n("p",[e._v("We introduced the "),n("code",[e._v("@SecuredChannel")]),e._v(" annotation, replacing the deprecated "),n("code",[e._v("ChannelSecurityInterceptorFactoryBean")]),e._v(".\nFor more information, see "),n("RouterLink",{attrs:{to:"/en/spring-integration/security.html#security"}},[e._v("Security in Spring Integration")]),e._v(".")],1),e._v(" "),n("h5",{attrs:{id:"securitycontext-propagation"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#securitycontext-propagation"}},[e._v("#")]),e._v(" "),n("code",[e._v("SecurityContext")]),e._v(" Propagation")]),e._v(" "),n("p",[e._v("We introduced the "),n("code",[e._v("SecurityContextPropagationChannelInterceptor")]),e._v(" for the "),n("code",[e._v("SecurityContext")]),e._v(" propagation from one message flow’s thread to another.\nFor more information, see "),n("RouterLink",{attrs:{to:"/en/spring-integration/security.html#security"}},[e._v("Security in Spring Integration")]),e._v(".")],1),e._v(" "),n("h5",{attrs:{id:"filesplitter"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#filesplitter"}},[e._v("#")]),e._v(" FileSplitter")]),e._v(" "),n("p",[e._v("In 4.1.2, we added "),n("code",[e._v("FileSplitter")]),e._v(", which splits text files into lines.\nIt now has full support in the "),n("code",[e._v("int-file:")]),e._v(" namespace.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/file.html#file-splitter"}},[e._v("File Splitter")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"zookeeper-support"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#zookeeper-support"}},[e._v("#")]),e._v(" Zookeeper Support")]),e._v(" "),n("p",[e._v("We added Zookeeper support to the framework to assist when running on a clustered or multi-host environment.\nThe change impacts the following features:")]),e._v(" "),n("ul",[n("li",[n("p",[n("code",[e._v("ZookeeperMetadataStore")])])]),e._v(" "),n("li",[n("p",[n("code",[e._v("ZookeeperLockRegistry")])])]),e._v(" "),n("li",[n("p",[e._v("Zookeeper Leadership")])])]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/zookeeper.html#zookeeper"}},[e._v("Zookeeper Support")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"thread-barrier"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#thread-barrier"}},[e._v("#")]),e._v(" Thread Barrier")]),e._v(" "),n("p",[e._v("A new thread "),n("code",[e._v("")]),e._v(" component is available, letting a thread be suspended until some asynchronous event occurs.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/barrier.html#barrier"}},[e._v("Thread Barrier")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"stomp-support"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#stomp-support"}},[e._v("#")]),e._v(" STOMP Support")]),e._v(" "),n("p",[e._v("We added STOMP support to the framework as an inbound and outbound channel adapters pair.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/stomp.html#stomp"}},[e._v("STOMP Support")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"codec"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#codec"}},[e._v("#")]),e._v(" Codec")]),e._v(" "),n("p",[e._v("A new "),n("code",[e._v("Codec")]),e._v(" abstraction has been introduced, to encode and decode objects to and from "),n("code",[e._v("byte[]")]),e._v(".\nWe added an implementation that uses Kryo.\nWe also added codec-based transformers and message converters.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/codec.html#codec"}},[e._v("Codec")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"message-preparedstatement-setter"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#message-preparedstatement-setter"}},[e._v("#")]),e._v(" Message PreparedStatement Setter")]),e._v(" "),n("p",[e._v("A new "),n("code",[e._v("MessagePreparedStatementSetter")]),e._v(" functional interface callback is available for the "),n("code",[e._v("JdbcMessageHandler")]),e._v(" ("),n("code",[e._v("")]),e._v(" and "),n("code",[e._v("")]),e._v(") as an alternative to using "),n("code",[e._v("SqlParameterSourceFactory")]),e._v(" to populate parameters on the "),n("code",[e._v("PreparedStatement")]),e._v(" with the "),n("code",[e._v("requestMessage")]),e._v(" context.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/jdbc.html#jdbc-outbound-channel-adapter"}},[e._v("Outbound Channel Adapter")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"general-changes-7"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#general-changes-7"}},[e._v("#")]),e._v(" General Changes")]),e._v(" "),n("p",[e._v("This section describes general changes from version 4.1 to version 4.2.")]),e._v(" "),n("h5",{attrs:{id:"wiretap"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#wiretap"}},[e._v("#")]),e._v(" WireTap")]),e._v(" "),n("p",[e._v("As an alternative to the existing "),n("code",[e._v("selector")]),e._v(" attribute, the "),n("code",[e._v("")]),e._v(" element now supports the "),n("code",[e._v("selector-expression")]),e._v(" attribute.")]),e._v(" "),n("h5",{attrs:{id:"file-changes-5"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#file-changes-5"}},[e._v("#")]),e._v(" File Changes")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/file.html#files"}},[e._v("File Support")]),e._v(" for more information about these changes.")],1),e._v(" "),n("h6",{attrs:{id:"appending-new-lines"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#appending-new-lines"}},[e._v("#")]),e._v(" Appending New Lines")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("")]),e._v(" and "),n("code",[e._v("")]),e._v(" now support an "),n("code",[e._v("append-new-line")]),e._v(" attribute.\nIf set to "),n("code",[e._v("true")]),e._v(", a new line is appended to the file after a message is written.\nThe default attribute value is "),n("code",[e._v("false")]),e._v(".")]),e._v(" "),n("h6",{attrs:{id:"ignoring-hidden-files"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#ignoring-hidden-files"}},[e._v("#")]),e._v(" Ignoring Hidden Files")]),e._v(" "),n("p",[e._v("We added the "),n("code",[e._v("ignore-hidden")]),e._v(" attribute for the "),n("code",[e._v("")]),e._v(" to let you set whether to pick up hidden files from the source directory.\nIt defaults to "),n("code",[e._v("true")]),e._v(".")]),e._v(" "),n("h6",{attrs:{id:"writing-inputstream-payloads"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#writing-inputstream-payloads"}},[e._v("#")]),e._v(" Writing "),n("code",[e._v("InputStream")]),e._v(" Payloads")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("FileWritingMessageHandler")]),e._v(" now also accepts "),n("code",[e._v("InputStream")]),e._v(" as a valid message payload type.")]),e._v(" "),n("h6",{attrs:{id:"headdirectoryscanner"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#headdirectoryscanner"}},[e._v("#")]),e._v(" "),n("code",[e._v("HeadDirectoryScanner")])]),e._v(" "),n("p",[e._v("You can now use the "),n("code",[e._v("HeadDirectoryScanner")]),e._v(" with other "),n("code",[e._v("FileListFilter")]),e._v(" implementations.")]),e._v(" "),n("h6",{attrs:{id:"last-modified-filter"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#last-modified-filter"}},[e._v("#")]),e._v(" Last Modified Filter")]),e._v(" "),n("p",[e._v("We added the "),n("code",[e._v("LastModifiedFileListFilter")]),e._v(".")]),e._v(" "),n("h6",{attrs:{id:"watch-service-directory-scanner"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#watch-service-directory-scanner"}},[e._v("#")]),e._v(" Watch Service Directory Scanner")]),e._v(" "),n("p",[e._v("We added the "),n("code",[e._v("WatchServiceDirectoryScanner")]),e._v(".")]),e._v(" "),n("h6",{attrs:{id:"persistent-file-list-filter-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#persistent-file-list-filter-changes"}},[e._v("#")]),e._v(" Persistent File List Filter Changes")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("AbstractPersistentFileListFilter")]),e._v(" has a new property ("),n("code",[e._v("flushOnUpdate")]),e._v(") which, when set to "),n("code",[e._v("true")]),e._v(", calls "),n("code",[e._v("flush()")]),e._v(" on the metadata store if it implements "),n("code",[e._v("Flushable")]),e._v(" (for example, "),n("code",[e._v("PropertiesPersistingMetadataStore")]),e._v(").")]),e._v(" "),n("h5",{attrs:{id:"class-package-change"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#class-package-change"}},[e._v("#")]),e._v(" Class Package Change")]),e._v(" "),n("p",[e._v("We moved the "),n("code",[e._v("ScatterGatherHandler")]),e._v(" class from the "),n("code",[e._v("org.springframework.integration.handler")]),e._v(" to the "),n("code",[e._v("org.springframework.integration.scattergather")]),e._v(".")]),e._v(" "),n("h5",{attrs:{id:"tcp-changes-4"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#tcp-changes-4"}},[e._v("#")]),e._v(" TCP Changes")]),e._v(" "),n("p",[e._v("This section describes general changes to the Spring Integration TCP functionality.")]),e._v(" "),n("h6",{attrs:{id:"tcp-serializers"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#tcp-serializers"}},[e._v("#")]),e._v(" TCP Serializers")]),e._v(" "),n("p",[e._v("The TCP "),n("code",[e._v("Serializers")]),e._v(" no longer "),n("code",[e._v("flush()")]),e._v(" the "),n("code",[e._v("OutputStream")]),e._v(".\nThis is now done by the "),n("code",[e._v("TcpNxxConnection")]),e._v(" classes.\nIf you use the serializers directly within your code, you may have to "),n("code",[e._v("flush()")]),e._v(" the "),n("code",[e._v("OutputStream")]),e._v(".")]),e._v(" "),n("h6",{attrs:{id:"server-socket-exceptions"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#server-socket-exceptions"}},[e._v("#")]),e._v(" Server Socket Exceptions")]),e._v(" "),n("p",[n("code",[e._v("TcpConnectionServerExceptionEvent")]),e._v(" instances are now published whenever an unexpected exception occurs on a TCP server socket (also added to 4.1.3 and 4.0.7).\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ip.html#tcp-events"}},[e._v("TCP Connection Events")]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"tcp-server-port"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#tcp-server-port"}},[e._v("#")]),e._v(" TCP Server Port")]),e._v(" "),n("p",[e._v("If you configure a TCP server socket factory to listen on a random port, you can now obtain the actual port chosen by the OS by using "),n("code",[e._v("getPort()")]),e._v("."),n("code",[e._v("getServerSocketAddress()")]),e._v(" is also available.")]),e._v(" "),n("p",[e._v('See "'),n("RouterLink",{attrs:{to:"/en/spring-integration/ip.html#tcp-connection-factories"}},[e._v("TCP Connection Factories")]),e._v('" for more information.')],1),e._v(" "),n("h6",{attrs:{id:"tcp-gateway-remote-timeout"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#tcp-gateway-remote-timeout"}},[e._v("#")]),e._v(" TCP Gateway Remote Timeout")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("TcpOutboundGateway")]),e._v(" now supports "),n("code",[e._v("remote-timeout-expression")]),e._v(" as an alternative to the existing "),n("code",[e._v("remote-timeout")]),e._v(" attribute.\nThis allows setting the timeout based on each message.")]),e._v(" "),n("p",[e._v("Also, the "),n("code",[e._v("remote-timeout")]),e._v(" no longer defaults to the same value as "),n("code",[e._v("reply-timeout")]),e._v(", which has a completely different meaning.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/ip.html#tcp-ob-gateway-attributes"}},[e._v(".TCP Outbound Gateway Attributes")]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"tcp-sslsession-available-for-header-mapping"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#tcp-sslsession-available-for-header-mapping"}},[e._v("#")]),e._v(" TCP SSLSession Available for Header Mapping")]),e._v(" "),n("p",[n("code",[e._v("TcpConnection")]),e._v(" implementations now support "),n("code",[e._v("getSslSession()")]),e._v(" to let you extract information from the session to add to message headers.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ip.html#ip-msg-headers"}},[e._v("IP Message Headers")]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"tcp-events"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#tcp-events"}},[e._v("#")]),e._v(" TCP Events")]),e._v(" "),n("p",[e._v("New events are now published whenever a correlation exception occurs — such as sending a message to a non-existent socket.")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("TcpConnectionEventListeningMessageProducer")]),e._v(" is deprecated.\nUse the generic event adapter instead.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/ip.html#tcp-events"}},[e._v("TCP Connection Events")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"inboundchanneladapter-changes-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#inboundchanneladapter-changes-2"}},[e._v("#")]),e._v(" "),n("code",[e._v("@InboundChannelAdapter")]),e._v(" Changes")]),e._v(" "),n("p",[e._v("Previously, the "),n("code",[e._v("@Poller")]),e._v(" on an inbound channel adapter defaulted the "),n("code",[e._v("maxMessagesPerPoll")]),e._v(" attribute to "),n("code",[e._v("-1")]),e._v(" (infinity).\nThis was inconsistent with the XML configuration of "),n("code",[e._v("")]),e._v(", which defaults to "),n("code",[e._v("1")]),e._v(".\nThe annotation now defaults this attribute to "),n("code",[e._v("1")]),e._v(".")]),e._v(" "),n("h5",{attrs:{id:"api-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#api-changes"}},[e._v("#")]),e._v(" API Changes")]),e._v(" "),n("p",[n("code",[e._v("o.s.integration.util.FunctionIterator")]),e._v(" now requires a "),n("code",[e._v("o.s.integration.util.Function")]),e._v(" instead of a "),n("code",[e._v("reactor.function.Function")]),e._v(".\nThis was done to remove an unnecessary hard dependency on Reactor.\nAny uses of this iterator need to change the import.")]),e._v(" "),n("p",[e._v("Reactor is still supported for functionality such as the "),n("code",[e._v("Promise")]),e._v(" gateway.\nThe dependency was removed for those users who do not need it.")]),e._v(" "),n("h5",{attrs:{id:"jms-changes-3"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#jms-changes-3"}},[e._v("#")]),e._v(" JMS Changes")]),e._v(" "),n("p",[e._v("This section describes general changes to the Spring Integration TCP functionality.")]),e._v(" "),n("h6",{attrs:{id:"reply-listener-lazy-initialization"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#reply-listener-lazy-initialization"}},[e._v("#")]),e._v(" Reply Listener Lazy Initialization")]),e._v(" "),n("p",[e._v("You can now configure the reply listener in JMS outbound gateways to be initialized on-demand and stopped after an idle period, instead of being controlled by the gateway’s lifecycle.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/jms.html#jms-outbound-gateway"}},[e._v("Outbound Gateway")]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"conversion-errors-in-message-driven-endpoints"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#conversion-errors-in-message-driven-endpoints"}},[e._v("#")]),e._v(" Conversion Errors in Message-Driven Endpoints")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("error-channel")]),e._v(" is now used for the conversion errors.\nIn previous versions, they caused transaction rollback and message redelivery.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/jms.html#jms-message-driven-channel-adapter"}},[e._v("Message-driven Channel Adapter")]),e._v(" and "),n("RouterLink",{attrs:{to:"/en/spring-integration/jms.html#jms-inbound-gateway"}},[e._v("Inbound Gateway")]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"default-acknowledge-mode"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#default-acknowledge-mode"}},[e._v("#")]),e._v(" Default Acknowledge Mode")]),e._v(" "),n("p",[e._v("When using an implicitly defined "),n("code",[e._v("DefaultMessageListenerContainer")]),e._v(", the default "),n("code",[e._v("acknowledge")]),e._v(" is now "),n("code",[e._v("transacted")]),e._v(".\nWe recommend using "),n("code",[e._v("transacted")]),e._v(" when using this container, to avoid message loss.\nThis default now applies to the message-driven inbound adapter and the inbound gateway.\nIt was already the default for JMS-backed channels.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/jms.html#jms-message-driven-channel-adapter"}},[e._v("Message-driven Channel Adapter")]),e._v(" and "),n("RouterLink",{attrs:{to:"/en/spring-integration/jms.html#jms-inbound-gateway"}},[e._v("Inbound Gateway")]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"shared-subscriptions"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#shared-subscriptions"}},[e._v("#")]),e._v(" Shared Subscriptions")]),e._v(" "),n("p",[e._v("We added Namespace support for shared subscriptions (JMS 2.0) to message-driven endpoints and the "),n("code",[e._v("")]),e._v(".\nPreviously, you had to wire up listener containers as "),n("code",[e._v("")]),e._v(" declarations to use shared connections.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/jms.html#jms"}},[e._v("JMS Support")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"conditional-pollers"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#conditional-pollers"}},[e._v("#")]),e._v(" Conditional Pollers")]),e._v(" "),n("p",[e._v("We now provide much more flexibility for dynamic polling.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/polling-consumer.html#conditional-pollers"}},[e._v("Conditional Pollers for Message Sources")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"amqp-changes-7"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#amqp-changes-7"}},[e._v("#")]),e._v(" AMQP Changes")]),e._v(" "),n("p",[e._v("This section describes general changes to the Spring Integration AMQP functionality.")]),e._v(" "),n("h6",{attrs:{id:"publisher-confirmations"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#publisher-confirmations"}},[e._v("#")]),e._v(" Publisher Confirmations")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("")]),e._v(" now supports "),n("code",[e._v("confirm-correlation-expression")]),e._v(", "),n("code",[e._v("confirm-ack-channel")]),e._v(", and "),n("code",[e._v("confirm-nack-channel")]),e._v(" attributes (which have a purpose similar to that of "),n("code",[e._v("")]),e._v(").")]),e._v(" "),n("h6",{attrs:{id:"correlation-data"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#correlation-data"}},[e._v("#")]),e._v(" Correlation Data")]),e._v(" "),n("p",[e._v("For both the outbound channel adapter and the inbound gateway, if the correlation data is a "),n("code",[e._v("Message")]),e._v(", it becomes the basis of the message on the ack or nack channel, with the additional header(s) added.\nPreviously, any correlation data (including "),n("code",[e._v("Message")]),e._v(") was returned as the payload of the ack or nack message.")]),e._v(" "),n("h6",{attrs:{id:"inbound-gateway-properties"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#inbound-gateway-properties"}},[e._v("#")]),e._v(" Inbound Gateway Properties")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("")]),e._v(" now exposes the "),n("code",[e._v("amqp-template")]),e._v(" attribute to allow more control over an external bean for the reply "),n("code",[e._v("RabbitTemplate")]),e._v(".\nYou can also provide your own "),n("code",[e._v("AmqpTemplate")]),e._v(" implementation.\nIn addition, you can use "),n("code",[e._v("default-reply-to")]),e._v(" if the request message does not have a "),n("code",[e._v("replyTo")]),e._v(" property.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/amqp.html#amqp"}},[e._v("AMQP Support")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"xpath-splitter-improvements"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#xpath-splitter-improvements"}},[e._v("#")]),e._v(" XPath Splitter Improvements")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("XPathMessageSplitter")]),e._v(" ("),n("code",[e._v("")]),e._v(") now allows the configuration of "),n("code",[e._v("output-properties")]),e._v(" for the internal "),n("code",[e._v("javax.xml.transform.Transformer")]),e._v(" and supports an "),n("code",[e._v("Iterator")]),e._v(" mode (defaults to "),n("code",[e._v("true")]),e._v(") for the XPath evaluation "),n("code",[e._v("org.w3c.dom.NodeList")]),e._v(" result.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/xml.html#xml-xpath-splitting"}},[e._v("Splitting XML Messages")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"http-changes-5"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#http-changes-5"}},[e._v("#")]),e._v(" HTTP Changes")]),e._v(" "),n("p",[e._v("This section describes general changes to the Spring Integration HTTP functionality.")]),e._v(" "),n("h6",{attrs:{id:"cors"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#cors"}},[e._v("#")]),e._v(" CORS")]),e._v(" "),n("p",[e._v("The HTTP inbound endpoints ("),n("code",[e._v("")]),e._v(" and "),n("code",[e._v("")]),e._v(") now allow the\nconfiguration of Cross-origin Resource Sharing (CORS).")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/http.html#http-cors"}},[e._v("Cross-origin Resource Sharing (CORS) Support")]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"inbound-gateway-timeout"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#inbound-gateway-timeout"}},[e._v("#")]),e._v(" Inbound Gateway Timeout")]),e._v(" "),n("p",[e._v("You can configure the HTTP inbound gate way to return a status code that you specify when a request times out.\nThe default is now "),n("code",[e._v("500 Internal Server Error")]),e._v(" instead of "),n("code",[e._v("200 OK")]),e._v(".")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/http.html#http-response-statuscode"}},[e._v("Response Status Code")]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"form-data"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#form-data"}},[e._v("#")]),e._v(" Form Data")]),e._v(" "),n("p",[e._v("We added documentation for proxying "),n("code",[e._v("multipart/form-data")]),e._v(" requests.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/http.html#http"}},[e._v("HTTP Support")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"gateway-changes-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#gateway-changes-2"}},[e._v("#")]),e._v(" Gateway Changes")]),e._v(" "),n("p",[e._v("This section describes general changes to the Spring Integration Gateway functionality.")]),e._v(" "),n("h6",{attrs:{id:"gateway-methods-can-return-completablefuture"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#gateway-methods-can-return-completablefuture"}},[e._v("#")]),e._v(" Gateway Methods can Return "),n("code",[e._v("CompletableFuture")])]),e._v(" "),n("p",[e._v("When using Java 8, gateway methods can now return "),n("code",[e._v("CompletableFuture")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/gateway.html#gw-completable-future"}},[n("code",[e._v("CompletableFuture")])]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"messaginggateway-annotation"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#messaginggateway-annotation"}},[e._v("#")]),e._v(" MessagingGateway Annotation")]),e._v(" "),n("p",[e._v("The request and reply timeout properties are now "),n("code",[e._v("String")]),e._v(" instead of "),n("code",[e._v("Long")]),e._v(" to allow configuration with property placeholders or SpEL.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/gateway.html#messaging-gateway-annotation"}},[n("code",[e._v("@MessagingGateway")]),e._v(" Annotation")]),e._v(".")],1),e._v(" "),n("h5",{attrs:{id:"aggregator-changes-3"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#aggregator-changes-3"}},[e._v("#")]),e._v(" Aggregator Changes")]),e._v(" "),n("p",[e._v("This section describes general changes to the Spring Integration aggregator functionality.")]),e._v(" "),n("h6",{attrs:{id:"aggregator-performance"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#aggregator-performance"}},[e._v("#")]),e._v(" Aggregator Performance")]),e._v(" "),n("p",[e._v("This release includes some performance improvements for aggregating components (aggregator, resequencer, and others), by more efficiently removing messages from groups when they are released.\nNew methods ("),n("code",[e._v("removeMessagesFromGroup")]),e._v(") have been added to the message store.\nSet the "),n("code",[e._v("removeBatchSize")]),e._v(" property (default: "),n("code",[e._v("100")]),e._v(") to adjust the number of messages deleted in each operation.\nCurrently, the JDBC, Redis, and MongoDB message stores support this property.")]),e._v(" "),n("h6",{attrs:{id:"output-message-group-processor"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#output-message-group-processor"}},[e._v("#")]),e._v(" Output Message Group Processor")]),e._v(" "),n("p",[e._v("When using a "),n("code",[e._v("ref")]),e._v(" or inner bean for the aggregator, you can now directly bind a "),n("code",[e._v("MessageGroupProcessor")]),e._v(".\nIn addition, we added a "),n("code",[e._v("SimpleMessageGroupProcessor")]),e._v(" that returns the collection of messages in the group.\nWhen an output processor produces a collection of "),n("code",[e._v("Message")]),e._v(", the aggregator releases those messages individually.\nConfiguring the "),n("code",[e._v("SimpleMessageGroupProcessor")]),e._v(" makes the aggregator a message barrier, where messages are held up until they all arrive and are then released individually.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/aggregator.html#aggregator"}},[e._v("Aggregator")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"ftp-and-sftp-changes-3"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#ftp-and-sftp-changes-3"}},[e._v("#")]),e._v(" FTP and SFTP Changes")]),e._v(" "),n("p",[e._v("This section describes general changes to the Spring Integration FTP and SFTP functionality.")]),e._v(" "),n("h6",{attrs:{id:"inbound-channel-adapters"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#inbound-channel-adapters"}},[e._v("#")]),e._v(" Inbound Channel Adapters")]),e._v(" "),n("p",[e._v("You can now specify a "),n("code",[e._v("remote-directory-expression")]),e._v(" on the inbound channel adapters, to determine the directory at runtime.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ftp.html#ftp"}},[e._v("FTP/FTPS Adapters")]),e._v(" and "),n("RouterLink",{attrs:{to:"/en/spring-integration/sftp.html#sftp"}},[e._v("SFTP Adapters")]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"gateway-partial-results"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#gateway-partial-results"}},[e._v("#")]),e._v(" Gateway Partial Results")]),e._v(" "),n("p",[e._v("When you use FTP or SFTP outbound gateways to operate on multiple files (with "),n("code",[e._v("mget")]),e._v(" and "),n("code",[e._v("mput")]),e._v("), an exception can\noccur after part of the request is completed.\nIf such a condition occurs, a "),n("code",[e._v("PartialSuccessException")]),e._v(" that contains the partial results is thrown.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/ftp.html#ftp-outbound-gateway"}},[e._v("FTP Outbound Gateway")]),e._v(" and "),n("RouterLink",{attrs:{to:"/en/spring-integration/sftp.html#sftp-outbound-gateway"}},[e._v("SFTP Outbound Gateway")]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"delegating-session-factory"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#delegating-session-factory"}},[e._v("#")]),e._v(" Delegating Session Factory")]),e._v(" "),n("p",[e._v("We added a delegating session factory, enabling the selection of a particular session factory based on some thread context value.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/ftp.html#ftp-dsf"}},[e._v("Delegating Session Factory")]),e._v(" and "),n("RouterLink",{attrs:{to:"/en/spring-integration/sftp.html#sftp-dsf"}},[e._v("Delegating Session Factory")]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"default-sftp-session-factory"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#default-sftp-session-factory"}},[e._v("#")]),e._v(" Default Sftp Session Factory")]),e._v(" "),n("p",[e._v("Previously, the "),n("code",[e._v("DefaultSftpSessionFactory")]),e._v(" unconditionally allowed connections to unknown hosts.\nThis is now configurable (default: "),n("code",[e._v("false")]),e._v(").")]),e._v(" "),n("p",[e._v("The factory now requires a configured "),n("code",[e._v("knownHosts")]),e._v(", file unless the "),n("code",[e._v("allowUnknownKeys")]),e._v(" property is "),n("code",[e._v("true")]),e._v(" (default: "),n("code",[e._v("false")]),e._v(").")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/sftp.html#sftp-unk-keys"}},[n("code",[e._v("allowUnknownKeys")]),e._v("::Set to "),n("code",[e._v("true")]),e._v(" to allow connections to hosts with unknown (or changed) keys.")]),e._v(" for more information.")],1),e._v(" "),n("h6",{attrs:{id:"message-session-callback"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#message-session-callback"}},[e._v("#")]),e._v(" Message Session Callback")]),e._v(" "),n("p",[e._v("We introduced the "),n("code",[e._v("MessageSessionCallback")]),e._v(" to perform any custom "),n("code",[e._v("Session")]),e._v(" operations with the "),n("code",[e._v("requestMessage")]),e._v(" context in the "),n("code",[e._v("")]),e._v(".")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/ftp.html#ftp-session-callback"}},[e._v("Using "),n("code",[e._v("MessageSessionCallback")])]),e._v(" and "),n("RouterLink",{attrs:{to:"/en/spring-integration/sftp.html#sftp-session-callback"}},[e._v("MessageSessionCallback")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"websocket-changes-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#websocket-changes-2"}},[e._v("#")]),e._v(" Websocket Changes")]),e._v(" "),n("p",[e._v("We added "),n("code",[e._v("WebSocketHandlerDecoratorFactory")]),e._v(" support to the "),n("code",[e._v("ServerWebSocketContainer")]),e._v(" to allow chained customization for the internal "),n("code",[e._v("WebSocketHandler")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/web-sockets.html#web-sockets-namespace"}},[e._v("WebSockets Namespace Support")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"application-event-adapters-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#application-event-adapters-changes"}},[e._v("#")]),e._v(" Application Event Adapters changes")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("ApplicationEvent")]),e._v(" adapters can now operate with "),n("code",[e._v("payload")]),e._v(" as an "),n("code",[e._v("event")]),e._v(" to directly allow omitting custom "),n("code",[e._v("ApplicationEvent")]),e._v(" extensions.\nFor this purpose, we introduced the "),n("code",[e._v("publish-payload")]),e._v(" boolean attribute has been introduced on the "),n("code",[e._v("")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/event.html#applicationevent"}},[e._v("Spring "),n("code",[e._v("ApplicationEvent")]),e._v(" Support")]),e._v(" for more information.")],1),e._v(" "),n("h3",{attrs:{id:"changes-between-4-0-and-4-1"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#changes-between-4-0-and-4-1"}},[e._v("#")]),e._v(" Changes between 4.0 and 4.1")]),e._v(" "),n("p",[e._v("See the "),n("a",{attrs:{href:"https://github.com/spring-projects/spring-integration/wiki/Spring-Integration-4.0-to-4.1-Migration-Guide",target:"_blank",rel:"noopener noreferrer"}},[e._v("Migration Guide"),n("OutboundLink")],1),e._v(" for important changes that might affect your applications.\nYou can find migration guides for all versions back to 2.1 on the "),n("a",{attrs:{href:"https://github.com/spring-projects/spring-integration/wiki",target:"_blank",rel:"noopener noreferrer"}},[e._v("wiki"),n("OutboundLink")],1),e._v(".")]),e._v(" "),n("h4",{attrs:{id:"new-components-8"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#new-components-8"}},[e._v("#")]),e._v(" New Components")]),e._v(" "),n("p",[e._v("Version 4.1 added a number of new components.")]),e._v(" "),n("h5",{attrs:{id:"promise-gateway"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#promise-gateway"}},[e._v("#")]),e._v(" Promise Gateway")]),e._v(" "),n("p",[e._v("The messaging gateway methods now support a Reactor "),n("code",[e._v("Promise")]),e._v(" return type.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/gateway.html#async-gateway"}},[e._v("Asynchronous Gateway")]),e._v(".")],1),e._v(" "),n("h5",{attrs:{id:"websocket-support"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#websocket-support"}},[e._v("#")]),e._v(" WebSocket support")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("WebSocket")]),e._v(" module is now available.\nIt is fully based on the Spring WebSocket and Spring Messaging modules and provides an "),n("code",[e._v("")]),e._v(" and an "),n("code",[e._v("")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/web-sockets.html#web-sockets"}},[e._v("WebSockets Support")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"scatter-gather-enterprise-integration-pattern"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#scatter-gather-enterprise-integration-pattern"}},[e._v("#")]),e._v(" Scatter-Gather Enterprise Integration Pattern")]),e._v(" "),n("p",[e._v("We implemented the scatter-gather enterprise integration pattern.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/scatter-gather.html#scatter-gather"}},[e._v("Scatter-Gather")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"routing-slip-pattern"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#routing-slip-pattern"}},[e._v("#")]),e._v(" Routing Slip Pattern")]),e._v(" "),n("p",[e._v("We added the routing slip EIP pattern implementation.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/router.html#routing-slip"}},[e._v("Routing Slip")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"idempotent-receiver-pattern"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#idempotent-receiver-pattern"}},[e._v("#")]),e._v(" Idempotent Receiver Pattern")]),e._v(" "),n("p",[e._v("We added the idempotent receiver enterprise integration pattern implementation by adding the "),n("code",[e._v("")]),e._v(" component in XML or the "),n("code",[e._v("IdempotentReceiverInterceptor")]),e._v(" and "),n("code",[e._v("IdempotentReceiver")]),e._v(" annotations for Java configuration.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/handler-advice.html#idempotent-receiver"}},[e._v("Idempotent Receiver Enterprise Integration Pattern")]),e._v(" and the "),n("a",{attrs:{href:"https://docs.spring.io/spring-integration/api/index.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("Javadoc"),n("OutboundLink")],1),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"boon-jsonobjectmapper"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#boon-jsonobjectmapper"}},[e._v("#")]),e._v(" Boon "),n("code",[e._v("JsonObjectMapper")])]),e._v(" "),n("p",[e._v("We added the Boon "),n("code",[e._v("JsonObjectMapper")]),e._v(" for the JSON transformers.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/transformer.html#transformer"}},[e._v("Transformer")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"redis-queue-gateways"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#redis-queue-gateways"}},[e._v("#")]),e._v(" Redis Queue Gateways")]),e._v(" "),n("p",[e._v("We added the "),n("code",[e._v("")]),e._v(" and "),n("code",[e._v("")]),e._v(" components.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/redis.html#redis-queue-inbound-gateway"}},[e._v("Redis Queue Inbound Gateway")]),e._v(" and "),n("RouterLink",{attrs:{to:"/en/spring-integration/redis.html#redis-queue-outbound-gateway"}},[e._v("Redis Queue Outbound Gateway")]),e._v(".")],1),e._v(" "),n("h5",{attrs:{id:"pollskipadvice"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#pollskipadvice"}},[e._v("#")]),e._v(" "),n("code",[e._v("PollSkipAdvice")])]),e._v(" "),n("p",[e._v("We added the "),n("code",[e._v("PollSkipAdvice")]),e._v(", which you can use within the "),n("code",[e._v("")]),e._v(" of the "),n("code",[e._v("")]),e._v(" to determine if the current poll should be suppressed (skipped) by some condition that you implement with "),n("code",[e._v("PollSkipStrategy")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/polling-consumer.html#polling-consumer"}},[e._v("Poller")]),e._v(" for more information.")],1),e._v(" "),n("h4",{attrs:{id:"general-changes-8"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#general-changes-8"}},[e._v("#")]),e._v(" General Changes")]),e._v(" "),n("p",[e._v("This section describes general changes from version 4.0 to version 4.1.")]),e._v(" "),n("h5",{attrs:{id:"amqp-inbound-endpoints-channel"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#amqp-inbound-endpoints-channel"}},[e._v("#")]),e._v(" AMQP Inbound Endpoints, Channel")]),e._v(" "),n("p",[e._v("Elements that use a message listener container (inbound endpoints and channel) now support the "),n("code",[e._v("missing-queues-fatal")]),e._v(" attribute.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/amqp.html#amqp"}},[e._v("AMQP Support")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"amqp-outbound-endpoints"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#amqp-outbound-endpoints"}},[e._v("#")]),e._v(" AMQP Outbound Endpoints")]),e._v(" "),n("p",[e._v("The AMQP outbound endpoints support a new property called "),n("code",[e._v("lazy-connect")]),e._v(" (default: "),n("code",[e._v("true")]),e._v(").\nWhen "),n("code",[e._v("true")]),e._v(", the connection to the broker is not established until the first message arrives (assuming there are no inbound endpoints, which always try to establish the connection during startup).\nWhen set to "),n("code",[e._v("false")]),e._v(", an attempt to establish the connection is made during application startup.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/amqp.html#amqp"}},[e._v("AMQP Support")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"simplemessagestore"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#simplemessagestore"}},[e._v("#")]),e._v(" SimpleMessageStore")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("SimpleMessageStore")]),e._v(" no longer makes a copy of the group when calling "),n("code",[e._v("getMessageGroup()")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/message-store.html#sms-caution"}},[e._v("[WARNING]")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"web-service-outbound-gateway-encode-uri"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#web-service-outbound-gateway-encode-uri"}},[e._v("#")]),e._v(" Web Service Outbound Gateway: "),n("code",[e._v("encode-uri")])]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("")]),e._v(" now provides an "),n("code",[e._v("encode-uri")]),e._v(" attribute to allow disabling the encoding of the URI object before sending the request.")]),e._v(" "),n("h5",{attrs:{id:"http-inbound-channel-adapter-and-status-code"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#http-inbound-channel-adapter-and-status-code"}},[e._v("#")]),e._v(" Http Inbound Channel Adapter and Status Code")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("")]),e._v(" can now be configured with a "),n("code",[e._v("status-code-expression")]),e._v(" to override the default "),n("code",[e._v("200 OK")]),e._v(" status.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/http.html#http-namespace"}},[e._v("HTTP Namespace Support")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"mqtt-adapter-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#mqtt-adapter-changes"}},[e._v("#")]),e._v(" MQTT Adapter Changes")]),e._v(" "),n("p",[e._v("You can now configure the MQTT channel adapters to connect to multiple servers — for example, to support High Availability (HA).\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/mqtt.html#mqtt"}},[e._v("MQTT Support")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("The MQTT message-driven channel adapter now supports specifying the QoS setting for each subscription.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/mqtt.html#mqtt-inbound"}},[e._v("Inbound (Message-driven) Channel Adapter")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("The MQTT outbound channel adapter now supports asynchronous sends, avoiding blocking until delivery is confirmed.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/mqtt.html#mqtt-outbound"}},[e._v("Outbound Channel Adapter")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("It is now possible to programmatically subscribe to and unsubscribe from topics at runtime.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/mqtt.html#mqtt-inbound"}},[e._v("Inbound (Message-driven) Channel Adapter")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"ftp-and-sftp-adapter-changes"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#ftp-and-sftp-adapter-changes"}},[e._v("#")]),e._v(" FTP and SFTP Adapter Changes")]),e._v(" "),n("p",[e._v("The FTP and SFTP outbound channel adapters now support appending to remote files and taking specific actions when a remote file already exists.\nThe remote file templates now also supports this, as well as "),n("code",[e._v("rmdir()")]),e._v(" and "),n("code",[e._v("exists()")]),e._v(".\nIn addition, the remote file templates provide access to the underlying client object, enabling access to low-level APIs.")]),e._v(" "),n("p",[e._v("See "),n("RouterLink",{attrs:{to:"/en/spring-integration/ftp.html#ftp"}},[e._v("FTP/FTPS Adapters")]),e._v(" and "),n("RouterLink",{attrs:{to:"/en/spring-integration/sftp.html#sftp"}},[e._v("SFTP Adapters")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"splitter-and-iterator"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#splitter-and-iterator"}},[e._v("#")]),e._v(" Splitter and Iterator")]),e._v(" "),n("p",[n("code",[e._v("Splitter")]),e._v(" components now support an "),n("code",[e._v("Iterator")]),e._v(" as the result object for producing output messages.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/splitter.html#splitter"}},[e._v("Splitter")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"aggregator"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#aggregator"}},[e._v("#")]),e._v(" Aggregator")]),e._v(" "),n("p",[n("code",[e._v("Aggregator")]),e._v(" instancess now support a new attribute "),n("code",[e._v("expire-groups-upon-timeout")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/aggregator.html#aggregator"}},[e._v("Aggregator")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"content-enricher-improvements"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#content-enricher-improvements"}},[e._v("#")]),e._v(" Content Enricher Improvements")]),e._v(" "),n("p",[e._v("We added a "),n("code",[e._v("null-result-expression")]),e._v(" attribute, which is evaluated and returned if "),n("code",[e._v("")]),e._v(" returns "),n("code",[e._v("null")]),e._v(".\nYou can add it in "),n("code",[e._v("
")]),e._v(" and "),n("code",[e._v("")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/content-enrichment.html#content-enricher"}},[e._v("Content Enricher")]),e._v(" for more information.")],1),e._v(" "),n("p",[e._v("We added an "),n("code",[e._v("error-channel")]),e._v(" attribute, which is used to handle an error flow if an "),n("code",[e._v("Exception")]),e._v(" occurs downstream of the "),n("code",[e._v("request-channel")]),e._v(".\nThis lets you return an alternative object to use for enrichment.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/content-enrichment.html#content-enricher"}},[e._v("Content Enricher")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"header-channel-registry"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#header-channel-registry"}},[e._v("#")]),e._v(" Header Channel Registry")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("")]),e._v(" element’s "),n("code",[e._v("")]),e._v(" child element can now override the header channel registry’s default time for retaining channel mappings.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/content-enrichment.html#header-channel-registry"}},[e._v("Header Channel Registry")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"orderly-shutdown"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#orderly-shutdown"}},[e._v("#")]),e._v(" Orderly Shutdown")]),e._v(" "),n("p",[e._v("We made improvements to the orderly shutdown algorithm.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/shutdown.html#jmx-shutdown"}},[e._v("Orderly Shutdown")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"management-for-recipientlistrouter"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#management-for-recipientlistrouter"}},[e._v("#")]),e._v(" Management for "),n("code",[e._v("RecipientListRouter")])]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("RecipientListRouter")]),e._v(" now provides several management operations to configure recipients at runtime.\nWith that, you can now configure the "),n("code",[e._v("")]),e._v(" without any "),n("code",[e._v("")]),e._v(" from the start.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/router.html#recipient-list-router-management"}},[n("code",[e._v("RecipientListRouterManagement")])]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"abstractheadermapper-non-standard-headers-token"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#abstractheadermapper-non-standard-headers-token"}},[e._v("#")]),e._v(" AbstractHeaderMapper: NON_STANDARD_HEADERS token")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("AbstractHeaderMapper")]),e._v(" implementation now provides the additional "),n("code",[e._v("NON_STANDARD_HEADERS")]),e._v(" token to map any user-defined headers, which are not mapped by default.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/amqp.html#amqp-message-headers"}},[e._v("AMQP Message Headers")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"amqp-channels-template-channel-transacted"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#amqp-channels-template-channel-transacted"}},[e._v("#")]),e._v(" AMQP Channels: "),n("code",[e._v("template-channel-transacted")])]),e._v(" "),n("p",[e._v("We introduced the "),n("code",[e._v("template-channel-transacted")]),e._v(" attribute for AMQP "),n("code",[e._v("MessageChannel")]),e._v(" instances.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/amqp.html#amqp-channels"}},[e._v("AMQP-backed Message Channels")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"syslog-adapter"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#syslog-adapter"}},[e._v("#")]),e._v(" Syslog Adapter")]),e._v(" "),n("p",[e._v("The default syslog message converter now has an option to retain the original message in the payload while still setting the headers.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/syslog.html#syslog-inbound-adapter"}},[e._v("Syslog Inbound Channel Adapter")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"asynchronous-gateway-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#asynchronous-gateway-2"}},[e._v("#")]),e._v(" Asynchronous Gateway")]),e._v(" "),n("p",[e._v("In addition to the "),n("code",[e._v("Promise")]),e._v(" return type "),n("a",{attrs:{href:"#x4.1-promise-gateway"}},[e._v("mentioned earlier")]),e._v(", gateway methods may now return a "),n("code",[e._v("ListenableFuture")]),e._v(", introduced in Spring Framework 4.0.\nYou can also disable asynchronous processing in the gateway, letting a downstream flow directly return a "),n("code",[e._v("Future")]),e._v(".\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/gateway.html#async-gateway"}},[e._v("Asynchronous Gateway")]),e._v(".")],1),e._v(" "),n("h5",{attrs:{id:"aggregator-advice-chain"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#aggregator-advice-chain"}},[e._v("#")]),e._v(" Aggregator Advice Chain")]),e._v(" "),n("p",[n("code",[e._v("Aggregator")]),e._v(" and "),n("code",[e._v("Resequencer")]),e._v(" now support "),n("code",[e._v("")]),e._v(" and "),n("code",[e._v("")]),e._v(" child elements to advise the "),n("code",[e._v("forceComplete")]),e._v(" operation.\nSee "),n("RouterLink",{attrs:{to:"/en/spring-integration/aggregator.html#aggregator-xml"}},[e._v("Configuring an Aggregator with XML")]),e._v(" for more information.")],1),e._v(" "),n("h5",{attrs:{id:"outbound-channel-adapter-and-scripts"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#outbound-channel-adapter-and-scripts"}},[e._v("#")]),e._v(" Outbound Channel Adapter and Scripts")]),e._v(" "),n("p",[e._v("The "),n("code",[e._v("")]),e._v(" now supports the "),n("code",[e._v("