Get ahead
VMware offers training and certification to turbo-charge your progress.
Learn moreWe are pleased to announce that the Java DSL for Spring Integration 1.0 Milestone 3 has been released. Please use the Milestone Repository with Maven or Gradle, download a distribution archive, or see the project home page for more information.
Since the last Milestone 2, some new features and further improvements, as well as a number of bug fixes have been included to this Milestone, with the GA release due around the end of October.
First of all thanks for all who are interested in this Spring Integration Extension, provide feedback, share their thoughts and even contribute.
Here is a summary of major changes:
Spring Integration 4.1
Current Milestone provides compatibility with Spring Integration 4.1 as well as with Spring Framework 4.1.
The changes include:
Channel names late resolution
,which allows for DSL IntegrationFlow
s definitions to be based on just channel names and avoid workarounds that required
@DependsOn
from one flow to another;
(as well as its DSL) is based on Spring Messaging module;
.io/spring/docs/current/spring-framework-reference/html/expressions.html#expressions-spel-compilation).
It is very useful for Spring Integration, which extensively uses SpEL at runtime. You can enable the SpEL Compiler using the
spring.expression.compiler.mode
System Property with a value of IMMEDIATE
or MIXED
.
Of course, compatibility with Spring Integration 4.0 still remains.
IntegrationFlow Lambda
The IntegrationFlow
bean definition can now be presented as a Lambda
too, to simplify the DSL usage:
@Bean
public IntegrationFlow lambdaFlow() {
return f -> f.filter("World"::equals)
.transform("Hello "::concat)
.handle(System.out::println);
}
Actually we just made IntegrationFlow
a functional interface with a single method
define(IntegrationFlowDefinition<?> flow)
and the IntegrationFlowBeanPostProcessor
just converts that 'fake' bean
to the real StandardIntegrationFlow
based on implicit IntegrationFlowBuilder
. The only limitation is with such a
definition, that it is based on an implicit DirectChannel
with lambdaFlow.input
bean name.
Protocol-specific Adapters
With this Milestone, several new protocol-specific Namespace factories
have been introduced: Files
,
(S)Ftp
and Mail
. Some simple samples of their usage:
@Autowired
private DefaultFtpSessionFactory ftpSessionFactory;
@Bean
public IntegrationFlow ftpInboundFlow() {
return IntegrationFlows
.from(Ftp.inboundAdapter(this.ftpSessionFactory)
.preserveTimestamp(true)
.remoteDirectory("ftpSource")
.regexFilter(".*\\.txt$")
.localFilenameGeneratorExpression("#this.toUpperCase() + '.a'")
.localDirectory(new File("tmp")),
e -> e.id("ftpInboundAdapter"))
.channel(MessageChannels.queue("ftpInboundResultChannel"))
.get();
}
@Bean
public IntegrationFlow tailFlow() {
return IntegrationFlows
.from(Files.tailAdapter(new File(tmpDir, "TailTest"))
.delay(500)
.end(false))
.channel(MessageChannels.queue("tailChannel"))
.get();
}
@Bean
public IntegrationFlow imapIdleFlow() throws AddressException {
return IntegrationFlows
.from(Mail.imapIdleAdapter("imap://user:[email protected]:993/INBOX")
.searchTermStrategy((f, l) ->
new AndTerm(new FromTerm(new InternetAddress("bar@baz")),
new FlagTerm(new Flags(Flags.Flag.SEEN), false)))
.javaMailProperties(p -> p
.put("mail.debug", "true")
.put("mail.imap.connectionpoolsize", "5"))
.shouldReconnectAutomatically(true))
.enrichHeaders(s -> s.headerExpressions(h -> h
.put(MailHeaders.SUBJECT, "payload.subject")
.put(MailHeaders.FROM, "payload.from[0].toString()")))
.channel(MessageChannels.queue("imapIdleChannel"))
.get();
}
Support additions
As you could notice in the last IMAP
sample the .javaMailProperties()
and .enrichHeaders()
have fluent syntax
to specify Properties
and Map<String, String>
as inline objects. Unfortunately, Java doesn't provide a Builder
API
for those simple classes, hence we do that for you and provide functional interfaces to build Properties
and Map
from Lambdas. For example, the Mail.headers()
provides a MailHeadersBuilder
- an extension of MapBuilder
,
which can be used in the .enrichHeaders()
as well:
@Bean
public IntegrationFlow sendMailFlow() {
return f -> f.enrichHeaders(Mail.headers().subject("foo").from("foo@bar").to("bar@baz"))
.handle(Mail.outboundAdapter("smtp.gmail.com")
.credentials("user", "pw")
.protocol("smtp")));
}
Of course, this is an equivalent of <int-mail:header-enricher>
from XML configuration.
Wrapping up
You can obtain more information about these and existing classes from their source code.
We look forward to your comments and feedback (StackOverflow (spring-integration
tag),
Spring JIRA, GitHub)
as soon as possible and report issues you find before we GA towards over a couple months.
SpringOne 2GX 2014
Some of those mentioned topics are being covered at SpringOne tomorrow. Please attend [Gary Russell's Session] (https://2014.event.springone2gx.com/schedule/sessions/spring_integration_java_configuration_and_more.html) to learn more about these and other Spring Integration improvements added in the last 12 months.