[Camel in Action] 4-3. Camel Bean 파라미터 바인딩과 어노테이션

파라미터 바인딩이란?

Camel이 Bean 메서드를 호출할 때, Exchange에서 필요한 데이터를 꺼내 메서드 파라미터에 자동으로 바인딩합니다. 이를 파라미터 바인딩(Parameter Binding)이라 합니다.

기본 타입 바인딩

// Camel이 자동으로 처리하는 기본 타입들
public class OrderProcessor {
    // Exchange 전체
    public void process(Exchange exchange) { ... }

    // Message 객체
    public void process(Message message) { ... }

    // 본문 직접 (타입 변환 포함)
    public void process(Order order) { ... }
    public void process(String text) { ... }

    // 여러 파라미터 - Camel이 자동 매핑
    public void process(Order order, Exchange exchange) { ... }
}

Camel 어노테이션으로 정밀 바인딩

import org.apache.camel.Body;
import org.apache.camel.Header;
import org.apache.camel.Headers;
import org.apache.camel.ExchangeProperty;

@Component
public class AnnotatedOrderService {

    // @Body: 메시지 본문 바인딩
    public Order processOrder(@Body Order order) {
        return doProcess(order);
    }

    // @Header: 특정 헤더 바인딩
    public String generateConfirmation(
            @Body Order order,
            @Header("customerId") String customerId,
            @Header(value = "region", defaultValue = "DOMESTIC") String region) {
        return customerId + "-" + order.getId() + "-" + region;
    }

    // @Headers: 전체 헤더 Map 바인딩
    public void logHeaders(@Headers Map<String, Object> headers) {
        headers.forEach((k, v) -> System.out.println(k + " = " + v));
    }

    // @ExchangeProperty: Exchange 프로퍼티 바인딩
    public void process(@Body Order order,
                        @ExchangeProperty("correlationId") String corrId) {
        System.out.println("상관관계 ID: " + corrId);
    }
}

언어 어노테이션

import org.apache.camel.language.Simple;
import org.apache.camel.language.XPath;
import org.apache.camel.language.JsonPath;

@Component
public class ExpressionBean {

    // @Simple: Simple 표현식으로 값 가져오기
    public void process(@Body Order order,
                        @Simple("${date:now:yyyy-MM-dd}") String today) {
        System.out.println("오늘 날짜: " + today);
    }

    // @XPath: XML 메시지에서 XPath로 값 추출
    public void processXml(@XPath("//order/@id") String orderId,
                           @XPath("//order/amount/text()") double amount) {
        System.out.printf("주문 %s: %.2f원%n", orderId, amount);
    }

    // @JsonPath: JSON 메시지에서 JsonPath로 값 추출
    public void processJson(@JsonPath("$.orderId") String orderId,
                            @JsonPath("$.customer.name") String name) {
        System.out.println(orderId + " - " + name);
    }
}

@BeanInject로 의존성 주입

// 라우트 빌더 내에서 Bean 주입
public class MyRoute extends RouteBuilder {
    @BeanInject
    private OrderService orderService;

    @Override
    public void configure() {
        from("direct:start")
            .bean(orderService);
    }
}

Optional 파라미터

// 헤더가 없을 때 null 허용
public void process(@Body Order order,
                    @Header(value="priority", required=false) Integer priority) {
    int p = priority != null ? priority : 0;
    // ...
}

반환값 처리

// void: 본문 변경 없음
public void log(@Body Order order) {
    System.out.println(order);
}

// 값 반환: 반환값이 새로운 메시지 본문이 됨
public Order transform(@Body String json) {
    return parseOrder(json);
}

// null 반환: 본문이 null로 설정됨 (주의)
public Order conditionalTransform(@Body String json) {
    if (!isValid(json)) return null;  // 주의: null로 설정됨
    return parseOrder(json);
}

Leave a Comment