spring boot統合ehcache 2.xはhibernate 2級キャッシュに使用されます。
本論文では、どのようにspring bootにehcacheをヒップホップとして一体化するかを紹介します。各フレームのバージョンは以下の通りです。 spring book:1.4.3.RELEASE スプリングフレームワーク:4.3.5.RELEASE hibernate:5.0.11.Final(spring-book-starter-data-jpaデフォルト依存) ehcache:2.1.3 プロジェクト依存
ehcacheは純粋なJavaのキャッシュフレームであり、一つの汎用キャッシュとして使用することもできるし、hibernateの二級キャッシュとして使用することもできる。キャッシュデータは、次の3つのストレージを選択できます。 MemoryStore C On-heap memory used to hold cache elemens.This tier is subject to Java garbage collection. OffHeappore C Provides overflow capacity to the MemoryStore.Limited in size only by available RAM.Not subject to Java garbage collection(GC).Available only with Terracotta BigMemory product Disc Store C Backs up in-memory cache elemens and provides overflow capacity to the other tiers. ヒベルナ2級キャッシュの設定
hibernateの二級キャッシュは、entityとqueryレベルのキャッシュをサポートしています。org.hibernate.ache.spi.RegionFactoryは、各種の抜き差し可能なキャッシュプロバイダとhibernateの集積を提供しています。
ehcacheプロファイル
ehcache 2.xプロファイル見本は公式サイトを参照してのehcache.xmlを提供します。本例で使用するプロファイルを以下に示します。
ehcacheには、cacheのinit/addedなどの二種類のイベントがあります。二番目はcahche関連のイベントで、例えばcache put/expireなどです。ehcacheでは、デフォルトではこれらの2つのイベントのモニターはなく、自主的にモニターとモニター工場の種類を実現してからehcache.xmlに配置すると、効果があります。
上記ehcache.xml構成では、カスタムcacheにcacheEventListenerFactoryを配置し、キャッシュイベントを傍受する。cacheManager Factory実現クラスも搭載しています。具体的な実現コードは以下の通りです。
CacheManager Event Listenerが簡単に実現します。
entity cacheを使うには、entityに対応する注釈を付ける必要があります。javax.persistence.acheable注釈は、当該entityが2級キャッシュを使用し、org.hibernate.annotations.ache注釈はキャッシュポリシーを指定し、どのキャッシュエリアに格納するかを指定します。
キャッシュポリシーに関する詳細情報はヒベルナ5.0公式文書を参照することができる。
完全コードの例はgithubを参照してください。
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<exclusions>
<exclusion>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.3</version>
</dependency>
Ehcache概要ehcacheは純粋なJavaのキャッシュフレームであり、一つの汎用キャッシュとして使用することもできるし、hibernateの二級キャッシュとして使用することもできる。キャッシュデータは、次の3つのストレージを選択できます。
hibernateの二級キャッシュは、entityとqueryレベルのキャッシュをサポートしています。org.hibernate.ache.spi.RegionFactoryは、各種の抜き差し可能なキャッシュプロバイダとhibernateの集積を提供しています。
# hibernate
spring.jpa.properties.hibernate.generate_statistics=true
#
spring.jpa.properties.hibernate.cache.use_second_level_cache=true
#
spring.jpa.properties.hibernate.cache.use_query_cache=true
# provider
spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
# shared-cache-mode
spring.jpa.properties.javax.persistence.sharedCache.mode=ENABLE_SELECTIVE
hibernateキャッシュに関するすべての構成はヒベルナ5.0公式文書を参照することができる。ehcacheプロファイル
ehcache 2.xプロファイル見本は公式サイトを参照してのehcache.xmlを提供します。本例で使用するプロファイルを以下に示します。
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.ehcache.org/ehcache.xsd"
updateCheck="true" monitoring="autodetect"
dynamicConfig="true">
<diskStore path="user.dir/cache"/>
<transactionManagerLookup class="net.sf.ehcache.transaction.manager.DefaultTransactionManagerLookup"
properties="jndiName=java:/TransactionManager" propertySeparator=";"/>
<cacheManagerEventListenerFactory class="com.yangyi.base.ehcache.CustomerCacheManagerEventListenerFactory" properties=""/>
<defaultCache
maxEntriesLocalHeap="0"
eternal="false"
timeToIdleSeconds="1200"
timeToLiveSeconds="1200">
<!--<terracotta/>-->
</defaultCache>
<cache name="entityCache"
maxEntriesLocalHeap="1000"
maxEntriesLocalDisk="10000"
eternal="false"
diskSpoolBufferSizeMB="20"
timeToIdleSeconds="10"
timeToLiveSeconds="20"
memoryStoreEvictionPolicy="LFU"
transactionalMode="off">
<persistence strategy="localTempSwap"/>
<cacheEventListenerFactory class="com.yangyi.base.ehcache.CustomerCacheEventListenerFactory" />
</cache>
<cache name="org.hibernate.cache.internal.StandardQueryCache"
maxEntriesLocalHeap="5" eternal="false" timeToLiveSeconds="120">
<persistence strategy="localTempSwap" />
<cacheEventListenerFactory class="com.yangyi.base.ehcache.CustomerCacheEventListenerFactory" />
</cache>
<cache name="org.hibernate.cache.spi.UpdateTimestampsCache"
maxEntriesLocalHeap="5000" eternal="true">
<persistence strategy="localTempSwap" />
<cacheEventListenerFactory class="com.yangyi.base.ehcache.CustomerCacheEventListenerFactory" />
</cache>
</ehcache>
ehcache事件監聴ehcacheには、cacheのinit/addedなどの二種類のイベントがあります。二番目はcahche関連のイベントで、例えばcache put/expireなどです。ehcacheでは、デフォルトではこれらの2つのイベントのモニターはなく、自主的にモニターとモニター工場の種類を実現してからehcache.xmlに配置すると、効果があります。
上記ehcache.xml構成では、カスタムcacheにcacheEventListenerFactoryを配置し、キャッシュイベントを傍受する。cacheManager Factory実現クラスも搭載しています。具体的な実現コードは以下の通りです。
CacheManager Event Listenerが簡単に実現します。
package com.yangyi.base.ehcache;
import net.sf.ehcache.CacheException;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Status;
import net.sf.ehcache.event.CacheManagerEventListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* ehcache customer cacheManagerEventListener
* Created by yangjinfeng on 2017/1/5.
*/
public class CustomerCacheManagerEventListener implements CacheManagerEventListener {
private Logger logger = LoggerFactory.getLogger(getClass());
private final CacheManager cacheManager;
public CustomerCacheManagerEventListener(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
@Override
public void init() throws CacheException {
logger.info("init ehcache...");
}
@Override
public Status getStatus() {
return null;
}
@Override
public void dispose() throws CacheException {
logger.info("ehcache dispose...");
}
@Override
public void notifyCacheAdded(String s) {
logger.info("cacheAdded... {}", s);
logger.info(cacheManager.getCache(s).toString());
}
@Override
public void notifyCacheRemoved(String s) {
}
}
CacheManagerEventListenerFactoryの簡単な実現
package com.yangyi.base.ehcache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.event.CacheManagerEventListener;
import net.sf.ehcache.event.CacheManagerEventListenerFactory;
import java.util.Properties;
/**
* Created by yangjinfeng on 2017/1/5.
*/
public class CustomerCacheManagerEventListenerFactory extends CacheManagerEventListenerFactory {
@Override
public CacheManagerEventListener createCacheManagerEventListener(CacheManager cacheManager, Properties properties) {
return new CustomerCacheManagerEventListener(cacheManager);
}
}
Cacheevent Listenerの簡単な実現
package com.yangyi.base.ehcache;
import net.sf.ehcache.CacheException;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import net.sf.ehcache.event.CacheEventListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Created by yangjinfeng on 2017/1/5.
*/
public class CustomerCacheEventListener implements CacheEventListener {
private Logger logger = LoggerFactory.getLogger(getClass());
@Override
public void notifyElementRemoved(Ehcache ehcache, Element element) throws CacheException {
logger.info("cache removed. key = {}, value = {}", element.getObjectKey(), element.getObjectValue());
}
@Override
public void notifyElementPut(Ehcache ehcache, Element element) throws CacheException {
logger.info("cache put. key = {}, value = {}", element.getObjectKey(), element.getObjectValue());
}
@Override
public void notifyElementUpdated(Ehcache ehcache, Element element) throws CacheException {
logger.info("cache updated. key = {}, value = {}", element.getObjectKey(), element.getObjectValue());
}
@Override
public void notifyElementExpired(Ehcache ehcache, Element element) {
logger.info("cache expired. key = {}, value = {}", element.getObjectKey(), element.getObjectValue());
}
@Override
public void notifyElementEvicted(Ehcache ehcache, Element element) {
logger.info("cache evicted. key = {}, value = {}", element.getObjectKey(), element.getObjectValue());
}
@Override
public void notifyRemoveAll(Ehcache ehcache) {
logger.info("all elements removed. cache name = {}", ehcache.getName());
}
@Override
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
@Override
public void dispose() {
logger.info("cache dispose.");
}
}
CacheventListenerFactoryの簡単な実現
package com.yangyi.base.ehcache;
import net.sf.ehcache.event.CacheEventListener;
import net.sf.ehcache.event.CacheEventListenerFactory;
import java.util.Properties;
/**
* Created by yangjinfeng on 2017/1/5.
*/
public class CustomerCacheEventListenerFactory extends CacheEventListenerFactory {
@Override
public CacheEventListener createCacheEventListener(Properties properties) {
return new CustomerCacheEventListener();
}
}
上記のイベントモニターの実装と構成を完了したら、アプリケーションを起動し、各イベントモニターから出力されたロゴを確認して、有効かどうかを確認します。
2017-01-07 10:27:07.810 INFO 4264 --- [ main] com.yangyi.Application : Starting Application on yangjinfeng-pc with PID 4264 (E:\JavaWorkSpace\spring-boot-ehcache3-hibernate5-jcache\target\classes started by yangjinfeng in E:\JavaWorkSpace\spring-boot-ehcache3-hibernate5-jcache)
2017-01-07 10:27:07.810 INFO 4264 --- [ main] com.yangyi.Application : No active profile set, falling back to default profiles: default
2017-01-07 10:27:07.865 INFO 4264 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@2ef3eef9: startup date [Sat Jan 07 10:27:07 CST 2017]; root of context hierarchy
2017-01-07 10:27:09.155 INFO 4264 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [class org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$6eb4eae9] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-01-07 10:27:09.191 INFO 4264 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.cache.annotation.ProxyCachingConfiguration' of type [class org.springframework.cache.annotation.ProxyCachingConfiguration$$EnhancerBySpringCGLIB$$b7c72107] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-01-07 10:27:09.206 INFO 4264 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration' of type [class org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration$$EnhancerBySpringCGLIB$$ac3ae5ab] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-01-07 10:27:09.285 INFO 4264 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'spring.cache-org.springframework.boot.autoconfigure.cache.CacheProperties' of type [class org.springframework.boot.autoconfigure.cache.CacheProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-01-07 10:27:09.291 INFO 4264 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.cache.CacheManagerCustomizers' of type [class org.springframework.boot.autoconfigure.cache.CacheManagerCustomizers] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-01-07 10:27:09.293 INFO 4264 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.cache.EhCacheCacheConfiguration' of type [class org.springframework.boot.autoconfigure.cache.EhCacheCacheConfiguration$$EnhancerBySpringCGLIB$$46d9b2a9] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-01-07 10:27:09.418 INFO 4264 --- [ main] .y.b.e.CustomerCacheManagerEventListener : init ehcache...
2017-01-07 10:27:09.487 INFO 4264 --- [ main] .y.b.e.CustomerCacheManagerEventListener : cacheAdded... org.hibernate.cache.spi.UpdateTimestampsCache
2017-01-07 10:27:09.487 INFO 4264 --- [ main] .y.b.e.CustomerCacheManagerEventListener : [ name = org.hibernate.cache.spi.UpdateTimestampsCache status = STATUS_ALIVE eternal = true overflowToDisk = true maxEntriesLocalHeap = 5000 maxEntriesLocalDisk = 0 memoryStoreEvictionPolicy = LRU timeToLiveSeconds = 0 timeToIdleSeconds = 0 persistence = LOCALTEMPSWAP diskExpiryThreadIntervalSeconds = 120 cacheEventListeners: com.yangyi.base.ehcache.CustomerCacheEventListener ; orderedCacheEventListeners: maxBytesLocalHeap = 0 overflowToOffHeap = false maxBytesLocalOffHeap = 0 maxBytesLocalDisk = 0 pinned = false ]
2017-01-07 10:27:09.487 INFO 4264 --- [ main] .y.b.e.CustomerCacheManagerEventListener : cacheAdded... org.hibernate.cache.internal.StandardQueryCache
2017-01-07 10:27:09.487 INFO 4264 --- [ main] .y.b.e.CustomerCacheManagerEventListener : [ name = org.hibernate.cache.internal.StandardQueryCache status = STATUS_ALIVE eternal = false overflowToDisk = true maxEntriesLocalHeap = 5 maxEntriesLocalDisk = 0 memoryStoreEvictionPolicy = LRU timeToLiveSeconds = 120 timeToIdleSeconds = 0 persistence = LOCALTEMPSWAP diskExpiryThreadIntervalSeconds = 120 cacheEventListeners: com.yangyi.base.ehcache.CustomerCacheEventListener ; orderedCacheEventListeners: maxBytesLocalHeap = 0 overflowToOffHeap = false maxBytesLocalOffHeap = 0 maxBytesLocalDisk = 0 pinned = false ]
2017-01-07 10:27:09.503 INFO 4264 --- [ main] .y.b.e.CustomerCacheManagerEventListener : cacheAdded... entityCache
2017-01-07 10:27:09.503 INFO 4264 --- [ main] .y.b.e.CustomerCacheManagerEventListener : [ name = entityCache status = STATUS_ALIVE eternal = false overflowToDisk = true maxEntriesLocalHeap = 1000 maxEntriesLocalDisk = 10000 memoryStoreEvictionPolicy = LFU timeToLiveSeconds = 20 timeToIdleSeconds = 10 persistence = LOCALTEMPSWAP diskExpiryThreadIntervalSeconds = 120 cacheEventListeners: com.yangyi.base.ehcache.CustomerCacheEventListener ; orderedCacheEventListeners: maxBytesLocalHeap = 0 overflowToOffHeap = false maxBytesLocalOffHeap = 0 maxBytesLocalDisk = 0 pinned = false ]
2017-01-07 10:27:09.503 INFO 4264 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'ehCacheCacheManager' of type [class net.sf.ehcache.CacheManager] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-01-07 10:27:09.503 INFO 4264 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'cacheManager' of type [class org.springframework.cache.ehcache.EhCacheCacheManager] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-01-07 10:27:09.503 INFO 4264 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'cacheAutoConfigurationValidator' of type [class org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration$CacheManagerValidator] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-01-07 10:27:09.829 INFO 4264 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2017-01-07 10:27:09.839 INFO 4264 --- [ main] o.apache.catalina.core.StandardService : Starting service Tomcat
2017-01-07 10:27:09.839 INFO 4264 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.6
2017-01-07 10:27:09.924 INFO 4264 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2017-01-07 10:27:09.924 INFO 4264 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2061 ms
2017-01-07 10:32:41.876 INFO 4264 --- [nio-8080-exec-1] c.y.b.e.CustomerCacheEventListener : cache put. key = com.yangyi.entity.User#1, value = org.hibernate.cache.ehcache.internal.strategy.AbstractReadWriteEhcacheAccessStrategy$Item@1c13194d
2017-01-07 10:32:41.877 INFO 4264 --- [nio-8080-exec-1] c.y.b.e.CustomerCacheEventListener : cache put. key = com.yangyi.entity.Authority#1, value = org.hibernate.cache.ehcache.internal.strategy.AbstractReadWriteEhcacheAccessStrategy$Item@2accc177
2017-01-07 10:32:41.878 INFO 4264 --- [nio-8080-exec-1] c.y.b.e.CustomerCacheEventListener : cache put. key = com.yangyi.entity.Authority#2, value = org.hibernate.cache.ehcache.internal.strategy.AbstractReadWriteEhcacheAccessStrategy$Item@2b3b9c7e
2017-01-07 10:32:41.879 INFO 4264 --- [nio-8080-exec-1] c.y.b.e.CustomerCacheEventListener : cache put. key = com.yangyi.entity.Authority#3, value = org.hibernate.cache.ehcache.internal.strategy.AbstractReadWriteEhcacheAccessStrategy$Item@4c31e58c
注釈方式は二級キャッシュを使用します。entity cacheを使うには、entityに対応する注釈を付ける必要があります。javax.persistence.acheable注釈は、当該entityが2級キャッシュを使用し、org.hibernate.annotations.ache注釈はキャッシュポリシーを指定し、どのキャッシュエリアに格納するかを指定します。
キャッシュポリシーに関する詳細情報はヒベルナ5.0公式文書を参照することができる。
package com.yangyi.entity;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.Cacheable;
import javax.persistence.Entity;
import javax.persistence.JoinTable;
@Entity
@Table(name = "users")
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "entityCache")
public class User implements Serializable {
}
最後に、私達はspring boot応用面でcache機能を開けて、org.springframe ebook.cache.annotations.EnballCaching注釈を使う必要があります。
package com.yangyi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
完全コード完全コードの例はgithubを参照してください。
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。