aws-serverless-java-containerのSpring Boot2チュートリアルをやってみただけ（メモ）

# はじめに

aws-serverless-java-containerを使用して、LambdaでSpring Boot2のアプリケーションを動かしてみます。

- [Quick start Spring Boot2](https://github.com/awslabs/aws-serverless-java-container/wiki/Quick-start---Spring-Boot2)

以下はWindowsにインストール済みとします。

- JDK
- Maven
- AWS CLI
- Node.js
- Serverless Framework


# プロジェクト作成

MavenのArchetype Pluginを使ってJava projectを作成します。

```
mvn archetype:generate -DgroupId=my.service -DartifactId=my-service -Dversion=1.0-SNAPSHOT -DarchetypeGroupId=com.amazonaws.serverless.archetypes -DarchetypeArtifactId=aws-serverless-springboot2-archetype -DarchetypeVersion=1.5
```

アーキタイプは、pom.xmlファイルとbuild.gradleファイルを含む新しいプロジェクトをセットアップします。 生成されたコードには、AWS LambdaのメインエントリポイントであるStreamLambdaHandlerクラスが含まれます。 / pingリソースを含むリソースパッケージ。 アプリケーションを実行する一連の単体テスト。


実行すると以下のプロジェクトが作成されました。
今回は使用しませんが、template.ymlはAWSデプロイ用のSAMテンプレートです。

```
>tree /F
フォルダー パスの一覧
ボリューム シリアル番号は B3BC-AD20 です
C:.
│  build.gradle
│  pom.xml
│  README.md
│  template.yml
│
└─src
    ├─assembly
    │      bin.xml
    │
    ├─main
    │  ├─java
    │  │  └─my
    │  │      └─service
    │  │          │  Application.java
    │  │          │  StreamLambdaHandler.java
    │  │          │
    │  │          └─controller
    │  │                  PingController.java
    │  │
    │  └─resources
    │          application.properties
    │
    └─test
        └─java
            └─my
                └─service
                        StreamLambdaHandlerTest.java
```

この時点で/pingへリクエストすると、pongを返すRESTアプリケーションになっているので、デプロイ用のファイルを作成します。

```
>mvn package -DskipTests
```

作成されたファイルは以下のファイル名になっており、約15MBでした。Spring Bootのアプリケーションとしては小さなサイズになっています。

- my-service-1.0-SNAPSHOT-lambda-package.zip


# Lambdaへデプロイ

早速デプロイしてみます。SAMテンプレートが生成されていますのでそのまま使用していいのですが、今回はServerless Frameworkを使用します。
設定ファイル（serverless.yml）は以下のようになります。

```yaml
service: my-service

provider:
  name: aws
  runtime: java8
  region: ap-northeast-1

package:
  artifact: target/my-service-1.0-SNAPSHOT-lambda-package.zip

functions:
  hello:
    handler: my.service.StreamLambdaHandler
    events:
      - http: GET ping
```

sls deployコマンドでLabmdaへデプロイします。

```
> sls deploy

>sls deploy
Serverless: Packaging service...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
........
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service my-service-1.0-SNAPSHOT.jar file to S3 (2.37 KB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
..............................
Serverless: Stack update finished...
Service Information
service: my-service
stage: dev
region: ap-northeast-1
stack: my-service-dev
resources: 11
api keys:
  None
endpoints:
  GET - https://XXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/dev/ping
functions:
  hello: my-service-dev-hello
layers:
  None
Serverless: Run the "serverless" command to setup monitoring, troubleshooting and testing.
```


「https://XXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/dev/ping」のようにアクセス先URLが表示されるので、実行すると以下のようなJSONが返ってきます。

```json
{"pong":"Hello, World!"}
```


# 注意点

注意点が記載されていたのでメモ。

## @&#xFFF0;ComponentoScanアノテーションは使用しない。

@&#xFFF0;ComponentoScanアノテーションはパッケージ内のすべてのクラスを自動的にスキャンしてくれますが、負荷の高い操作であり、Lambdaの場合は@&#xFFF0;Importに切り替えたほうが良い。

## Avoid relationship autowiring

これはよくわからなかった。こんな機能あったっけ？
代わりに@&#xFFF0;Autowiredアノテーションを使うようにとのこと。

## パラメータありのコンストラクタでは@&#xFFF0;ConstructorPropertiesを使う

以下のコンストラクタでは、@&#xFFF0;ConstructorPropertiesがないとコンストラクタのパラメータ名とデータのバインディングが自動で行われ、I/O時間が大幅に低下する（らしい）。必ず@&#xFFF0;ConstructorPropertiesアノテーションを使用すること。

```
public class Pet {
  @ConstructorProperties({"name", "breed"})
  public Pet(String name, String breed) {
    this.name = name;
    this.breed = synopsis;
  }
}
```

# その他

元ページにはSpring security, Spring profilesについても記載あり。