Enterprise Integration Patterns in Java (2025)


Enterprise Integration Patterns in Java

Enterprise Integration Patterns (EIP) provide solutions for common integration challenges. This comprehensive guide explores various integration patterns and their implementations in Java.

Pro Tip: Understanding integration patterns helps in building scalable and maintainable enterprise applications.

Message Routing

Note: Message routing patterns determine how messages flow between different components.

Content-Based Router


@Component
public class ContentBasedRouter {
    
    @Autowired
    private OrderProcessor orderProcessor;
    
    @Autowired
    private PaymentProcessor paymentProcessor;
    
    public void route(Message message) {
        Order order = (Order) message.getPayload();
        
        switch (order.getType()) {
            case "STANDARD":
                orderProcessor.processStandardOrder(order);
                break;
            case "EXPRESS":
                orderProcessor.processExpressOrder(order);
                break;
            case "PAYMENT":
                paymentProcessor.processPayment(order);
                break;
            default:
                throw new IllegalArgumentException("Unknown order type: " + order.getType());
        }
    }
}

@Configuration
public class RouterConfig {
    
    @Bean
    public IntegrationFlow orderFlow() {
        return IntegrationFlows
            .from("orderChannel")
            .route(Message.class, message -> {
                Order order = (Order) message.getPayload();
                return order.getType().toLowerCase();
            })
            .channelMapping("standard", "standardOrderChannel")
            .channelMapping("express", "expressOrderChannel")
            .channelMapping("payment", "paymentChannel")
            .get();
    }
}

Message Filter


@Component
public class OrderFilter {
    
    public boolean accept(Message message) {
        Order order = (Order) message.getPayload();
        return order.getAmount() > 1000 && order.getStatus().equals("PENDING");
    }
}

@Configuration
public class FilterConfig {
    
    @Bean
    public IntegrationFlow filterFlow() {
        return IntegrationFlows
            .from("orderChannel")
            .filter(Message.class, message -> {
                Order order = (Order) message.getPayload();
                return order.getAmount() > 1000 && order.getStatus().equals("PENDING");
            })
            .channel("filteredOrderChannel")
            .get();
    }
}

Message Transformation

Pro Tip: Message transformation patterns help in converting messages between different formats.

Message Translator


@Component
public class OrderTranslator {
    
    public PaymentRequest translate(Order order) {
        return PaymentRequest.builder()
            .orderId(order.getId())
            .amount(order.getAmount())
            .currency(order.getCurrency())
            .customerId(order.getCustomerId())
            .build();
    }
}

@Configuration
public class TranslatorConfig {
    
    @Bean
    public IntegrationFlow translationFlow() {
        return IntegrationFlows
            .from("orderChannel")
            .transform(Order.class, order -> {
                return PaymentRequest.builder()
                    .orderId(order.getId())
                    .amount(order.getAmount())
                    .currency(order.getCurrency())
                    .customerId(order.getCustomerId())
                    .build();
            })
            .channel("paymentChannel")
            .get();
    }
}

Content Enricher


@Component
public class OrderEnricher {
    
    @Autowired
    private CustomerService customerService;
    
    public EnrichedOrder enrich(Order order) {
        Customer customer = customerService.getCustomer(order.getCustomerId());
        return EnrichedOrder.builder()
            .order(order)
            .customerName(customer.getName())
            .customerEmail(customer.getEmail())
            .build();
    }
}

@Configuration
public class EnricherConfig {
    
    @Bean
    public IntegrationFlow enrichmentFlow() {
        return IntegrationFlows
            .from("orderChannel")
            .enrich(enricher -> enricher
                .requestChannel("customerLookupChannel")
                .requestPayload(Message::getPayload)
                .propertyFunction("customerName", 
                    response -> ((Customer) response).getName())
                .propertyFunction("customerEmail", 
                    response -> ((Customer) response).getEmail()))
            .channel("enrichedOrderChannel")
            .get();
    }
}

Message Endpoints

Note: Message endpoints connect messaging systems to other systems.

Service Activator


@Component
public class OrderServiceActivator {
    
    @Autowired
    private OrderService orderService;
    
    public void handleOrder(Message message) {
        Order order = message.getPayload();
        orderService.processOrder(order);
    }
}

@Configuration
public class ServiceActivatorConfig {
    
    @Bean
    public IntegrationFlow serviceActivatorFlow() {
        return IntegrationFlows
            .from("orderChannel")
            .handle(message -> {
                Order order = (Order) message.getPayload();
                orderService.processOrder(order);
            })
            .get();
    }
}

Gateway


@MessagingGateway
public interface OrderGateway {
    
    @Gateway(requestChannel = "orderChannel")
    OrderResponse submitOrder(Order order);
    
    @Gateway(requestChannel = "orderStatusChannel")
    OrderStatus getOrderStatus(String orderId);
}

@Configuration
public class GatewayConfig {
    
    @Bean
    public IntegrationFlow gatewayFlow() {
        return IntegrationFlows
            .from("orderChannel")
            .handle(orderService::processOrder)
            .transform(order -> OrderResponse.builder()
                .orderId(order.getId())
                .status(order.getStatus())
                .build())
            .get();
    }
}

System Management

Pro Tip: System management patterns help in monitoring and controlling integration systems.

Circuit Breaker


@Component
public class CircuitBreaker {
    private final int threshold;
    private final long timeout;
    private int failureCount;
    private long lastFailureTime;
    private CircuitState state;
    
    public CircuitBreaker(int threshold, long timeout) {
        this.threshold = threshold;
        this.timeout = timeout;
        this.state = CircuitState.CLOSED;
    }
    
    public boolean execute(Supplier operation) {
        if (state == CircuitState.OPEN) {
            if (System.currentTimeMillis() - lastFailureTime > timeout) {
                state = CircuitState.HALF_OPEN;
            } else {
                return false;
            }
        }
        
        try {
            boolean result = operation.get();
            if (state == CircuitState.HALF_OPEN) {
                state = CircuitState.CLOSED;
                failureCount = 0;
            }
            return result;
        } catch (Exception e) {
            failureCount++;
            lastFailureTime = System.currentTimeMillis();
            state = CircuitState.OPEN;
            return false;
        }
    }
    
    private enum CircuitState {
        CLOSED, OPEN, HALF_OPEN
    }
}

Message Store


@Component
public class MessageStore {
    private final Map> store = new ConcurrentHashMap<>();
    
    public void store(String id, Message message) {
        store.put(id, message);
    }
    
    public Message retrieve(String id) {
        return store.get(id);
    }
    
    public void remove(String id) {
        store.remove(id);
    }
}

@Configuration
public class MessageStoreConfig {
    
    @Bean
    public IntegrationFlow messageStoreFlow() {
        return IntegrationFlows
            .from("inputChannel")
            .handle(message -> {
                String id = UUID.randomUUID().toString();
                messageStore.store(id, message);
            })
            .channel("outputChannel")
            .get();
    }
}

Best Practices

Pro Tip: Following integration patterns best practices ensures reliable and maintainable systems.

Integration Best Practices

  • Use appropriate message channels
  • Implement proper error handling
  • Use message transformation when needed
  • Implement proper monitoring
  • Use circuit breakers for external services
  • Implement proper logging
  • Use message stores for reliability
  • Implement proper testing
  • Use appropriate message formats
  • Implement proper security
  • Use proper configuration management
  • Implement proper documentation
  • Use proper versioning
  • Implement proper monitoring
  • Follow integration standards

Conclusion

Enterprise Integration Patterns provide proven solutions for common integration challenges. By implementing these patterns and following best practices, you can build robust and maintainable enterprise applications.