eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (cat=Spring Boot)
announcement - icon

Refactor Java code safely — and automatically — with OpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy to put off. That’s where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions — one for newcomers and one for experienced users. You’ll see how recipes work, how to apply them across projects, and how to modernize code with confidence.

Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.

Course – LJB – NPI EA (cat = Core Java)
announcement - icon

Code your way through and build up a solid, practical foundation of Java:

>> Learn Java Basics

Partner – LambdaTest – NPI EA (cat= Testing)
announcement - icon

Distributed systems often come with complex challenges such as service-to-service communication, state management, asynchronous messaging, security, and more.

Dapr (Distributed Application Runtime) provides a set of APIs and building blocks to address these challenges, abstracting away infrastructure so we can focus on business logic.

In this tutorial, we'll focus on Dapr's pub/sub API for message brokering. Using its Spring Boot integration, we'll simplify the creation of a loosely coupled, portable, and easily testable pub/sub messaging system:

>> Flexible Pub/Sub Messaging With Spring Boot and Dapr

1. Introduction

This article will introduce the core concepts of Spring Integration primarily through small, practical examples.

Spring Integration provides a lot of powerful components that can greatly enhance the interconnectivity of systems and processes within an enterprise architecture.

It embodies some of the finest and most popular design patterns, helping developers avoid rolling their own.

We will take a look at the specific needs that this library fills in an enterprise application and why it is advisable over some of its alternatives. We will also look at some available tools for further simplifying the development of Spring Integration-based applications.

2. Setup

<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-core</artifactId>
    <version>6.0.0</version>
</dependency>
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-file</artifactId>
    <version>6.0.0</version>
</dependency>

You can download the latest versions of Spring Integration Core and the Spring Integration File Support from Maven Central.

3. The Messaging Pattern

One of the foundational patterns in this library is Messaging. The pattern is centered around messages – discrete payloads of data that move from an originating system or process to one or multiple systems or processes via predefined channels.

Historically, the pattern arose as the most flexible way to integrate multiple disparate systems in a way that:

  • Almost completely decouples the systems involved in the integration
  • Allows participant systems in the integration to be completely agnostic of each others underlying protocols, formatting, or other implementation details
  • Encourages the development and reuse of components involved in the integration

4. Messaging Integration in Action

Let’s consider a basic example that copies a MPEG video file from a designated folder to another configured folder:

@Configuration
@EnableIntegration
public class BasicIntegrationConfig{
    public String INPUT_DIR = "the_source_dir";
    public String OUTPUT_DIR = "the_dest_dir";
    public String FILE_PATTERN = "*.mpeg";

    @Bean
    public MessageChannel fileChannel() {
        return new DirectChannel();
    }

    @Bean
    @InboundChannelAdapter(value = "fileChannel", poller = @Poller(fixedDelay = "1000"))
    public MessageSource<File> fileReadingMessageSource() {
        FileReadingMessageSource sourceReader= new FileReadingMessageSource();
        sourceReader.setDirectory(new File(INPUT_DIR));
        sourceReader.setFilter(new SimplePatternFileListFilter(FILE_PATTERN));
        return sourceReader;
    }

    @Bean
    @ServiceActivator(inputChannel= "fileChannel")
    public MessageHandler fileWritingMessageHandler() {
        FileWritingMessageHandler handler = new FileWritingMessageHandler(new File(OUTPUT_DIR));
        handler.setFileExistsMode(FileExistsMode.REPLACE);
        handler.setExpectReply(false);
        return handler;
    }
}

The code above configures a service activator, an integration channel, and an inbound channel adapter.

We’ll examine each of these component types in greater detail shortly. The @EnableIntegration annotation designates this class as a Spring Integration configuration.

Let’s start our Spring Integration application context:

public static void main(String... args) {
    AbstractApplicationContext context 
      = new AnnotationConfigApplicationContext(BasicIntegrationConfig.class);
    context.registerShutdownHook();
    
    Scanner scanner = new Scanner(System.in);
    System.out.print("Please enter q and press <enter> to exit the program: ");
    
    while (true) {
       String input = scanner.nextLine();
       if("q".equals(input.trim())) {
          break;
      }
    }
    System.exit(0);
}

The main method above starts up the integration context; it also accepts the “q” character input from the command line to exit the program. Let us examine the components in more detail.

5. Spring Integration Components

5.1. Message

The org.springframework.integration.Message interface defines the spring Message: the unit of data transfer within a Spring Integration context.

public interface Message<T> {
    T getPayload();
    MessageHeaders getHeaders();
}

It defines accessors to two key elements:

  • Message headers, essentially a key-value container that can be used to transmit metadata, as defined in the org.springframework.integration.MessageHeaders class
  • The message payload, which is the actual data that is of value to be transferred — in our use-case, the video file is the payload

5.2. Channel

A channel in Spring Integration (and indeed, EAI) is the basic plumbing in an integration architecture. It’s the pipe by which messages are relayed from one system to another.

You can think of it as a literal pipe through which an integrated system or process can push messages to (or receive messages from) other systems.

Channels in Spring Integration come in various flavors, depending on your need. They are largely configurable and usable out of the box, without any custom code, but should you have custom needs, there’s a robust framework available.

