46.4. 프로그래밍 모델

46.4.1. 개요

API 구성 요소 프레임워크의 컨텍스트에서 주요 구성 요소 구현 클래스는 org.apache.camel.util.component 패키지의 기본 클래스에서 파생됩니다. 이러한 기본 클래스는 구성 요소를 구현할 때 선택적으로 재정의할 수 있는 몇 가지 메서드를 정의합니다. 이 섹션에서는 해당 방법에 대한 간략한 설명과 자체 구성 요소 구현에서 사용하는 방법을 설명합니다.

46.4.2. 구현할 구성 요소 메서드

일반적으로 수정할 필요가 없는 생성된 메서드 구현 외에도 Component 클래스에서 다음 메서드 중 일부를 선택적으로 재정의할 수 있습니다.In addition to the generated method implementations (which you usually do not need to modify), you can optionally override some of the following methods in the Component class:

doStart()
(선택 사항) 콜드 시작 중에 구성 요소에 대한 리소스를 생성하는 콜백입니다. 다른 접근 방식은 지연 초기화 전략을 채택하는 것입니다(필요한 경우에만 리소스를 생성). 사실 지연 초기화는 종종 최상의 전략이므로 doStart 방법이 필요하지 않은 경우가 많습니다.
doStop()

(선택 사항) 구성 요소가 중지되는 동안 코드를 호출하는 콜백입니다. 구성 요소를 중지하면 모든 리소스가 종료되고 내부 상태가 삭제되고 캐시가 지워집니다.

참고

Camel은 해당 doStart 가 호출되지 않은 경우에도 현재 CamelContext 가 종료되면 항상 doStop 이 호출되도록 보장합니다.

doShutdown
(선택 사항) CamelContext 가 종료되는 동안 코드를 호출하는 콜백입니다. 중지된 구성 요소를 다시 시작할 수 있지만(일차 시작의 의미) 종료되는 구성 요소는 완전히 완료됩니다. 따라서 이 콜백은 구성 요소에 속하는 리소스를 확보할 수 있는 마지막 기회를 나타냅니다.

46.4.3. Component 클래스에서 구현해야 할 다른 것은 무엇입니까?

Component 클래스는 구성 요소 개체 자체와 동일한 (또는 유사한) 라이프 사이클이 있는 개체에 대한 참조를 보유하는 자연적인 위치입니다. 예를 들어 구성 요소가 OAuth 보안을 사용하는 경우 Component 클래스에 필요한 OAuth 개체에 대한 참조를 유지하고 OAuth 개체를 생성하기 위해 Component 클래스에 메서드를 정의하는 것이 자연스럽습니다.

46.4.4. 구현할 끝점 방법

다음과 같이 생성된 메서드 중 일부를 수정하고 필요한 경우 Endpoint 클래스에서 상속된 일부 메서드를 덮어쓸 수 있습니다.

afterConfigureProperties()

이 메서드에서 수행해야 하는 주요 작업은 API 이름과 일치하도록 적절한 유형의 프록시 클래스(API 클래스)를 생성하는 것입니다. API 이름( endpoint URI에서 이미 추출된)은 상속된 apiName 필드 또는 getApiName 접근자를 통해 사용할 수 있습니다. 일반적으로 apiName 필드에서 스위치를 수행하여 해당 프록시 클래스를 생성합니다. 예를 들면 다음과 같습니다.

// Java
private Object apiProxy;
...
@Override
protected void afterConfigureProperties() {
    // TODO create API proxy, set connection properties, etc.
    switch (apiName) {
        case HELLO_FILE:
            apiProxy = new ExampleFileHello();
            break;
        case HELLO_JAVADOC:
            apiProxy = new ExampleJavadocHello();
            break;
        default:
            throw new IllegalArgumentException("Invalid API name " + apiName);
    }
}
getApiProxy(ApiMethod 메서드, Map<String, Object> args)

ConfigureProperties 이후에 생성한 프록시 인스턴스를 반환하려면 이 메서드를 재정의합니다. 예를 들면 다음과 같습니다.

@Override
public Object getApiProxy(ApiMethod method, Map<String, Object> args) {
    return apiProxy;
}

특별한 경우에는 API 메서드 및 인수에 따라 프록시를 선택할 수 있습니다. getApiProxy 는 필요한 경우 이 접근 방식을 유연하게 수행할 수 있습니다.

doStart()
(선택 사항) 콜드 시작 중에 리소스를 생성하는 콜백입니다. Component.doStart() 와 동일한 의미 체계가 있습니다.
doStop()
(선택 사항) 구성 요소가 중지되는 동안 코드를 호출하는 콜백입니다. Component.doStop() 과 동일한 의미 체계가 있습니다.
doShutdown
(선택 사항) 구성 요소를 종료하는 동안 코드를 호출하는 콜백입니다. Component.doShutdown() 과 동일한 의미가 있습니다.
interceptPropertyNames(Set<String> propertyNames)

(선택 사항) API 구성 요소 프레임워크는 끝점 URI 및 제공된 옵션 값을 사용하여 호출할 메서드를 결정합니다(대신 및 별칭으로 인해 모호함). 그러나 구성 요소가 내부적으로 옵션 또는 메서드 매개 변수를 추가하는 경우 호출할 올바른 방법을 결정하기 위해 프레임워크가 도움이 필요할 수 있습니다. 이 경우 interceptPropertyNames 메서드를 재정의하고 propertyNames 세트에 추가(hidden 또는 implicit) 옵션을 추가해야 합니다. 메서드 매개 변수의 전체 목록이 propertyNames 세트에 제공되면 프레임 워크에서 호출할 올바른 메서드를 식별할 수 있습니다.

