Spring Framework 5およびEhCache 3.5

2018-03-01 spring spring-mvc ehcache ehcache-3

Spring Boot 2 / Spring Framework 5に基づくWebアプリケーションでEhCache 3.5キャッシング機能を使用しようとしました。

EHCache依存関係を追加しました:

    <dependency>
        <groupId>org.ehcache</groupId>
        <artifactId>ehcache</artifactId>
        <version>3.5.0</version>
    </dependency>
    <dependency>
        <groupId>javax.cache</groupId>
        <artifactId>cache-api</artifactId>
        <version>1.0.0</version>
    </dependency>

次に、src / main / resourcesフォルダーにehcache.xmlファイルを作成しました。

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
    monitoring="autodetect" dynamicConfig="true">

    <cache name="orders" maxElementsInMemory="100" 
        eternal="false" overflowToDisk="false" 
        memoryStoreEvictionPolicy="LFU" copyOnRead="true"
        copyOnWrite="true" />
</ehcache>

Spring 5リファレンスガイドでは、EHCacheの使用法については触れられていません。Spring4リファレンスガイドでは、「Ehcache 3.xはJSR-107に完全に準拠しており、専用のサポートは必要ありません」と述べています。

そこで、コントローラーOrderControllerとRESTエンドポイントを作成しました。

@Cacheable("orders")
@GetMapping(path = "/{id}")
public Order findById(@PathVariable int id) {
    return orderRepository.findById(id);
}

スプリングブート構成:

@SpringBootApplication
@EnableCaching
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

しかし、このエンドポイントを呼び出すと、例外が発生します。

Builder [public org.Order org.OrderController.findById(int)] caches = [orders]の 'orders'という名前のキャッシュが見つかりません|キー= '' | keyGenerator = '' | cacheManager = '' | cacheResolver = '' |条件= '' |でなければ=」| sync = 'false'

次に、Spring Framework 4の例を使用しようとしました:

@Bean
public CacheManager cacheManager() {
    return new EhCacheCacheManager(ehCacheCacheManager().getObject());
}

@Bean
public EhCacheManagerFactoryBean ehCacheCacheManager() {
    EhCacheManagerFactoryBean cmfb = new EhCacheManagerFactoryBean();
    cmfb.setConfigLocation(new ClassPathResource("ehcache.xml"));
    cmfb.setShared(true);
    return cmfb;
}

ただし、例外のためコンパイルできません。

タイプnet.sf.ehcache.CacheManagerを解決できません。必要な.classファイルから間接的に参照されている

お知らせ下さい。

Answers

ehcacheバージョン2を使用するように強制する必要があります

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>2.10.3</version>
</dependency>

ehcache 3を使用するには:

ここにアプリケーションがあります:

@SpringBootApplication
@EnableCaching
public class Application {

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

ここにapplication.ymlがあります

spring:
  cache:
    ehcache:
      config: ehcache.xml

ここにテスト用のカウンターがあるサービス

@Service
public class OrderService {

    public static int counter=0;

    @Cacheable("orders")
    public Order findById(Long id) {
        counter++;
        return new Order(id, "desc_" + id);
    }
}

以下は、キャッシュを使用していることを証明するためのテストです。

@RunWith(SpringRunner.class)
@SpringBootTest
public class OrderServiceTest {

    @Autowired
    private OrderService orderService;

    @Test
    public void getHello() throws Exception {
        orderService.findById(1l);
        assertEquals(1, OrderService.counter);
        orderService.findById(1l);
        assertEquals(1, OrderService.counter);
        orderService.findById(2l);
        assertEquals(2, OrderService.counter);
    }
}

実際の例はこちらをご覧ください。

追加の調査を行いました。次の構成は、Spring Bootによって(application.propertiesから)取得されません。

spring.cache.ehcache.config=classpath:ehcache.xml

そのため、jcache.xmlを作成し、src / main / resourceフォルダーにも配置しました。

<config xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
    xmlns='http://www.ehcache.org/v3'
    xsi:schemaLocation="
        http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd">