Point-to-Point (P2P) channels are used to establish 1-to-1 communication lines between systems or components. One component publishes a message to the channel so another can pick it up. There can be only one component at each end of the channel.

As we have seen, configuring a channel is as simple as returning an instance of DirectChannel:

@Bean
public MessageChannel fileChannel1() {
    return new DirectChannel();
}

@Bean
public MessageChannel fileChannel2() {
    return new DirectChannel();
}

@Bean
public MessageChannel fileChannel3() {
    return new DirectChannel();
}

Here, we have defined three separate channels all identified by the name of their respective getter methods.

Publish-Subscribe (Pub-Sub) channels are used to establish a one-to-many communication line between systems or components. This will allow us to publish to all 3 of the direct channels that we created earlier.

So following our example, we can replace the P2P channel with a pub-sub channel:

@Bean
public MessageChannel pubSubFileChannel() {
    return new PublishSubscribeChannel();
}

@Bean
@InboundChannelAdapter(value = "pubSubFileChannel", poller = @Poller(fixedDelay = "1000"))
public MessageSource<File> fileReadingMessageSource() {
    FileReadingMessageSource sourceReader = new FileReadingMessageSource();
    sourceReader.setDirectory(new File(INPUT_DIR));
    sourceReader.setFilter(new SimplePatternFileListFilter(FILE_PATTERN));
    return sourceReader;
}

We have now converted the inbound channel adapter to publish to a Pub-Sub channel. This will allow us to send the files that are being read from the source folder to multiple destinations.

5.3. Bridge

A bridge in Spring Integration is used to connect two message channels or adapters if for any reason they can’t connect directly.

In our case, we can use a bridge to connect our Pub-Sub channel to three different P2P channels (because P2P and Pub-Sub channels can’t be connected directly):

@Bean
@BridgeFrom(value = "pubSubFileChannel")
public MessageChannel fileChannel1() {
    return new DirectChannel();
}

@Bean
@BridgeFrom(value = "pubSubFileChannel")
public MessageChannel fileChannel2() {
    return new DirectChannel();
}

@Bean
@BridgeFrom(value = "pubSubFileChannel")
public MessageChannel fileChannel3() {
    return new DirectChannel();
}

The above bean configuration now bridges the pubSubFileChannel to three P2P channels. The @BridgeFrom annotation is what defines a bridge and can be applied to any number of channels that need to subscribe to the Pub-Sub channel.

We can read the above code as “create a bridge from the pubSubFileChannel to fileChannel1, fileChannel2, and fileChannel3 so that messages from pubSubFileChannel can be fed to all three channels simultaneously.”

5.4. Service Activator

The Service Activator is any POJO that defines the @ServiceActivator annotation on a given method. This allows us to execute any method on our POJO when a message is received from an inbound channel, and it allows us to write messages to an outward channel.

In our example, our service activator receives a file from the configured input channel and writes it to the configured folder.

5.5. Adapter

The Adapter is an enterprise integration pattern-based component that allows one to “plug-in” to a system or data source. It is almost literally an adapter as we know it from plugging into a wall socket or electronic device.

It allows reusable connectivity to otherwise “black-box” systems like databases, FTP servers and messaging systems such as JMS, AMQP, and social networks like Twitter. The ubiquity of the need to connect to these systems means that adapters are very portable and reusable (in fact there’s a small catalog of adapters, freely available and ready to use by anyone).

Adapters fall into two broad categories — inbound and outbound.

Let’s examine these categories in the context of the adapters in use in our sample scenario:

Inbound adapters, as we have seen, are used to bring in messages from the external system (in this case a filesystem directory).

Our inbound adapter configuration consists of:

  • An @InboundChannelAdapter annotation that marks the bean configuration as an adapter — we configure the channel to which the adapter will feed its messages (in our case, an MPEG file) and a poller, a component which helps the adapter poll the configured folder at the specified interval
  • A standard Spring java configuration class that returns a FileReadingMessageSource, the Spring Integration class implementation that handles filesystem polling

Outbound adapters are used to send messages outwards. Spring Integration supports a large variety of out-of-the-box adapters for various common use cases.

6. Conclusion

We have examined a basic use case with Spring Integration that demonstrates the java-based configuration of the library and reusability of the available components.

Spring Integration code is deployable as a standalone project within JavaSE as well as part of something larger in a Jakarta EE environment. While it doesn’t directly compete with other EAI-centric products and patterns like Enterprise Service Buses (ESBs), it is a viable, lightweight alternative to solving many of the same problems that ESBs were built to solve.

The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.
Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (tag=Refactoring)
announcement - icon

Modern Java teams move fast — but codebases don’t always keep up. Frameworks change, dependencies drift, and tech debt builds until it starts to drag on delivery. OpenRewrite was built to fix that: an open-source refactoring engine that automates repetitive code changes while keeping developer intent intact.

The monthly training series, led by the creators and maintainers of OpenRewrite at Moderne, walks through real-world migrations and modernization patterns. Whether you’re new to recipes or ready to write your own, you’ll learn practical ways to refactor safely and at scale.

If you’ve ever wished refactoring felt as natural — and as fast — as writing code, this is a good place to start.

Course – LS – NPI – (cat=Spring)
announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

eBook Jackson – NPI EA – 3 (cat = Jackson)