基本要素:版本、概念與抽象
- Ehcache 3.x是一個用Java語言實現的緩存庫,並且實現了 JSR107規范
- Ehcache從2.x升級到3.x后,Maven依賴從 net.sf.ehcache:ehcache:2.x 變成了org.ehcache:ehcache:3.x
- Ehcache基本概念有:
- 要緩存的對象是“鍵值對”
- 鍵值對的容器就是“緩存Cache”
- 每個緩存有自己的配置,就是“緩存配置CacheConfiguration”,通過CacheConfigurationBuilder構建
- Ehcache中可以管理多個緩存,需要一個“緩存管理器CacheManager”。通過CacheManager+緩存的名稱可以創建或獲得緩存
- 緩存對象的存儲位置有: 堆內存heap;堆外內存offheap;硬盤disk。 offheap就是位於JVM外的內存,不受GC管理
通過編程方式創建緩存
引入依賴
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.8.0</version>
</dependency>
測試代碼
@Test
public void testA() {
CacheManagerBuilder builder = CacheManagerBuilder.newCacheManagerBuilder();
CacheManager cacheManager = builder.build();
cacheManager.init();//cacheManager創建后一定要初始化
ResourcePoolsBuilder poolsBuilder = ResourcePoolsBuilder.newResourcePoolsBuilder();
ResourcePools pools = poolsBuilder.heap(10, EntryUnit.ENTRIES).build();//用於配置一個cache的heap/offheap/disk的容量.
CacheConfigurationBuilder<Long, String> cacheConfigBuilder = CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, pools);
CacheConfiguration<Long, String> cacheConfiguration = cacheConfigBuilder.build();//創建一個緩存配置
Cache myCache = cacheManager.createCache("myCache", cacheConfiguration);//根據緩存名稱和緩存配置創建緩存
myCache.put(1L, "hahaha");
logger.info("{}", myCache.get(1L));
cacheManager.close();//系統關閉時, 應調用cacheManager的close方法
}
通過XML配置創建緩存
Ehcache的XML配置:
<?xml version="1.0" encoding="UTF-8" ?>
<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.xsd">
<!-- 可以把多個緩存配置相同的部分抽象出來形成cache-template模板 -->
<cache-template name="myDefaults">
<key-type>java.lang.Long</key-type>
<value-type>java.lang.String</value-type>
<heap unit="entries">200</heap>
</cache-template>
<cache alias="foo">
<key-type>java.lang.String</key-type>
<value-type>java.lang.String</value-type>
<resources>
<heap unit="entries">20</heap> <!-- heap可以存儲20個元素 -->
<offheap unit="MB">10</offheap> <!-- offheap可以存儲10MB -->
</resources>
</cache>
<!-- 繼承cache-template模板 -->
<cache alias="bar" uses-template="myDefaults">
<key-type>java.lang.Number</key-type>
</cache>
<cache alias="simpleCache" uses-template="myDefaults" />
</config>
測試代碼:
@Test
public void testB() {
URL ehcacheConfigUrl = getClass().getResource("/ehcache.xml");
Configuration configuration = new XmlConfiguration(ehcacheConfigUrl); //從XML配置改造緩存配置
CacheManager cacheManager = CacheManagerBuilder.newCacheManager(configuration);//創建CacheManager
cacheManager.init();
Cache<String, String> foo = cacheManager.getCache("foo", String.class, String.class);//從CachaManager用緩存名稱獲取緩存
foo.put("1", "hehehe");
logger.info("{}", foo.get("1"));
Cache<Number, String> bar = cacheManager.getCache("bar", Number.class, String.class);
bar.put(1, "hohoho");
logger.info("{}", bar.get(1));
cacheManager.close();
}
通過JSR107(JCache)的api獲取Ehcache的緩存--編程方式
@Test
public void testA() {
//CachingProvider provider = Caching.getCachingProvider("org.ehcache.jsr107.EhcacheCachingProvider");
CachingProvider provider = Caching.getCachingProvider();//通過spi技術找到provider. 適用於類路徑中只有一個JCache實現, 否則得用上面一行代碼指明provider
CacheManager cacheManager = provider.getCacheManager();
ResourcePoolsBuilder poolsBuilder = ResourcePoolsBuilder.newResourcePoolsBuilder();
ResourcePools pools = poolsBuilder.heap(10, EntryUnit.ENTRIES).build();
CacheConfigurationBuilder<Long, String> configBuilder = CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, pools);
CacheConfiguration<Long, String> cacheConfig = configBuilder.build();//ehcache的configuration
Cache<Long, String> cache = cacheManager.createCache("myCache", Eh107Configuration.fromEhcacheCacheConfiguration(cacheConfig));//通過Eh107Configuration將ehcache的config轉為jcache的config
cache.put(1L, "hahaha");
logger.info("{}", cache.get(1L));
cacheManager.close();
}
通過JSR107(JCache)的api獲取Ehcache的緩存--XML配置
引入JSR107規范
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
<version>1.1.1</version>
</dependency>
Ehcache的XML配置采用上面的
測試代碼:
@Test
public void testB() throws Exception {
CachingProvider provider = Caching.getCachingProvider("org.ehcache.jsr107.EhcacheCachingProvider");
URI uri = getClass().getResource("/ehcache.xml").toURI();
CacheManager cacheManager = provider.getCacheManager(uri, getClass().getClassLoader());
Cache<String, String> cache = cacheManager.getCache("foo", String.class, String.class);
cache.put("1", "hehehe");
logger.info("{}", cache.get("1"));
cacheManager.close();
}
通過JCache在Spring中注入Ehcache
Spring的XML配置
<bean id="jCacheManager" class="org.springframework.cache.jcache.JCacheManagerFactoryBean">
<property name="cacheManagerUri" value="classpath:ehcache.xml" />
</bean>
<bean id="cacheManager" class="org.springframework.cache.jcache.JCacheCacheManager">
<property name="cacheManager" ref="jCacheManager" />
</bean>
測試代碼:
@ContextConfiguration("classpath:spring.xml")
public class SpringJcacheEhcacheTest extends AbstractTestNGSpringContextTests {
private static final Logger logger = LoggerFactory.getLogger(SpringJcacheEhcacheTest.class);
@Autowired
private CacheManager cacheManager;
@Test
public void testA() {
Cache<Number, String> barCache = cacheManager.getCache("bar", Number.class, String.class);
barCache.put(1, "hahaha");
barCache.put(2L, "hehehe");
logger.info("{}", barCache.get(1));
logger.info("{}", barCache.get(2L));
cacheManager.close();
}
}
其他--在Spring中注入Ehcache 2.x
引入Ehcache2.x
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.6</version>
</dependency>
Ehcache 2.x配置
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false" monitoring="autodetect" dynamicConfig="true">
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
<cache name="foo"
eternal="false"
timeToLiveSeconds="300"
maxElementsInMemory="2000"
maxElementsOnDisk="20000"
overflowToDisk="true"
diskPersistent="true"
memoryStoreEvictionPolicy="FIFO"/>
</ehcache>
spring的XML配置
<bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache-2.x.xml"/>
</bean>
<bean id="cacheManager2.x" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="cacheManagerFactory"/>
</bean>
測試代碼:
@ContextConfiguration("classpath:spring.xml")
public class SpringEhcache2xTest extends AbstractTestNGSpringContextTests {
private static final Logger logger = LoggerFactory.getLogger(SpringEhcache2xTest.class);
@Autowired
private EhCacheCacheManager ehCacheCacheManager;
@Test
public void testA() {
CacheManager cacheManager = ehCacheCacheManager.getCacheManager();
Cache cache = cacheManager.getCache("foo");
Element ele = new Element(1L, "Ehcache 2.x");
cache.put(ele);
logger.info("{}", cache.get(1L).getObjectValue());
cacheManager.shutdown();
}
}
最后
Ehcache 3.x官方文檔: http://www.ehcache.org/documentation/3.8/getting-started.html
完整代碼: https://github.com/JamboSonng/Demo-Master/tree/master/Master-Ehcache