Usage

Implementation

Spring Cloud Functionでは、基本的に、以下の3種類のクラスを実装しておく必要がある。

  1. クラウド実行環境でイベントをハンドリングするクラス
  2. Applicaitonの実行・起動・設定を行うクラス
  3. ファンクションコードを実装したクラス

例えば、Amazon Lambdaでは、イベントが発生すると、ハンドラとして、ユーザが継承して実装した com.amazonaws.services.lambda.runtime.RequestHandlerクラスが 呼び出されことになる。Spring Funciton Cloudでは、当クラスをイベントの種類ごとに複数提供しており、 このイベントクラス内で、DIコンテナの構築処理行われることになる。もっともスタンダードなハンドラクラスである、 org.springframework.cloud.function.adapter.aws.SpringBootRequestHandlerを使用する場合、 イベントをハンドリングするクラスを以下の通り、IOとなる型パラメータを指定して作成すれば良い。

1 org.debugroom.sample.spring.cloud.function.Handler.java
package org.debugroom.sample.spring.cloud.function;

import org.springframework.cloud.function.adapter.aws.SpringBootRequestHandler;

public class Handler extends SpringBootRequestHandler<String, String>{
}

Note

上記のクラスでは、型パラメータを指定している以外は、 SpringBootRequestHandlerのデフォルトメソッドを利用するため、特に何もオーバーライドはしていない。 作成したハンドラクラスは、AWSコンソールで、フルパス・メソッド登録する。

Note

AWSにデプロイする場合、型パラメータには、com.amazonaws.services.lambda.runtime.eventsにある イベントクラスを指定することになるが、ここでは簡単のため、特にイベントパラメータ受け取らずファンクションを実行するよう、String型を仮指定する。

イベントの種類ごとに作られた上記のハンドラクラスから、SpringのDIコンテナ構築処理が呼ばれることになる。 (Amazon Lambdaであれば、org.springframework.cloud.function.adapter.aws.SpringFunctionInitializer#initializeが呼ばれる)

Note

アプリケーション起動するためのクラスはMavenのSpringBootプラグインの中で、指定。

Applicationの実行・起動及び設定を行うクラスでは、以下の通り、org.springframework.boot.autoconfigure.SpringBootApplicationアノテーションを付与し、 メインメソッド内にSpringアプリケーションを実行する処理を記述しておく。 S3Client等、その他ファンクションの実行に必要な設定があれば、同時にコンフィグクラスに設定しておく。

org.debugroom.sample.spring.cloud.function.config.App.java
package org.debugroom.sample.spring.cloud.function.config;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {

        public static void main(String args[]){
                SpringApplication.run(App.class, args);
        }

}

最後に、ハンドラクラス内で呼び出されるファンクションクラスをjava.util.function.Functionクラスを継承して実装する。 以下は、インプットとして文字列を0個以上のストリーム(Flux型)として受け取るが、アウトプットに “test”という文字列をストリームとして返す例である。

org.debugroom.sample.spring.cloud.function.StringFunction.java
package org.debugroom.sample.spring.cloud.function;

import reactor.core.publisher.Flux;

public class StringFunction implements
    java.util.function.Function<Flux<String>, Flux<String>>{

        @Override
        public Flux<String> apply(Flux<String> t) {
                  return Flux.just("test");
        }

}

Note

Flux型については こちら も参照のこと。 要は多量の文字列データをノンブロッキングに高速に処理することを目的とした型と解釈すれば良い。

Functionクラスは、デフォルトでコンフィグクラスに@Beanで登録するか、 org.springframework.cloud.function.context.FunctionScanアノテーションを付与してSpringにコンポーネントスキャンさせるか いずれかの方法で登録しておく。@FunctionScanアノテーションは、設定ファイルで、 spring.cloud.function.scan.packagesのプロパティとして指定できる(デフォルトはfunctions)

spring:
  cloud:
    function:
      scan:
        packages: org.debugroom.sample.spring.cloud.function

Note

S3などspring-cloud-awsを利用する場合は、EC2を前提とする設定を以下の通り変更してく。

cloud:
  aws:
    stack:
      auto: false
    credentials:
      instanceProfile: false
      profileName:
    region:
      auto: false

実装後は、mvn packageで依存ライブラリを含むJARファイルを作成し、クラウド実行環境へデプロイする。 例として、Amazon Lambdaへのアップロード及び、設定は コードの作成・デプロイ を参照のこと。

Warning

Spring Cloud Functionで実行するファンクションは初回起動時にDIコンテナの起動で数十秒要する。 2回目以降、Lambda実行環境が再利用されるので、イベント通知後処理は早く実行されるが、完全マネージドのLambda環境では、 しばらく関数が実行されないと実行環境が破棄され、再びその後のファンクション実行時にDIコンテナの起動処理が必要になる。 API Gatewaryなどはデフォルト30[s]のリクエストタイムアウトがあるので、Spring Cloud Functionの実行は 即時性を求められる処理について、適用するかどうか十分検討して実装すること。