缺點:磁盤存儲佔用大、突發殺進程可能導致數據衝突(重建緩存機制),不適合強持久化場景(可改用 Berkeley DB JE)。
Eclipse + Maven + Spring 3.2.8 + EhCache 2.8.2 + JUnit 4.10
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.8.2</version>
</dependency>
<!-- Spring context-support 必須引入,提供 EhCacheFactoryBean -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<ehcache>
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000" eternal="false"
overflowToDisk="true" timeToIdleSeconds="10"
timeToLiveSeconds="20" diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"/>
<cache name="cacheTest"
maxElementsInMemory="1000" eternal="false"
overflowToDisk="true" timeToIdleSeconds="10"
timeToLiveSeconds="20"/>
</ehcache>
關鍵屬性:eternal=true 永不過期(忽略 TTI/TTL);overflowToDisk 內存溢出寫磁盤(要求對象實現 Serializable);memoryStoreEvictionPolicy LRU/FIFO/LFU。
<beans xmlns:cache="https://www.springframework.org/schema/cache" ...>
<context:component-scan base-package="com.luo.service"/>
<cache:annotation-driven cache-manager="cacheManager"/>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="ehcache"/>
</bean>
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache-setting.xml"/>
</bean>
</beans>
public interface EhCacheTestService {
String getTimestamp(String param);
}
@Service
public class EhCacheTestServiceImpl implements EhCacheTestService {
@Cacheable(value="cacheTest", key="#param")
public String getTimestamp(String param) {
return String.valueOf(System.currentTimeMillis());
}
}
value 對應 EhCache 配置中的 cache name;key 支持 SpEL,#param 表示方法參數。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:application.xml"})
public class EhCacheTestServiceTest extends AbstractJUnit4SpringContextTests {
@Autowired private EhCacheTestService service;
@Test
public void testCache() throws InterruptedException {
System.out.println("第一次調用:" + service.getTimestamp("param")); // 進入方法,生成時間戳
Thread.sleep(2000);
System.out.println("2秒後調用:" + service.getTimestamp("param")); // 命中緩存,返回相同時間戳
Thread.sleep(11000); // 超過 TTL 20s? 此處配置 10s TTI + 20s TTL,實際以 TTL 為準
System.out.println("再過11秒調用:" + service.getTimestamp("param")); // 緩存失效,重新生成
}
}
第一次調用:1484723456789 2秒後調用:1484723456789 <-- 相同,緩存命中 再過11秒調用:1484723467890 <-- 不同,緩存過期重新執行
