この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
前回、Spring BootをAWS Lambdaで動かす方法について書きました。今回も同じテーマなのですが「@Autowired」アノテーションを使用してComponentのインスタンスを取得する、よりSpring Bootらしい実装ができたので、それについて書きたいと思います。
実装について - 今回変わったところ
「@Autowired」アノテーションなどSpringの機能を使用するため、今回はLambdaのHandlerを実装するクラスをSpringのApplication Contextとして指定しました。以下に、今回変更があったクラスについて記述します。
1.RequestHandler
Lambdaのエントリーポイントとなるhanderを実装するクラスです。先にも書いたように、このクラスをApplication Contextとして指定します。
LambdaFunctionHandler.java
package com.example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import lombok.Setter;
@SpringBootApplication
public class LambdaFunctionHandler implements RequestHandler<Object, Object>{
@Autowired
private SampleBean sampleBean;
@Autowired
private ConfigReader configReader;
@Setter
private Object input;
@Setter
private Context context;
@Override
public Object handleRequest(Object input, Context context) {
context.getLogger().log("-----start.-----");
String args[] = new String[0];
try (ConfigurableApplicationContext ctx = SpringApplication.run(LambdaFunctionHandler.class, args)) {
LambdaFunctionHandler app = ctx.getBean(LambdaFunctionHandler.class);
app.setInput(input);
app.setContext(context);
app.run(args);
context.getLogger().log("-----end.-----");
return "success.";
} catch (Exception e) {
e.printStackTrace();
context.getLogger().log("error.\n");
return "error.";
}
}
public void run(String... args) throws Exception {
String inputValue = sampleBean.sampleMethod(input.toString());
context.getLogger().log(inputValue);
context.getLogger().log("Region = " + configReader.getRegion());
context.getLogger().log("Bucket = " + configReader.getBucket());
context.getLogger().log("file = " + configReader.getFile());
}
}
handlerを持つクラスに対して、13行目で「@SpringBootApplication」アノテーションを付与してSpring Bootとして開始できるようにしています。32・33行目でこのクラスをApplication Contextとし、36行目でrunメソッドを呼び出しています。行いたい主な処理は、このrunメソッド内に記述することになります。
またrunメソッド内でLambdaのhandlerが取得する2つの変数「input」「context」を使用するため、34・35行目でSetterを呼び出してセットしています。なお「input」「context」にはlombokの「@Setter」アノテーションを付与することで、Setterを自動的に生成しています。
runメソッド内で使用したい2つのCompornent「SampleBean」「ConfigReader」は、16・19行目で「@Autowired」アノテーションを付与して宣言しています。これにより、Springにより自動的にインスタンスが作成されることになります。
2.Applicationクラス
前回はApplicationクラス内に、Beanを取得するメソッドを用意しました。今回は「@Autowired」アノテーションでBeanのインスタンスは取得するため、そのメソッドは削除します。実際は上記のhanderより起動するため、Lambdaでの実行だけを考慮すれば必要ないクラスかもしれません。
Application.java
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
3.ConfigReaderクラス
前回はConfigReaderクラス内でComponentのインスタンスを取得するため、先に削除したApplicationクラスのBeanを取得するメソッドを呼び出していました。今回は「@Autowired」アノテーションでComponentのインスタンスを取得します。以下のソースの9行目がその箇所です。
ConfigReader.java
package com.example;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class ConfigReader {
@Autowired
private Settings settings;
public String getRegion(){
return settings.getRegion();
}
public String getBucket(){
Map<String, String> map = settings.getS3();
return map.get("bucket");
}
public String getFile(){
Map<String, String> map = settings.getS3();
return map.get("file");
}
}
まとめ
handerを実装するクラスをApplication ContextとしてSpringを起動することで、「@Autowired」アノテーションを使用することができました。なお、残りのソースについては前回を参照してください。