    <cache alias="orders">
        <key-type>org.springframework.cache.interceptor.SimpleKey</key-type>
        <value-type>java.util.Collections$SingletonList</value-type>
        <heap unit="entries">200</heap>
    </cache>
</config>

次に、application.propertiesの設定を

spring.cache.jcache.config=classpath:jcache.xml

これで、Spring Cachingは正しく動作します。しかし、それはまだehcache.xmlをピックアップする方法の問題です

ここにはさまざまなものが混在しています。使用しているEhcache 3は、SpringからJCacheで使用されます。

これが、 spring.cache.jcache.config=classpath:ehcache.xmlを使用する必要がある理由です。

次に、Ehcache構成は実際にEhcache 2構成です。 EhCacheCacheManagerです。 JCacheのために、あなたが使用する必要がありますJCacheCacheManager 。しかし実際には、 ehcache.xmlを使用する必要さえありません。

これを機能させるための手順は次のとおりです

ステップ1:正しい依存関係を設定します。親pom依存関係管理によって提供されるため、バージョンを指定する必要がないことに注意してください。 javax.cacheがバージョン1.1になりました。

<dependency>
    <groupId>org.ehcache</groupId>
    <artifactId>ehcache</artifactId>
</dependency>
<dependency>
    <groupId>javax.cache</groupId>
    <artifactId>cache-api</artifactId>
</dependency>

ステップ2: src/main/resources ehcache.xmlファイルを追加します。以下の例。

<?xml version="1.0" encoding="UTF-8"?>
<config
    xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
    xmlns:jsr107='http://www.ehcache.org/v3/jsr107'
    xmlns='http://www.ehcache.org/v3'
    xsi:schemaLocation="
        http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.5.xsd
        http://www.ehcache.org/v3/jsr107 http://www.ehcache.org/schema/ehcache-107-ext-3.5.xsd">

  <service>
    <jsr107:defaults enable-management="false" enable-statistics="true"/>
  </service>

  <cache alias="value">
    <resources>
      <heap unit="entries">2000</heap>
    </resources>
  </cache>
</config>

ステップ3: ehcache.xmlを見つけるには、この行を含むapplication.propertiesが必要ehcache.xml

spring.cache.jcache.config=classpath:ehcache.xml

JCacheはクラスパスにあるため、Spring Cacheはそれをキャッシュプロバイダーとして選択します。したがって、 spring.cache.type=jcacheを指定する必要はありません。

ステップ4:キャッシュを有効にする

    @SpringBootApplication
    @EnableCaching
    public class Cache5Application {

        private int value = 0;

        public static void main(String[] args) {
            ApplicationContext context = SpringApplication.run(Cache5Application.class, args);
            Cache5Application app = context.getBean(Cache5Application.class);
            System.out.println(app.value());
            System.out.println(app.value());
        }

        @Cacheable("value")
        public int value() {
            return value++;
        }
    }

同じ問題に直面しています。

  • 私のehcache.xmlは次のようになります

    <config xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
        xmlns='http://www.ehcache.org/v3'
        xmlns:jsr107='http://www.ehcache.org/v3/jsr107'
        xsi:schemaLocation="
            http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd
            http://www.ehcache.org/v3/jsr107 http://www.ehcache.org/schema/ehcache-107-ext-3.0.xsd">
      <service>
          <jsr107:defaults>
              <jsr107:cache name="vehicles" template="heap-cache" />
          </jsr107:defaults>
      </service>
      <cache-template name="heap-cache">
          <heap unit="entries">20</heap>
      </cache-template>
    </config>
    
  • spring.cache.jcache.config=classpath:ehcache.xmlを構成してapplication.properties

  • アプリケーションクラスに@EnableCaching@EnableCachingします。

  • サービス実装に@CacheResultがあります。

@CacheResult(cacheName = "vehicles")public VehicleDetail getVehicle(@CacheKey String VehicleId)がVehicleServiceExceptionをスローします

  • CacheManager Beanがないことに注意してください。

誰かが私が欠けているものを指摘することができれば、本当に役に立ちます。

うーん.. ehcache.xmlをに変更して、トリックをしました..

<config xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
    xmlns='http://www.ehcache.org/v3'
    xmlns:jsr107='http://www.ehcache.org/v3/jsr107'
    xsi:schemaLocation="
        http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd
        http://www.ehcache.org/v3/jsr107 http://www.ehcache.org/schema/ehcache-107-ext-3.0.xsd">

    <service>
        <jsr107:defaults enable-management="true"
            enable-statistics="true" />
    </service>

    <cache alias="vehicles" uses-template="heap-cache" />

    <cache-template name="heap-cache">
        <heap unit="entries">20</heap>
    </cache-template>
</config>

Related