[Camel in Action] 4-2. Camel Bean Registry와 메서드 선택 알고리즘

Bean Registry – Camel이 Bean을 찾는 방법

Camel 라우트에서 bean("myBean")처럼 이름으로 Bean을 참조할 때, Camel은 Bean Registry에서 해당 Bean을 찾습니다. 실행 환경에 따라 다른 Registry가 사용됩니다.

주요 Bean Registry 종류

1. ApplicationContextRegistry (Spring)

Spring Boot 환경에서 가장 많이 사용됩니다. Spring의 ApplicationContext가 Bean Registry 역할을 합니다.

@Bean
public OrderService orderService() {
    return new OrderService();
}

// 라우트에서 이름으로 참조
from("direct:input")
    .bean("orderService", "process");

2. SimpleRegistry (단독 실행)

SimpleRegistry registry = new SimpleRegistry();
registry.bind("myService", new MyService());

CamelContext context = new DefaultCamelContext(registry);
context.addRoutes(new RouteBuilder() {
    @Override
    public void configure() {
        from("direct:start")
            .bean("myService");
    }
});

3. JndiRegistry (J2EE 환경)

JndiRegistry registry = new JndiRegistry();
// JNDI 컨텍스트에 등록된 Bean을 자동으로 사용
from("direct:start")
    .bean("java:comp/env/myService");

4. CDI (Quarkus/Java EE)

// Quarkus + Camel
@ApplicationScoped
public class MyRoute extends RouteBuilder {
    @Inject
    OrderService orderService;

    @Override
    public void configure() {
        from("direct:start")
            .bean(orderService);  // 주입받은 Bean 직접 사용
    }
}

메서드 선택 알고리즘

메서드명을 지정하지 않으면 Camel은 다음 순서로 적합한 메서드를 찾습니다.

  1. @Handler 어노테이션: 하나의 메서드에 달려있으면 그 메서드 사용
  2. 메서드가 하나뿐: 자동으로 그 메서드 선택
  3. 메시지 본문 타입 매칭: 파라미터 타입이 메시지 본문 타입과 일치하는 메서드 선택
  4. 모호한 경우: 예외 발생 → 메서드명 명시 필요

@Handler 어노테이션

public class MultiMethodBean {
    @Handler  // Camel이 이 메서드를 선택
    public Order processOrder(Order order) {
        return doProcess(order);
    }

    public String validateOrder(Order order) {  // Camel이 무시
        return "valid";
    }
}

타입 기반 메서드 선택

public class TypeMatchingBean {
    public String process(String text) {     // String 본문일 때
        return text.toUpperCase();
    }

    public Order process(Order order) {      // Order 객체 본문일 때
        return processOrder(order);
    }

    public void process(InputStream is) {   // InputStream 본문일 때
        readStream(is);
    }
}

// Camel이 본문 타입을 보고 적절한 오버로드 메서드를 자동 선택
from("direct:start")
    .bean(TypeMatchingBean.class);  // 메서드명 지정 불필요

메서드 선택 문제 해결

// 문제: 오버로드된 메서드가 여러 개 → 예외 발생 가능
public class AmbiguousBean {
    public String process(String s) { ... }
    public String process(Integer i) { ... }
}

// 해결 1: 메서드명과 시그니처 명시
from("direct:start")
    .bean(AmbiguousBean.class, "process(String)");

// 해결 2: 먼저 타입 변환
from("direct:start")
    .convertBodyTo(String.class)
    .bean(AmbiguousBean.class, "process");

Leave a Comment