もうキャッシュの実装は怖くない!

はじめに

こんにちは。エキサイト株式会社で長期インターンをさせていただいている岡崎です。

今回は私が学んだキャッシュについての記事を書かせていただきます。

「もう分かっているんだが?」というエンジニアの皆さん向けではなく、Spring Bootでキャッシュを初めて実装する人向けの記事となっております。

そもそもキャッシュとは?

キャッシュとは、アクセスしたwebページの情報を一時的に保存していく技術です。

キャッシュを用いることで1からページを読み込むことがないので、動作の速さが期待できるぞってことですね。

キャッシュの流れは以下の通りになっています。

  1. コントローラまたはサービスは@Cacheableがついたメソッドを呼び出す
  2. Cache AOPが提供する@Cacheableにキーが渡される。CacheManegarを利用して、Hash Mapからデータを取得する。キャッシュデータが取得できた場合はコントローラまたはサービスへキャッシュデータを返却し、キャッシュデータが取得できない場合は次を実行する。
  3. Cache AOPは引数を渡し、定義されたサービスメソッドを実行し、戻り値を取得する。Cache AOPは2で特定されたキャッシュキーで取得した戻り値をCache Manegerを利用してHash Mapへデータとして格納する。
  4. Cache AOPはコントローラまたはサービスへ戻り値を返却する。

Cache AOP

キャッシュ機能の入り口になるインターフェース

Cache Maneger

キャッシュ機能をコントロールしてくれる

キャッシュのデータはredisが保持してくれます。

このredisはデータをメモリに保存してくれる高速なデータストアのことです。

キャッシュの実装は?

はい、ようやく本題ですね。

じゃあ、それってどうやって実装するの?という話です。

Spring Bootではキャッシュ機能のためのライブラリがすでに用意されています。

 キャッシュする必要があるメソッドに@Cacheableをつける

ますはここです。

この@Cacheableとは、キャッシュを有効化にするためのアノテーションです。

キャッシュを行いたいメソッドに対し、

@Cacheable(

cachename = “名前を任意でつける”

key = “キーがあればキーをつける。なければなくてよい”

condition = “キャッシュをする条件があればここでつける。なくてもよい”

)

public void sample(Integer sample, String sample) {

とつけます。

これだけでいい場合もあるのですが、現在だとそれだけではないときも多いと思います。

散々見たエラーはCould not read JSON: Cannot construct instance ofというものでした。

データのやり取りのイメージは以下です。

f:id:ooo-ka999:20210907105750p:plain

このアノテーションをつけることだけでうまくいく場合もありますが、そうでないこともあります。

例えばLocalDateTimeです。 うまくデフォルトのものだと変換ができなくて落ちてしまいます。 なので、

@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime sampleTime;

のようにアノテーションをつけてあげる必要があります。

そのほかにも、こんな事例がありました。 Jacksonでは、publicのフィールド、publicのゲッターを対象としてしまうので、対象にしたくないものは@JsonIgnoreをつける必要がありました。これで対象から外すためです。

使用例は以下の通りです。

@JsonIgnore
public Boolean isHogeHoge(String hogehoge) {
 return this.hogehoge == hogehoge;
}

また、デシリアライズ時にデフォルトコンストラクタが使用されてしまうので、デフォルトコンストラクタでデシリアライズしてほしくない場合は、@JsonCreatorを使ってデシリアライズ時のコンストラクタを使用してあげる必要があります。また、このときにprivateなインスタンス変数を使う場合は@JsonPropertyを用いてマッピングしたいキーの名前を指定してあげる必要がありました。

使用例は以下の通りです。

@JsonCreator
public SampleModel(@JsonProperty("sample") String sample) {
 this.sample=sample;
}

まとめ

キャッシュはキャッシュの対象にきちんと必要なアノテーションをつけてあげることが大切でした。キャッシュって奥深いんだなと今回では学びました。 まだまだ未熟なエンジニアですが、どんどん成長していきたいと思います。

また、余談ですがエキサイトのインターンはとても楽しく、充実しています! 興味ある人にはとてもおすすめしたいです。私はまだ引き続きインターンは続くので、残りの時間も成長できるように頑張っていきたいです。

ここまで読んでいただき、ありがとうございました