Fight the Future

Java言語とJVM、そしてJavaエコシステム全般にまつわること

プレゼン、ボランティアコーチします!

勉強会で話したいけど、プレゼンが初めて、苦手という方に無償でコーチします!

  • スライドのレビュー
  • 録画リハへのアドバイス

Twitter@jyukutyoまでメンションでもDMでも。 デブサミやJJUG CCCなど200人規模で登壇しました。海外での登壇も短いながらあり。デブサミ2017では公募スピーカー1位でした!

SpringでEhcacheを利用する

いやーSpringは至れり尽くせりな気がする。

There are a few implementations of that abstraction available out of the box: JDK java.util.concurrent.ConcurrentMap based caches, EhCache, Gemfire cache, Guava caches and JSR-107 compliant caches. Spring Framework Reference Documentation

このエントリではEhcacheそのものについては触れない。すでにEhcacheを利用していて、それをSpringで使うときの設定について。 Springの例にたがわず設定方法はいろいろあるけど(公式リファレンス参照)、XMLファイルでの設定は以下のとおり。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:cache="http://www.springframework.org/schema/cache"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/cache
        http://www.springframework.org/schema/cache/spring-cache.xsd">

  <bean id="cacheManager"
        class="org.springframework.cache.ehcache.EhCacheCacheManager">
    <property name="cacheManager" ref="ehcache"/>
  </bean>

  <!-- EhCache library setup -->
  <bean id="ehcache"
        class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    <property name="configLocation" value="classpath:/ehcache.xml"/>
  </bean>

  <cache:advice id="hogeCache" cache-manager="cacheManager">
    <cache:caching cache="hoge">
      <cache:cacheable method="hogeMethod" key="#hogeId" />
    </cache:caching>
  </cache:advice>

  <aop:config>
    <aop:advisor advice-ref="hogeCache" pointcut="execution(* com.jyukutyo.HogeImpl.*(..))"/>
  </aop:config>

基本的には通常のAOP設定と同じで、ポイントカットを指定してadviceをrefするだけなんだけど、adviceの定義に<cache:advice>要素が使える。 <cache:cacheable>要素でメソッドと、キャッシュの単位とするキーを指定する。このキーはSpring ELが使えるので、ELの式を使ってメソッドの引数名を書くことになる。

cacheManagerは今回Ehcacheを使うので、EhCacheCacheManagerクラスを使う。EhCacheManagerFactoryBeanではEhcacheの設定ファイルのロケーションを指定しておく。

今回のサンプルでキャッシュを設定するクラスはこんな感じのコードを想定してる。

public class HogeImpl {
  public List<Hoge> hogeMethod(Long hogeId) {
    ...
  }
}

あと、IntelliJ IDEAのSpringサポートを僕がうまく設定できていないのか、advice-ref="hogeCache"の部分にエラーの赤線が入ってしまう…正常に動作はするけど、消したいよね。メッセージは「Bean must be of 'org.aopalliance.aop.Advice' type less... Checks bean reference for required bean type.」。

XMLスキーマを見ると

 <xsd:element name="advice">
        <xsd:complexType>
            <xsd:annotation>
                <xsd:documentation source="java:org.springframework.cache.interceptor.CacheInterceptor">

でCacheInterceptorはMethodInterceptorを実装していて、MethodInterceptorはorg.aopalliance.aop.Adviceを継承しているから、型は合ってると思うんだけどね。