Spring Cloud Function은 다음과 같은 목표를 가진 프로젝트 있다.
- 비즈니스 로직을 함수(Function)를 통해 구현하도록 장려한다.
- 비즈니스 로직의 개발 라이프사이클을 특정 런타임 대상과 분리하여, 동일한 코드가 웹 엔드포인트, 스트림 프로세서, 태스크 등 다양한 환경에서 실행될 수 있도록 한다.
- 여러 서버리스 제공업체에 걸쳐 일관된 프로그래밍 모델을 지원하며, 독립 실행형(로컬 또는 PaaS)으로도 실행할 수 있다.
- 서버리스 제공업체 환경에서 Spring Boot의 핵심 기능(자동 구성, 의존성 주입, 메트릭 등)을 활성화한다.
이를 통해 모든 전송 세부 사항과 인프라를 추상화하여, 개발자가 익숙한 도구와 프로세스를 유지한 채 비즈니스 로직에만 집중할 수 있도록 돕는다.
함수 등록 흐름
Spring Cloud Function에서 함수(Supplier, Function, Consumer)가 등록되는 과정은 크게 두 가지 방식으로 나뉜다.
Functional 모드: 패키지 스캔을 통한 사전 등록
spring.functional.enabled=true로 설정하면 Functional 모드가 활성화된다. 이때 ContextFunctionCatalogInitializer가 postProcessBeanDefinitionRegistry를 실행하며 지정된 패키지(spring.cloud.function.scan.packages, 기본값: functions)를 스캔한다.
- 스캔을 통해 발견된
Supplier,Function,Consumer구현 클래스를 스프링 빈으로 등록한다. - 동시에 각 함수에 대해
registration_<FQN>형태의 이름을 가진FunctionRegistration빈을 생성한다. - 마지막으로, 등록된 모든
FunctionRegistration빈들을FunctionRegistry에 최종 등록하는 역할을 할FunctionRegistrationPostProcessor를 빈으로 추가한다.
일반 모드: lookup 시점의 지연 래핑(Lazy Wrapping)
Functional 모드를 사용하지 않을 경우, 함수는 실제 사용되는 시점(FunctionCatalog.lookup(...) 호출)에 등록된다. 만약 lookup 하려는 함수가 레지스트리에 아직 없다면, BeanFactoryAwareFunctionRegistry가 빈 팩토리에서 해당 이름의 빈을 찾는다. 그 후, 빈의 타입을 추론하여 FunctionRegistration으로 감싸 레지스트리에 등록한다.
FunctionRegistration으로 래핑 되는 타입
BeanFactoryAwareFunctionRegistry는 다양한 형태의 빈을 함수로 인식하고 FunctionRegistration으로 감싸 등록할 수 있다.
- 표준
Supplier/Function/Consumer빈:FunctionTypeUtils를 통해 타입을 추론한 뒤 래핑한다. - 메시징 스타일 함수:
BiFunction<T, Map<String,Object>, R>또는BiConsumer<T, Map<String,Object>>형태의 빈은 헤더(두 번째 인자)를 처리할 수 있는 어댑터 함수로 감싼 뒤 래핑된다. - Kotlin 람다/함수형 타입: Kotlin 전용 래퍼를 통해
FunctionRegistration을 생성한다. - POJO: 단 하나의 함수형 메서드를 가진 POJO 클래스의 경우, 프록시를 통해
Function인터페이스를 구현하도록 만든 후 래핑한다.
FunctionRegistrationPostProcessor는 FunctionRegistry 빈이 초기화될 때, 컨텍스트에 존재하는 모든 FunctionRegistration 빈들을 순회하며 FunctionRegistry에 최종적으로 등록하는 역할을 한다. 만약 FunctionRegistration에 타입 정보가 명확하지 않으면 예외가 발생한다.
함수 사용
주요 클라우드 제공자 어댑터
각 클라우드 제공업체의 런타임 환경과 Spring Cloud Function을 연결해 주는 어댑터가 제공된다.
| 클라우드 제공자 | 어댑터 | 엔트리포인트/핸들러 |
|---|---|---|
| AWS Lambda | spring-cloud-function-adapter-aws |
org.springframework.cloud.function.adapter.aws.FunctionInvoker |
| Google Cloud Functions | spring-cloud-function-adapter-gcp |
org.springframework.cloud.function.adapter.gcp.FunctionInvoker |
| Microsoft Azure Functions | spring-cloud-function-adapter-azure |
org.springframework.cloud.function.adapter.azure.AzureFunctionInstanceInjector |
이 어댑터들은 클라우드 런타임 → 어댑터 엔트리포인트 → 입력을 Message<?>로 변환 → FunctionCatalog.lookup(...) → 함수 실행 → 출력 변환 의 공통된 흐름을 따른다.
Web 환경에서 함수 실행 (Spring MVC 기준)
애플리케이션 컨텍스트에 등록된 Supplier, Function, Consumer 빈은 별도 설정 없이 자동으로 HTTP 엔드포인트로 노출된다.
이 과정은 다음과 같이 역할이 분리되어 처리된다.
- 함수 해석 (Mapping):
FunctionHandlerMapping(RequestMappingHandlerMapping의 하위 클래스)이 들어온 HTTP 요청의 경로와 메서드를 분석한다.FunctionCatalog를 사용해 요청에 매핑될 함수를 찾아 요청 속성(request attribute)에 바인딩하는 역할을 한다. - 함수 실행 (Execution):
FunctionController가 실제 실행을 담당한다.FunctionWebRequestProcessingHelper유틸리티를 통해 HTTP 요청을Message<?>객체로 변환하고, 헤더나 파라미터를 처리한 뒤, 이전 단계에서 찾아둔 함수를 실행한다. 실행 결과는 다시 HTTP 응답으로 변환되어 클라이언트에게 전달된다.
함수 정의 및 호출 예시
@Bean
Function<String, String> uppercase() {
return String::toUpperCase;
}
@Bean
Function<String, String> reverse() {
return s -> new StringBuilder(s).reverse().toString();
}
경로 및 메서드 매핑
- 기본 경로는
/{functionName}이며,spring.cloud.function.web.path속성으로prefix를 추가할 수 있다. - HTTP 메서드는
spring.cloud.function.http.GET=uppercase와 같이 특정 함수별로 지정할 수 있다.
호출
- Function 호출 (POST): Consumer와 Function은 기본적으로 POST 요청으로 호출된다.
# 단일 함수 호출
curl -H "Content-Type: text/plain" localhost:8080/uppercase -d 'hello'
→ HELLO
# 함수 체이닝(Composition)
curl -H "Content-Type: text/plain" localhost:8080/uppercase,reverse -d 'abc'
→ CBA
- Supplier 호출 (GET): Supplier는 GET 요청으로 호출되며, 스트리밍 응답도 지원한다.
curl localhost:8080/mySupplier
- Consumer는 일반적으로 202 Accepted 응답을 반환한다.
'스프링' 카테고리의 다른 글
| spring-cloud-function Add Azure Event Grid trigger (0) | 2025.10.20 |
|---|---|
| spring-cloud-stream Add consumer priority (0) | 2025.10.16 |
| spring-jdbc Optimize parameter matching in TableMetaDataContext (0) | 2025.10.10 |
| 트랜잭션이 시작되는 시점 (3) | 2025.08.11 |
| 더티채킹과 지연쓰기 디버깅 (2) | 2025.08.07 |