참고

Endpoint,Producer 또는 Consumer 클래스 수준에서 이 메서드를 재정의할 수 있습니다. 기본 규칙은 옵션이 생산자 엔드포인트와 소비자 엔드포인트 모두에 영향을 미치는 경우 Endpoint 클래스의 메서드를 재정의합니다.

interceptProperties(Map<String,Object> 속성)

(선택 사항) 이 메서드를 재정의하여 API 메서드를 호출하기 전에 옵션의 실제 값을 수정하거나 설정할 수 있습니다. 예를 들어 필요한 경우 이 방법을 사용하여 일부 옵션의 기본값을 설정할 수 있습니다. 실제로 interceptPropertyNames 메서드와 interceptProperty 메서드를 모두 재정의해야 하는 경우가 많습니다.

참고

Endpoint,Producer 또는 Consumer 클래스 수준에서 이 메서드를 재정의할 수 있습니다. 기본 규칙은 옵션이 생산자 엔드포인트와 소비자 엔드포인트 모두에 영향을 미치는 경우 Endpoint 클래스의 메서드를 재정의합니다.

46.4.5. 구현할 소비자 방법

다음과 같이 Consumer 클래스에서 상속된 일부 메서드를 선택적으로 재정의할 수 있습니다.

interceptPropertyNames(Set<String> propertyNames)
(선택 사항) 이 메서드의 의미 체계는 Endpoint.interceptPropertyNames와 유사합니다.
interceptProperties(Map<String,Object> 속성)
(선택 사항) 이 방법의 의미 체계는 Endpoint.interceptProperties와 유사합니다.
doInvokeMethod(Map<String, Object> args)

(선택 사항) 이 메서드를 재정의하면 Java API 메서드 호출을 가로챌 수 있습니다. 이 메서드를 재정의하는 가장 일반적인 이유는 메서드 호출에 대한 오류 처리를 사용자 지정하는 것입니다. 예를 들어 doInvokeMethod 를 재정의하는 일반적인 방법은 다음 코드 조각에 표시됩니다.

// Java
@Override
protected Object doInvokeMethod(Map<String, Object> args) {
    try {
        return super.doInvokeMethod(args);
    } catch (RuntimeCamelException e) {
        // TODO - Insert custom error handling here!
        ...
    }
}

Java API 메서드가 호출되도록 이 구현의 일정 시점에서 super-class에서 doInvokeMethod 를 호출해야 합니다.

interceptResult(Object methodResult, Exchange resultExchange)
(선택 사항) API 메서드 호출 결과에 대해 몇 가지 추가 처리를 수행합니다. 예를 들어 현재 Camel exchange 오브젝트인 resultExchange 에 사용자 지정 헤더를 추가할 수 있습니다.
오브젝트 splitResult(오브젝트 결과)

(선택 사항) 메서드 API 호출 결과가 java.util.Collection 개체 또는 Java 배열인 경우 API 구성 요소 프레임워크에서 결과를 여러 교환 개체로 분할합니다(단일 호출 결과가 여러 메시지로 변환됨).

기본 동작을 변경하려면 소비자 끝점에서 splitResult 메서드를 덮어쓸 수 있습니다. 결과 인수에는 API 메시지 호출 결과가 포함됩니다. 결과를 분할하려면 배열 유형을 반환해야 합니다.

참고

끝점 URI에서 consumer.splitResult=false 를 설정하여 기본 분할 동작을 전환할 수도 있습니다.

46.4.6. 구현할 생산자 메서드

다음과 같이 Producer 클래스에서 상속된 일부 메서드를 선택적으로 재정의할 수 있습니다.

interceptPropertyNames(Set<String> propertyNames)
(선택 사항) 이 메서드의 의미 체계는 Endpoint.interceptPropertyNames와 유사합니다.
interceptProperties(Map<String,Object> 속성)
(선택 사항) 이 방법의 의미 체계는 Endpoint.interceptProperties와 유사합니다.
doInvokeMethod(Map<String, Object> args)
(선택 사항) 이 방법의 의미 체계는 Consumer.doInvokeMethod 와 유사합니다.
interceptResult(Object methodResult, Exchange resultExchange)
(선택 사항) 이 방법의 의미 체계는 Consumer.interceptResult 와 유사합니다.
참고

Producer.splitResult() 메서드는 호출되지 않으므로 API 메서드를 분할하면 소비자 끝점에 사용할 수 있는 것과 동일한 방식으로 생성할 수 없습니다. 생산자 엔드포인트에 유사한 효과를 얻으려면 Camel의 split() DSL 명령(표준 엔터프라이즈 통합 패턴 중 하나)을 사용하여 컬렉션 또는 배열 결과를 분할할 수 있습니다.

46.4.7. 소비자 폴링 및 스레딩 모델

API 구성 요소 프레임워크에서 소비자 끝점의 기본 스레딩 모델은 폴링 소비자로 예약됩니다. 이는 소비자 끝점의 API 메서드가 정규 스케줄링된 시간 간격에 호출됨을 의미합니다. 자세한 내용은 “예약된 폴링 소비자 구현” 에서 참조하십시오.